Spec-Zone.ru › MySQL 9.2

14.17.7 Функции валидации JSON-схем

MySQL поддерживает валидацию JSON-документов по JSON-схемам, соответствующим Спецификации JSON-схемы Draft 4. Это можно сделать, используя одну из функций, описанных в этом разделе, обе из которых принимают два аргумента: JSON-схему и JSON-документ, который валидируется по этой схеме. JSON_SCHEMA_VALID() возвращает true, если документ валиден по схеме, и false — если нет; JSON_SCHEMA_VALIDATION_REPORT() предоставляет отчёт в формате JSON о валидации.

Обе функции обрабатывают null или некорректные входные данные следующим образом:

  • Если хотя бы один из аргументов — NULL, функция возвращает NULL.

  • Если хотя бы один из аргументов не является корректным JSON, функция вызывает ошибку.

  • Кроме того, если схема не является корректным JSON-объектом, функция возвращает .

MySQL поддерживает атрибут required в JSON-схемах для принудительного включения необходимых свойств (см. примеры в описаниях функций).

MySQL поддерживает атрибуты id, $schema, description и type в JSON-схемах, но не требует их использования.

MySQL не поддерживает внешние ресурсы в JSON-схемах; использование ключевого слова $ref приводит к ошибке JSON_SCHEMA_VALID() с ошибкой .

Примечание

MySQL поддерживает регулярные выражения в JSON-схемах, которые поддерживаются, но игнорируются при обнаружении некорректного паттерна (см. описание JSON_SCHEMA_VALID() для примера).

Эти функции описаны подробно в следующем списке:

  • JSON_SCHEMA_VALID(schema,document)

    Валидирует JSON document по JSON schema. Оба schema и document обязательны. Схема должна быть корректным JSON-объектом; документ — корректным JSON-документом. При соблюдении этих условий: если документ валиден по схеме, функция возвращает true (1); в противном случае — false (0).

    В этом примере мы устанавливаем переменную пользователя @schema со значением JSON-схемы для географических координат и другую переменную @document со значением JSON-документа, содержащего одну такую координату. Затем мы проверяем, что @document валиден по @schema, используя их в качестве аргументов для JSON_SCHEMA_VALID():

    mysql> SET @schema = '{
        '>  "id": "http://json-schema.org/geo",
        '> "$schema": "http://json-schema.org/draft-04/schema#",
        '> "description": "A geographical coordinate",
        '> "type": "object",
        '> "properties": {
        '>   "latitude": {
        '>     "type": "number",
        '>     "minimum": -90,
        '>     "maximum": 90
        '>   },
        '>   "longitude": {
        '>     "type": "number",
        '>     "minimum": -180,
        '>     "maximum": 180
        '>   }
        '> },
        '> "required": ["latitude", "longitude"]
        '>}';
    Query OK, 0 rows affected (0.01 sec)
    
    mysql> SET @document = '{
        '> "latitude": 63.444697,
        '> "longitude": 10.445118
        '>}';
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> SELECT JSON_SCHEMA_VALID(@schema, @document);
    +---------------------------------------+
    | JSON_SCHEMA_VALID(@schema, @document) |
    +---------------------------------------+
    |                                     1 |
    +---------------------------------------+
    1 row in set (0.00 sec)
    

    Поскольку @schema содержит атрибут required, мы можем установить @document со значением, которое в противном случае было бы валидно, но не содержит требуемых свойств, и затем проверить его на соответствие @schema, как показано здесь:

    mysql> SET @document = '{}';
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> SELECT JSON_SCHEMA_VALID(@schema, @document);
    +---------------------------------------+
    | JSON_SCHEMA_VALID(@schema, @document) |
    +---------------------------------------+
    |                                     0 |
    +---------------------------------------+
    1 row in set (0.00 sec)
    

    Если теперь мы установим значение @schema на ту же JSON-схему, но без атрибута required, @document будет валиден, поскольку это корректный JSON-объект, даже если он не содержит свойств, как показано здесь:

    mysql> SET @schema = '{
        '> "id": "http://json-schema.org/geo",
        '> "$schema": "http://json-schema.org/draft-04/schema#",
        '> "description": "A geographical coordinate",
        '> "type": "object",
        '> "properties": {
        '>   "latitude": {
        '>     "type": "number",
        '>     "minimum": -90,
        '>     "maximum": 90
        '>   },
        '>   "longitude": {
        '>     "type": "number",
        '>     "minimum": -180,
        '>     "maximum": 180
        '>   }
        '> }
        '>}';
    Query OK, 0 rows affected (0.00 sec)
    
    
    mysql> SELECT JSON_SCHEMA_VALID(@schema, @document);
    +---------------------------------------+
    | JSON_SCHEMA_VALID(@schema, @document) |
    +---------------------------------------+
    |                                     1 |
    +---------------------------------------+
    1 row in set (0.00 sec)
    

    JSON_SCHEMA_VALID() и ограничения CHECK. JSON_SCHEMA_VALID() также можно использовать для принудительного соблюдения ограничений CHECK.

    Рассмотрим таблицу geo, созданную, как показано здесь, со столбцом JSON coordinate, представляющим точку широты и долготы на карте, управляемым JSON-схемой, используемой в качестве аргумента в вызове JSON_SCHEMA_VALID(), который передаётся в качестве выражения для ограничения CHECK в этой таблице:

    mysql> CREATE TABLE geo (
        ->     coordinate JSON,
        ->     CHECK(
        ->         JSON_SCHEMA_VALID(
        ->             '{
        '>                 "type":"object",
        '>                 "properties":{
        '>                       "latitude":{"type":"number", "minimum":-90, "maximum":90},
        '>                       "longitude":{"type":"number", "minimum":-180, "maximum":180}
        '>                 },
        '>                 "required": ["latitude", "longitude"]
        '>             }',
        ->             coordinate
        ->         )
        ->     )
        -> );
    Query OK, 0 rows affected (0.45 sec)
    
    Примечание

    Поскольку ограничение MySQL CHECK не может содержать ссылок на переменные, вы должны передавать JSON-схему в JSON_SCHEMA_VALID() в строчном виде при использовании её для указания такого ограничения для таблицы.

    Мы присваиваем значения JSON, представляющие координаты, трём переменным, как показано здесь:

    mysql> SET @point1 = '{"latitude":59, "longitude":18}';
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> SET @point2 = '{"latitude":91, "longitude":0}';
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> SET @point3 = '{"longitude":120}';
    Query OK, 0 rows affected (0.00 sec)
    

    Первое из этих значений является корректным, как видно из следующего оператора INSERT:

    mysql> INSERT INTO geo VALUES(@point1);
    Query OK, 1 row affected (0.05 sec)
    

    Второе значение JSON некорректно и поэтому не удовлетворяет ограничению, как показано здесь:

    mysql> INSERT INTO geo VALUES(@point2);
    ERROR 3819 (HY000): Check constraint 'geo_chk_1' is violated.
    

    Вы можете получить точную информацию о характере ошибки — в данном случае, что значение latitude превышает максимальное значение, определённое в схеме — выдав оператор SHOW WARNINGS:

    mysql> SHOW WARNINGS\G
    *************************** 1. row ***************************
      Level: Error
       Code: 3934
    Message: The JSON document location '#/latitude' failed requirement 'maximum' at
    JSON Schema location '#/properties/latitude'.
    *************************** 2. row ***************************
      Level: Error
       Code: 3819
    Message: Check constraint 'geo_chk_1' is violated.
    2 rows in set (0.00 sec)
    

    Третье значение координат, определённое выше, также некорректно, так как отсутствует требуемое свойство latitude. Как и прежде, вы можете увидеть это, попытавшись вставить значение в таблицу geo, а затем выдав SHOW WARNINGS:

    mysql> INSERT INTO geo VALUES(@point3);
    ERROR 3819 (HY000): Check constraint 'geo_chk_1' is violated.
    mysql> SHOW WARNINGS\G
    *************************** 1. row ***************************
      Level: Error
       Code: 3934
    Message: The JSON document location '#' failed requirement 'required' at JSON
    Schema location '#'.
    *************************** 2. row ***************************
      Level: Error
       Code: 3819
    Message: Check constraint 'geo_chk_1' is violated.
    2 rows in set (0.00 sec)
    

    См. Раздел 15.1.21.6, «Ограничения CHECK», для получения дополнительной информации.

    JSON-схемы поддерживают указание регулярных выражений для строк, но реализация, используемая MySQL, игнорирует некорректные шаблоны. Это означает, что JSON_SCHEMA_VALID() может возвращать true даже тогда, когда регулярное выражение некорректно, как показано здесь:

    mysql> SELECT JSON_SCHEMA_VALID('{"type":"string","pattern":"("}', '"abc"');
    +---------------------------------------------------------------+
    | JSON_SCHEMA_VALID('{"type":"string","pattern":"("}', '"abc"') |
    +---------------------------------------------------------------+
    |                                                             1 |
    +---------------------------------------------------------------+
    1 row in set (0.04 sec)
    
  • JSON_SCHEMA_VALIDATION_REPORT(schema,document)

    Валидирует JSON document по JSON schema. Оба schema и document обязательны. Как и в случае с JSON_VALID_SCHEMA(), схема должна быть корректным JSON-объектом, а документ — корректным JSON-документом. При выполнении этих условий функция возвращает отчёт в виде JSON-документа о результатах валидации. Если JSON-документ считается валидным по JSON-схеме, функция возвращает JSON-объект с одним свойством valid со значением "true". Если валидация JSON-документа не пройдена, функция возвращает JSON-объект, который включает указанные здесь свойства:

    • valid: Всегда "false" для неуспешной валидации схемы

    • reason: Читабельный строковый текст с причиной неудачи

    • schema-location: URI-фрагмент JSON-указателя, указывающий, где в JSON-схеме произошла ошибка валидации (см. Примечание ниже)

    • document-location: URI-фрагмент JSON-указателя, указывающий, где в JSON-документе произошла ошибка валидации (см. Примечание ниже)

    • schema-failed-keyword: Строка, содержащая имя ключевого слова или свойства в JSON-схеме, которое было нарушено

    Примечание

    URI-фрагменты JSON-указателей определены в RFC 6901 - JavaScript Object Notation (JSON) Pointer. (Они не являются тем же, что и обозначение JSON-путей, используемое JSON_EXTRACT() и другими функциями JSON MySQL.) В этой нотации # представляет весь документ, а #/myprop представляет часть документа, включённую в свойство верхнего уровня с именем myprop. См. цитированную спецификацию и примеры, показанные позже в этом разделе, для получения дополнительной информации.

    В этом примере мы устанавливаем переменную пользователя @schema со значением JSON-схемы для географических координат и другую переменную @document со значением JSON-документа, содержащего одну такую координату. Затем мы проверяем, что @document валиден по @schema, используя их в качестве аргументов для JSON_SCHEMA_VALIDATION_REORT():

    mysql> SET @schema = '{
        '>  "id": "http://json-schema.org/geo",
        '> "$schema": "http://json-schema.org/draft-04/schema#",
        '> "description": "A geographical coordinate",
        '> "type": "object",
        '> "properties": {
        '>   "latitude": {
        '>     "type": "number",
        '>     "minimum": -90,
        '>     "maximum": 90
        '>   },
        '>   "longitude": {
        '>     "type": "number",
        '>     "minimum": -180,
        '>     "maximum": 180
        '>   }
        '> },
        '> "required": ["latitude", "longitude"]
        '>}';
    Query OK, 0 rows affected (0.01 sec)
    
    mysql> SET @document = '{
        '> "latitude": 63.444697,
        '> "longitude": 10.445118
        '>}';
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> SELECT JSON_SCHEMA_VALIDATION_REPORT(@schema, @document);
    +---------------------------------------------------+
    | JSON_SCHEMA_VALIDATION_REPORT(@schema, @document) |
    +---------------------------------------------------+
    | {"valid": true}                                   |
    +---------------------------------------------------+
    1 row in set (0.00 sec)
    

    Теперь мы устанавливаем @document, чтобы он указывал некорректное значение для одного из его свойств, как показано здесь:

    mysql> SET @document = '{
        '> "latitude": 63.444697,
        '> "longitude": 310.445118
        '> }';
    

    Валидация @document теперь терпит неудачу при проверке с JSON_SCHEMA_VALIDATION_REPORT(). Выходные данные вызова функции содержат подробную информацию об ошибке (с функцией, обернутой JSON_PRETTY() для лучшего форматирования), как показано здесь:

    mysql> SELECT JSON_PRETTY(JSON_SCHEMA_VALIDATION_REPORT(@schema, @document))\G
    *************************** 1. row ***************************
    JSON_PRETTY(JSON_SCHEMA_VALIDATION_REPORT(@schema, @document)): {
      "valid": false,
      "reason": "The JSON document location '#/longitude' failed requirement 'maximum' at JSON Schema location '#/properties/longitude'",
      "schema-location": "#/properties/longitude",
      "document-location": "#/longitude",
      "schema-failed-keyword": "maximum"
    }
    1 row in set (0.00 sec)
    

    Поскольку @schema содержит атрибут required, мы можем установить @document со значением, которое в противном случае было бы валидно, но не содержит необходимых свойств, и затем проверить его на соответствие @schema. Выходные данные JSON_SCHEMA_VALIDATION_REPORT() показывают, что валидация не проходит из-за отсутствия требуемого элемента, как показано здесь:

    mysql> SET @document = '{}';
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> SELECT JSON_PRETTY(JSON_SCHEMA_VALIDATION_REPORT(@schema, @document))\G
    *************************** 1. row ***************************
    JSON_PRETTY(JSON_SCHEMA_VALIDATION_REPORT(@schema, @document)): {
      "valid": false,
      "reason": "The JSON document location '#' failed requirement 'required' at JSON Schema location '#'",
      "schema-location": "#",
      "document-location": "#",
      "schema-failed-keyword": "required"
    }
    1 row in set (0.00 sec)
    

    Если теперь мы установим значение @schema на ту же JSON-схему, но без атрибута required, @document будет валиден, поскольку это корректный JSON-объект, даже если он не содержит свойств, как показано здесь:

    mysql> SET @schema = '{
        '> "id": "http://json-schema.org/geo",
        '> "$schema": "http://json-schema.org/draft-04/schema#",
        '> "description": "A geographical coordinate",
        '> "type": "object",
        '> "properties": {
        '>   "latitude": {
        '>     "type": "number",
        '>     "minimum": -90,
        '>     "maximum": 90
        '>   },
        '>   "longitude": {
        '>     "type": "number",
        '>     "minimum": -180,
        '>     "maximum": 180
        '>   }
        '> }
        '>}';
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> SELECT JSON_SCHEMA_VALIDATION_REPORT(@schema, @document);
    +---------------------------------------------------+
    | JSON_SCHEMA_VALIDATION_REPORT(@schema, @document) |
    +---------------------------------------------------+
    | {"valid": true}                                   |
    +---------------------------------------------------+
    1 row in set (0.00 sec)
    

© 2025 Oracle
Licensed under the GPLv2 License.
https://docs.oracle.com/cd/E17952_01/mysql-9.2-en/json-validation-functions.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API