Xml & json in sql server

Код

четыретритри

Msg 156, Level 15, State 1, Line 26
Incorrect syntax near the keyword 'select'.
Msg 102, Level 15, State 1, Line 28
Incorrect syntax near ')'.
Msg 9829, Level 16, State 1, Line 62
STRING_AGG aggregation result exceeded the limit of 8000 bytes. 
Use LOB types to avoid result truncation.
-- FOR XML PATH
select @strFilter = reverse( stuff( reverse(
	(select 'FullTableName = ' + '''' +  + '''' +
@strSeparator as 
from IndexColumnAnalysisList 
where RecID 
)
) -- первый reverse
	,1,1,'') -- stuff
	) -- второй reverse
Set @strFilter = left(@strFilter, len(@strFilter) - 3) –- удаление последнего ‘ or ’
-- FOR XML PATH
-- String_agg
select @strFilter = string_agg('FullTableName = ' + '''' + 
cast( as nvarchar(max)) + '''', @strSeparator)
	from IndexColumnAnalysisList
	where RecID 
–- String_agg

Tag-Based XML

This example uses tag-based XML, where each data element for an employee is surrounded by its own start and end tag.

First we create a table to hold our XML document and populate it with a document containing multiple rows of data. Using gives us a separate tag for each column in the query.

CREATE TABLE xml_tab (
  id        NUMBER,
  xml_data  XMLTYPE
);

DECLARE
  l_xmltype XMLTYPE;
BEGIN
  SELECT XMLELEMENT("employees",
           XMLAGG(
             XMLELEMENT("employee",
               XMLFOREST(
                 e.empno AS "empno",
                 e.ename AS "ename",
                 e.job AS "job",
                 TO_CHAR(e.hiredate, 'DD-MON-YYYY') AS "hiredate"
               )
             )
           ) 
         )
  INTO   l_xmltype
  FROM   emp e;

  INSERT INTO xml_tab VALUES (1, l_xmltype);
  COMMIT;
END;
/

We can see the resulting row containing the tag-based XML using the following query.

SET LONG 5000
SELECT x.xml_data.getClobVal()
FROM   xml_tab x;

X.XML_DATA.GETCLOBVAL()
--------------------------------------------------------------------------------
<employees>
  <employee>
    <empno>7369</empno>
    <ename>SMITH</ename>
    <job>CLERK</job>
    <hiredate>17-DEC-1980</hiredate>
  </employee>
  <employee>
    <empno>7499</empno>
    <ename>ALLEN</ename>
    <job>SALESMAN</job>
    <hiredate>20-FEB-1981</hiredate>
  </employee>
  <employee>
    <empno>7521</empno>
    <ename>WARD</ename>
    <job>SALESMAN</job>
    <hiredate>22-FEB-1981</hiredate>
  </employee>
  <employee>
    <empno>7566</empno>
    <ename>JONES</ename>
    <job>MANAGER</job>
    <hiredate>02-APR-1981</hiredate>
  </employee>
  <employee>
    <empno>7654</empno>
    <ename>MARTIN</ename>
    <job>SALESMAN</job>
    <hiredate>28-SEP-1981</hiredate>
  </employee>
  <employee>
    <empno>7698</empno>
    <ename>BLAKE</ename>
    <job>MANAGER</job>
    <hiredate>01-MAY-1981</hiredate>
  </employee>
  <employee>
    <empno>7782</empno>
    <ename>CLARK</ename>
    <job>MANAGER</job>
    <hiredate>09-JUN-1981</hiredate>
  </employee>
  <employee>
    <empno>7788</empno>
    <ename>SCOTT</ename>
    <job>ANALYST</job>
    <hiredate>19-APR-1987</hiredate>
  </employee>
  <employee>
    <empno>7839</empno>
    <ename>KING</ename>
    <job>PRESIDENT</job>
    <hiredate>17-NOV-1981</hiredate>
  </employee>
  <employee>
    <empno>7844</empno>
    <ename>TURNER</ename>
    <job>SALESMAN</job>
    <hiredate>08-SEP-1981</hiredate>
  </employee>
  <employee>
    <empno>7876</empno>
    <ename>ADAMS</ename>
    <job>CLERK</job>
    <hiredate>23-MAY-1987</hiredate>
  </employee>
  <employee>
    <empno>7900</empno>
    <ename>JAMES</ename>
    <job>CLERK</job>
    <hiredate>03-DEC-1981</hiredate>
  </employee>
  <employee>
    <empno>7902</empno>
    <ename>FORD</ename>
    <job>ANALYST</job>
    <hiredate>03-DEC-1981</hiredate>
  </employee>
  <employee>
    <empno>7934</empno>
    <ename>MILLER</ename>
    <job>CLERK</job>
    <hiredate>23-JAN-1982</hiredate>
  </employee>
</employees>

1 row selected.

SQL>

The operator allows us to split the XML data into rows and project columns on to it. We effectively make a cartesian product between the data table and the call, which allows to split a XML document in a single row into multiple rows in the final result set. The table column is identified as the source of the data using the clause. The rows are identified using a XQuery expression, in this case ‘/employees/employee’. Columns are projected onto the resulting XML fragments using the clause, which identifies the relevant tags using the expression and assigns the desired column names and data types. Be careful with the names of the columns in the clause. If you use anything other than upper case, they will need to be quoted to make direct reference to them. Notice we are querying using the alias of the call, rather than the regular table alias.

SELECT xt.*
FROM   xml_tab x,
       XMLTABLE('/employees/employee'
         PASSING x.xml_data
         COLUMNS 
           empno     VARCHAR2(4)  PATH 'empno',
           ename     VARCHAR2(10) PATH 'ename',
           job       VARCHAR2(9)  PATH 'job',
           hiredate  VARCHAR2(11) PATH 'hiredate'
         ) xt;

EMPN ENAME      JOB       HIREDATE
---- ---------- --------- -----------
7369 SMITH      CLERK     17-DEC-1980
7499 ALLEN      SALESMAN  20-FEB-1981
7521 WARD       SALESMAN  22-FEB-1981
7566 JONES      MANAGER   02-APR-1981
7654 MARTIN     SALESMAN  28-SEP-1981
7698 BLAKE      MANAGER   01-MAY-1981
7782 CLARK      MANAGER   09-JUN-1981
7788 SCOTT      ANALYST   19-APR-1987
7839 KING       PRESIDENT 17-NOV-1981
7844 TURNER     SALESMAN  08-SEP-1981
7876 ADAMS      CLERK     23-MAY-1987
7900 JAMES      CLERK     03-DEC-1981
7902 FORD       ANALYST   03-DEC-1981
7934 MILLER     CLERK     23-JAN-1982

14 rows selected.

SQL>

OpenJSON

Преобразование данных из JSON в реляционный формат

OPENJSON — функция с табличным значением, которая выполняет синтаксический анализ текста JSON и возвращает объекты и свойства из входных данных JSON в виде строк и столбцов.

In :

declare @json nvarchar(4000) 
set @json = N'
{
    "FirstName": "Илья",
    "LastName": "Гавриленко",
    "YearOfBirth": 2006,
    "Gender": "м",
    "Club": {
        "Name": "ГЦОР Трактор",
        "City": "Минск"
    },
    "Category": "II",
    "Coach": 
} 
'

select *
from openjson(@json) 

--извлечь все атрибуты, в том числе, более чем 1 уровня вложенности
select *
from openjson(@json) 
    with 
        (
            FirstName       nvarchar(20)    N'$.FirstName',
            LastName        nvarchar(30)    N'$.LastName',
            YearOfBirth     smallint        N'$.YearOfBirth',
            Gender          nchar(1)        N'$.Gender',
            Category        nvarchar(20)    N'$.Category',
            ClubCity        nvarchar(50)    N'$.Club.City',
            ClubName        nvarchar(100)   N'$.Club.Name',
            Coach           nvarchar(max)   N'$.Coach'        as json
        )  js

(7 rows affected)
(1 row affected)
Total execution time: 00:00:00.0173023

Out:

Out:

Если вы хотите получить данные из вложенного массива JSON, можно использовать корреляционный вызов OPENJSON  с помощью CROSS APPLY или OUTER APPLY:

In :

declare @json nvarchar(4000) 
set @json = N'
{
    "FirstName": "Илья",
    "LastName": "Гавриленко",
    "YearOfBirth": 2006,
    "Gender": "м",
    "Club": {
        "Name": "ГЦОР Трактор",
        "City": "Минск"
    },
    "Category": "II",
    "Coach": 
} 
'

--извлечь все атрибуты, в том числе, более чем 1 уровня вложенности
select      js.FirstName,
            js.LastName,
            js.YearOfBirth,
            js.Gender,
            js.Category,
            js.ClubCity,
            js.ClubName,
            jsc.CoachFirstName, 
            jsc.CoachLastName
from openjson(@json) 
    with 
        (
            FirstName       nvarchar(20)    N'$.FirstName',
            LastName        nvarchar(30)    N'$.LastName',
            YearOfBirth     smallint        N'$.YearOfBirth',
            Gender          nchar(1)        N'$.Gender',
            Category        nvarchar(20)    N'$.Category',
            ClubCity        nvarchar(50)    N'$.Club.City',
            ClubName        nvarchar(100)   N'$.Club.Name',
            Coach           nvarchar(max)   N'$.Coach'        as json
        )  js 
outer apply openjson(js.Coach)        
    with 
        (
            CoachFirstName  nvarchar(20)    N'$.FirstName',
            CoachLastName   nvarchar(30)    N'$.LastName'
        )  jsc

(2 rows affected)
Total execution time: 00:00:00.0071696

Out :

Introduction

Extensible Markup Language (XML) has been in existence for more than two decades. XML is a markup language for encoding documents in a format that is both human and machine readable. In XML, you define your own custom tags, elements and attributes to meet your specific needs. XML is case sensitive, allows comments and hierarchy is important. An XML file is a text file and can be opened with any text editor. The following is a sample of an XML document:

When we run a query against a relational database table, the resulting data is presented mostly in tabular format. Each horizontal row represents a record while the columns flow vertically and represent an attribute of the record.

In this post, I explore how MS SQL Server and PostgreSQL databases may be queried to output the data in an XML format instead of tabular format. Each of these databases contain inbuilt functionality to output XML. You can also manually write queries combining XML elements and data from the databases to create XML output. Manually created XML output is tedious, will be missing a root element and will therefore not conform to a .

AUTO mode

AUTO mode is one of the approaches to converts over to the XML elements from the rows of the table. Element names of the XML document corresponding to the column alias or column name of the SELECT query.

For example, the query result has been produced with a single XML document for the above sample data. The query result had 5 rows in a result set, which is changed over to a solitary cell result-set. This methodology is utilized in a single-valued function to return multiple rows in a single return variable.

1
2
3

SELECTuser_id,fname,lname,email_

FROMuser_details

FORXMLAUTO;

Here, AUTO produces header names utilizing table names.

Recap

XML Serializable Models

As mentioned above, I have an article on the subject of Using the XmlSerializer Attributes. If you have sample XML or an XSD schema to work from, you can use tools like XSD.exe or Skeleton Crew to generate XML Serializable code models. And, if you don’t already have a model, you might want to start with the XML structure and generate code from there. If you already have a model that’s not XML serializable, the article above can help you pepper your model with the attributes necessary to produce the XML you want.

XML Queries

Documentation on the mode of the clause seems to be spread fairly thin. Most write-ups I could find on the subject were basic. But with some experimentation, hopefully, you can make it do what you need. In any event, these are a couple of the references I found:

  • Moving FOR XML EXPLICIT to the new PATH mode (part II)
  • What’s New in FOR XML in Microsoft SQL Server 2005

XMLSerializer

You can, of course, re-use the demo project’s class. You can change it to suit your needs. Or, you can start from scratch and create your own. I chose to specifically use the implementations because, to my knowledge, SQL Server 2005 is the only engine that supports the clause, but I could very well be wrong about that.

Создание полнотекстового индекса в SQL Server

После создания полнотекстового каталога можно начинать создавать в нем полнотекстовые индекса. В нашем случае мы хотим создать полнотекстовый индекс, в котором участвует поле textdata таблицы TestTable.

Создание полнотекстового индекса на T-SQL

Для того чтобы создать полнотекстовый индекс можно написать следующую SQL инструкцию

CREATE FULLTEXT INDEX ON TestTable(textdata)
	KEY INDEX PK_TestTable ON (TestCatalog) 
	WITH (CHANGE_TRACKING AUTO)
GO

Где,

  • CREATE FULLTEXT INDEX – команда создания полнотекстового индекса;
  • TestTable(textdata) – таблица и столбец, включенные в индекс;
  • KEY INDEX PK_TestTable – имя уникального индекса таблицы TestTable;
  • ON (TestCatalog) — указываем, что полнотекстовый индекс будет создан в полнотекстовом каталоге TestCatalog. Если не указать этот параметр, то индекс будет создан в полнотекстовом каталоге по умолчанию;
  • WITH (CHANGE_TRACKING AUTO) – это мы говорим, что все изменения, которые будут вноситься в базовую таблицу (TestTable), автоматически отобразятся и в нашем полнотекстовом индексе, т.е. автоматическое заполнение.

Создание полнотекстового индекса в графическом интерфейсе Management Studio

Полнотекстовый индекс можно создать, используя и графические инструменты, для этого открываем свойства полнотекстового каталога и переходим в пункт «Таблицы или представления», выбираем нужную таблицу, поле, уникальный индекс и способ отслеживания изменений. В нашем случае у нас всего одна доступная таблица и одно поле.

Filtering Rows with XPath

We can limit the rows returned by altering the XPath expression. In the following example we only return rows with the job type of «CLERK».

SELECT xt.*
FROM   xml_tab x,
       XMLTABLE('/employees/employee'
         PASSING x.xml_data
         COLUMNS 
           empno     VARCHAR2(4)  PATH 'empno',
           ename     VARCHAR2(10) PATH 'ename',
           job       VARCHAR2(9)  PATH 'job',
           hiredate  VARCHAR2(11) PATH 'hiredate'
         ) xt;

EMPN ENAME      JOB       HIREDATE
---- ---------- --------- -----------
7369 SMITH      CLERK     17-DEC-1980
7876 ADAMS      CLERK     23-MAY-1987
7900 JAMES      CLERK     03-DEC-1981
7934 MILLER     CLERK     23-JAN-1982

4 rows selected.

SQL>

We could parameterise the job type using variable in the XPath, which is prefixed with a «$». The value for this variable is then passed in the clause. The variable must be aliases using and double quoted to make sure the name and case matches that of the variable in the XPath expression.

VARIABLE v_job VARCHAR2(10);
EXEC :v_job := 'CLERK';

SELECT xt.*
FROM   xml_tab x,
       XMLTABLE('/employees/employee'
         PASSING x.xml_data, :v_job AS "job"
         COLUMNS 
           empno     VARCHAR2(4)  PATH 'empno',
           ename     VARCHAR2(10) PATH 'ename',
           job       VARCHAR2(9)  PATH 'job',
           hiredate  VARCHAR2(11) PATH 'hiredate'
         ) xt;

EMPN ENAME      JOB       HIREDATE
---- ---------- --------- -----------
7369 SMITH      CLERK     17-DEC-1980
7876 ADAMS      CLERK     23-MAY-1987
7900 JAMES      CLERK     03-DEC-1981
7934 MILLER     CLERK     23-JAN-1982

4 rows selected.

SQL>

Изменение и удаление полнотекстового индекса

В случае необходимости можно изменить параметры полнотекстового индекса. Давайте в качестве примера, изменим способ отслеживания изменений с автоматического на ручной. Для изменения в графическом интерфейсе можно использовать окно «Свойства полнотекстового каталога -> Таблицы или представления», которое мы использовали при создании полнотекстового индекса.

Или можно написать следующий код

 ALTER FULLTEXT INDEX ON TestTable 
	SET CHANGE_TRACKING = MANUAL

Для того чтобы удалить полнотекстовый индекс достаточно просто удалить таблицу из списка объектов связанных с полнотекстовым каталогом в том же окне «Свойства полнотекстового каталога -> Таблицы или представления»

Или написать код T-SQL

  DROP FULLTEXT INDEX ON TestTable
Рейтинг
( Пока оценок нет )
Editor
Editor/ автор статьи

Давно интересуюсь темой. Мне нравится писать о том, в чём разбираюсь.

Понравилась статья? Поделиться с друзьями:
Вадлейд
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: