14.17.7 Функции валидации JSON-схем
MySQL поддерживает валидацию JSON-документов по отношению к JSON-схемам, соответствующим черновику 4 спецификации JSON Schema. Это можно сделать, используя любую из функций, подробно описанных в этом разделе, обе из которых принимают два аргумента: 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по отношению к JSONschema. И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)ПримечаниеПоскольку ограничение CHECK в MySQL не может содержать ссылки на переменные, вам необходимо передать 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.20.6, «Ограничения CHECK» для получения дополнительной информации.
JSON Schema поддерживает указание шаблонов регулярных выражений для строк, но реализация, используемая 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по отношению к JSONschema. И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.