ISJSON: примеры (SQL)

Проверка JSON в MS SQL с помощью функции ISJSON
Раздел: JSON функции, JSON
ISJSON(json_expression): int

Функция ISJSON в MS SQL Server

Функция ISJSON проверяет, содержит ли строка допустимые данные в формате JSON. Она используется для валидации входных данных перед их обработкой с помощью других JSON-функций, таких как JSON_VALUE или JSON_QUERY, что позволяет избежать ошибок во время выполнения запроса.

Синтаксис функции: ISJSON ( expression [, json_type_constraint] ).

  • expression - проверяемое выражение, обычно строкового типа (nvarchar, varchar).
  • json_type_constraint - необязательный целочисленный аргумент (флаг), который указывает, какой тип JSON следует проверять. Доступные значения:
    • 0 или без аргумента (по умолчанию): Проверяет, является ли выражение допустимым объектом или массивом JSON.
    • 1: Проверяет, является ли выражение допустимым объектом JSON.
    • 2: Проверяет, является ли выражение допустимым массивом JSON.

Возвращаемые значения:

  • 1: Если строка содержит допустимый JSON указанного типа.
  • 0: Если строка не содержит допустимый JSON или ее тип отличен от указанного в ограничении.
  • NULL: Если выражение expression имеет значение NULL.

Примеры базового использования

Простая проверка валидности строки как JSON.

SELECT ISJSON('{"name": "John", "age": 30}') AS Result;
Result
1

Проверка с указанием, что строка должна быть объектом JSON (флаг 1).

SELECT ISJSON('{"id": 1}', 1) AS Result_Object;
Result_Object
1

Проверка с указанием, что строка должна быть массивом JSON (флаг 2).

SELECT ISJSON('[1, 2, 3]', 2) AS Result_Array;
Result_Array
1

Пример возврата 0 для невалидного JSON.

SELECT ISJSON('{name: "John"}') AS Result; -- Нет кавычек у ключа
Result
0

Проверка несоответствия указанному типу. Запрос ожидает массив, но передан объект.

SELECT ISJSON('{"test": true}', 2) AS Result;
Result
0

Обработка NULL.

SELECT ISJSON(NULL) AS Result;
Result
NULL

Похожие функции MS SQL

  • JSON_VALUE: Извлекает скалярное значение (строку, число, логическое значение) из строки JSON по указанному пути. Используется, когда требуется получить конкретное поле. ISJSON применяют перед JSON_VALUE для проверки.
  • JSON_QUERY: Извлекает объект или массив (фрагмент JSON) из строки JSON по указанному пути. ISJSON может проверить валидность извлеченного фрагмента.
  • OPENJSON: Табличная функция, преобразующая строку JSON в набор строк и столбцов. ISJSON часто используется в предложении WHERE для фильтрации только валидных строк перед применением OPENJSON.

Функция ISJSON является единственной функцией валидации. Ее используют первым шагом в цепочке обработки JSON для обеспечения безопасности операций.

Типичные ошибки

  • Проверка нестроковых типов данных. Функция ожидает строку, другие типы могут привести к неявному преобразованию или ошибке.
  • -- Явное преобразование числа в строку не происходит, возвращается 0.
    SELECT ISJSON(123) AS Result;
    Result
    0
  • Использование функции для уже разобранного JSON. Если данные хранятся в столбце типа NVARCHAR(MAX), проблем нет. Но тип JSON, введенный в SQL Server 2016, не является строковым, и ISJSON вызовет ошибку.
  • -- Создание таблицы с типом JSON (псевдоним для NVARCHAR).
    DECLARE @t TABLE (data JSON);
    INSERT INTO @t VALUES ('{"key": "value"}');
    -- ISJSON работает, т.к. тип JSON по сути NVARCHAR.
    SELECT ISJSON(data) FROM @t;
    1
  • Непонимание возвращаемого значения NULL. При проверке поля, которое может быть NULL, результат также будет NULL, что в условии WHERE может быть интерпретировано как UNKNOWN и отфильтровано.
  • SELECT ISJSON(NULL) AS Result WHERE ISJSON(NULL) = 1; -- Ни одной строки не возвращено.
    (нет строк)

История изменений

  • SQL Server 2016 (13.x): Функция ISJSON была введена вместе с первоначальной поддержкой JSON.
  • SQL Server 2022 (16.x): Добавлен необязательный второй аргумент json_type_constraint, позволяющий проверять, является ли выражение объектом или массивом JSON. В предыдущих версиях функция имела только один аргумент.

В актуальных версиях рекомендуется использовать второй аргумент для более строгой проверки, если структура JSON известна заранее.

Расширенные примеры использования

Использование в предложении WHERE для фильтрации только валидных JSON-строк в таблице.

Пример sql
DECLARE @TestTable TABLE (id INT, json_data NVARCHAR(MAX));
INSERT INTO @TestTable VALUES
(1, '{"order": 101}'),
(2, 'Invalid JSON'),
(3, NULL),
(4, '[1,2,3]');

SELECT id, json_data
FROM @TestTable
WHERE ISJSON(json_data) = 1;
id  json_data
1   {"order": 101}
4   [1,2,3]

Комбинация с OPENJSON. Сначала проверяем, затем разбираем.

Пример sql
DECLARE @json NVARCHAR(MAX) = N'[
  {"name": "Alice", "score": 95},
  {"name": "Bob", "score": 88}
]';

SELECT name, score
FROM OPENJSON(@json)
WITH (name NVARCHAR(50), score INT)
WHERE ISJSON(@json) = 1; -- Гарантия валидности
name   score
Alice  95
Bob    88

Использование в вычисляемом столбце или ограничении для обеспечения целостности данных.

Пример sql
CREATE TABLE Documents (
    ID INT IDENTITY PRIMARY KEY,
    JsonContent NVARCHAR(MAX) CHECK (ISJSON(JsonContent) = 1)
);
-- Вставка пройдет
INSERT INTO Documents (JsonContent) VALUES ('{"status": "active"}');
-- Вставка не пройдет из-за нарушения ограничения CHECK
INSERT INTO Documents (JsonContent) VALUES ('Invalid');

Проверка вложенных JSON-фрагментов, извлеченных с помощью JSON_QUERY.

Пример sql
DECLARE @config NVARCHAR(MAX) = '
{
  "system": {"log": true},
  "users": ["admin", "user"]
}';

-- Проверяем, что извлеченное значение "system" является объектом JSON
SELECT 
    ISJSON(JSON_QUERY(@config, '$.system'), 1) AS IsSystemObject,
    ISJSON(JSON_QUERY(@config, '$.users'), 2) AS IsUsersArray;
IsSystemObject IsUsersArray
1             1

Обработка в сценарии миграции или очистки данных для поиска некорректных записей.

Пример sql
-- Найти все строки, где поле не содержит валидный JSON объект.
-- Используется флаг 1 для поиска именно объектов, а не массивов.
SELECT id, json_data
FROM RawDataTable
WHERE ISJSON(json_data, 1) = 0 
    AND json_data IS NOT NULL; -- Исключаем NULL из отчета

Аналоги в других СУБД и языках

  • MySQL: Функция JSON_VALID. Возвращает 1 (true) или 0 (false). Не поддерживает флаги для проверки типа.
  • SELECT JSON_VALID('{"a": 1}'); -- 1
    SELECT JSON_VALID('{a: 1}');   -- 0
    1
    0
  • PostgreSQL: Оператор IS JSON или функция jsonb_typeof (для jsonb). Проверка типа возможна через уточняющие слова: VALUE, ARRAY, OBJECT, SCALAR.
  • SELECT '{"a":1}'::jsonb IS JSON OBJECT; -- true
    SELECT '[1,2]'::jsonb IS JSON ARRAY;    -- true
    true
    true
  • Oracle: Метод IS JSON в проверочном ограничении. В SQL использует условие с ключевыми словами.
  • SELECT CASE WHEN '{"status":"OK"}' IS JSON THEN 'VALID' ELSE 'INVALID' END FROM DUAL;
    VALID
  • SQLite: Встроенной функции валидации JSON нет. Обычно используют функцию json_error_position из расширения JSON1 или обрабатывают ошибки при вызове других JSON-функций.
  • JavaScript: Используют блок try-catch с JSON.parse().
  • function isJson(str) {
        try { JSON.parse(str); return true; }
        catch(e) { return false; }
    }

Отличие MS SQL в поддержке опционального аргумента для проверки конкретного типа JSON (объект или массив).

MS SQL ISJSON function comments

En
ISJSON Tests whether a string contains valid JSON