Поиск…


Синтаксис

  • JSON_VALUE (выражение, путь) - извлекает скалярное значение из строки JSON.
  • JSON_QUERY (выражение [, путь]) - извлекает объект или массив из строки JSON.
  • OPENJSON (jsonExpression [, path]) - функция table-value, которая анализирует текст JSON и возвращает объекты и свойства в JSON в виде строк и столбцов.
  • ISJSON (выражение) - проверяет, содержит ли строка действительный JSON.
  • JSON_MODIFY (выражение, путь, newValue) - обновляет значение свойства в строке JSON и возвращает обновленную строку JSON.

параметры

параметры подробности
выражение Как правило, имя переменной или столбца, содержащего текст JSON.
дорожка Выражение пути JSON, которое указывает свойство для обновления. path имеет следующий синтаксис: [append] [lax | strict] $. <json path>
jsonExpression Является символьным символом Unicode, содержащим текст JSON.

замечания

Функция OPENJSON доступна только на уровне совместимости 130. Если уровень совместимости базы данных ниже 130, SQL Server не сможет найти и выполнить функцию OPENJSON. В настоящее время все базы данных Azure SQL по умолчанию установлены в 120. Вы можете изменить уровень совместимости базы данных, используя следующую команду:

ALTER DATABASE <Database-Name-Here> SET COMPATIBILITY_LEVEL = 130

Форматировать результаты запроса как JSON с FOR JSON

Данные входных таблиц (таблица «Люди»)

Я бы название Возраст
1 Джон 23
2 Джейн 31

запрос

SELECT Id, Name, Age
FROM People
FOR JSON PATH

Результат

[
    {"Id":1,"Name":"John","Age":23},
    {"Id":2,"Name":"Jane","Age":31}
]

Текст анализа JSON

Функции JSON_VALUE и JSON_QUERY анализируют текст JSON и возвращают скалярные значения или объекты / массивы на пути в тексте JSON.

DECLARE @json NVARCHAR(100) = '{"id": 1, "user":{"name":"John"}, "skills":["C#","SQL"]}'

SELECT
    JSON_VALUE(@json, '$.id') AS Id,
    JSON_VALUE(@json, '$.user.name') AS Name,
    JSON_QUERY(@json, '$.user') AS UserObject,
    JSON_QUERY(@json, '$.skills') AS Skills,
    JSON_VALUE(@json, '$.skills[0]') AS Skill0

Результат

Я бы название UserObject Навыки Skill0
1 Джон { "Имя": "Джон"} [ "C #", "SQL"] C #

Присоединяйте родительские и дочерние объекты JSON, используя CROSS APPLY OPENJSON

Присоединяйте родительские объекты со своими дочерними объектами, например, мы хотим, чтобы реляционная таблица каждого человека и их хобби

DECLARE @json nvarchar(1000) =
N'[
    {
        "id":1,
        "user":{"name":"John"},
        "hobbies":[
            {"name": "Reading"},
            {"name": "Surfing"}
        ]
    },
    {
        "id":2,
        "user":{"name":"Jane"},
        "hobbies":[
            {"name": "Programming"},
            {"name": "Running"}
        ]
    }
 ]'

запрос

SELECT 
    JSON_VALUE(person.value, '$.id') as Id,
    JSON_VALUE(person.value, '$.user.name') as PersonName,
    JSON_VALUE(hobbies.value, '$.name') as Hobby
FROM OPENJSON (@json) as person
    CROSS APPLY OPENJSON(person.value, '$.hobbies') as hobbies

В качестве альтернативы этот запрос можно записать с помощью предложения WITH.

SELECT 
    Id, person.PersonName, Hobby
FROM OPENJSON (@json)
WITH(
    Id int '$.id',
    PersonName nvarchar(100) '$.user.name',
    Hobbies nvarchar(max) '$.hobbies' AS JSON
) as person
CROSS APPLY OPENJSON(Hobbies)
WITH(
    Hobby nvarchar(100) '$.name'
)

Результат

Я бы PersonName Хобби
1 Джон чтение
1 Джон серфинг
2 Джейн программирование
2 Джейн Бег

Индекс по свойствам JSON с использованием вычисленных столбцов

При хранении JSON-документов в SQL Server нам необходимо иметь возможность эффективно фильтровать и сортировать результаты запроса по свойствам документов JSON.

CREATE TABLE JsonTable
(
    id int identity primary key,
    jsonInfo nvarchar(max),
    CONSTRAINT [Content should be formatted as JSON]
    CHECK (ISJSON(jsonInfo)>0)
)
INSERT INTO JsonTable
VALUES(N'{"Name":"John","Age":23}'),
(N'{"Name":"Jane","Age":31}'),
(N'{"Name":"Bob","Age":37}'),
(N'{"Name":"Adam","Age":65}')
GO

Учитывая приведенную выше таблицу. Если мы хотим найти строку с именем = 'Adam', мы выполним следующий запрос.

SELECT * 
FROM JsonTable Where 
JSON_VALUE(jsonInfo, '$.Name') = 'Adam'

Однако для этого требуется, чтобы SQL-сервер выполнил полную таблицу, которая на большой таблице неэффективна.

Чтобы ускорить это, мы хотели бы добавить индекс, однако мы не можем напрямую ссылаться на свойства в документе JSON. Решение состоит в том, чтобы добавить вычисленный столбец в пути JSON $.Name , а затем добавить индекс в вычисленный столбец.

ALTER TABLE JsonTable
ADD vName as JSON_VALUE(jsonInfo, '$.Name')

CREATE INDEX idx_name
ON JsonTable(vName)

Теперь, когда мы выполняем один и тот же запрос, вместо полного сканирования таблицы SQL-сервер использует индекс для поиска в некластеризованном индексе и поиск строк, удовлетворяющих заданным условиям.

Примечание. Чтобы SQL-сервер использовал индекс, вы должны создать вычисленный столбец с тем же выражением, которое вы планируете использовать в своих запросах, - в этом примере JSON_VALUE(jsonInfo, '$.Name') , однако вы также можете использовать имя вычисленного столбца vName

Отформатируйте одну строку таблицы как единый объект JSON, используя FOR JSON

Параметр WITHOUT_ARRAY_WRAPPER в предложении FOR JSON удаляет скобки массива с выхода JSON. Это полезно, если вы возвращаете одну строку в запросе.

Примечание. Эта опция выдаст недопустимый вывод JSON, если возвращается более одной строки.

Данные входных таблиц (таблица «Люди»)

Я бы название Возраст
1 Джон 23
2 Джейн 31

запрос

SELECT Id, Name, Age
FROM People
WHERE Id = 1
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER

Результат

{"Id":1,"Name":"John","Age":23}

Разбирать текст JSON с использованием функции OPENJSON

Функция OPENJSON анализирует текст JSON и возвращает несколько выходов. Значения, которые должны быть возвращены, указываются с использованием путей, определенных в предложении WITH. Если для некоторого столбца не указан путь, имя столбца используется как путь. Эта функция возвращает возвращаемые значения в типы SQL, определенные в предложении WITH. Опция AS JSON должна указываться в определении столбца, если какой-либо объект / массив должен быть возвращен.

DECLARE @json NVARCHAR(100) = '{"id": 1, "user":{"name":"John"}, "skills":["C#","SQL"]}'

SELECT * 
FROM OPENJSON (@json)
    WITH(Id int '$.id',
        Name nvarchar(100) '$.user.name',
        UserObject nvarchar(max) '$.user' AS JSON,
        Skills nvarchar(max) '$.skills' AS JSON,
        Skill0 nvarchar(20) '$.skills[0]')

Результат

Я бы название UserObject Навыки Skill0
1 Джон { "Имя": "Джон"} [ "C #", "SQL"] C #


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow