7.1.11 Режимы SQL сервера
Сервер MySQL может работать в разных режимах SQL и применять эти режимы по-разному для разных клиентов, в зависимости от значения системной переменной sql_mode. Администраторы баз данных могут установить глобальный режим SQL, соответствующий требованиям сайта и сервера, а каждое приложение может установить свой сеансовый режим SQL для собственных потребностей.
Режимы влияют на синтаксис SQL, который поддерживает MySQL, и на проверки валидности данных, которые он выполняет. Это облегчает использование MySQL в различных средах и совместно с другими серверами баз данных.
Для ответов на часто задаваемые вопросы о режимах SQL сервера в MySQL см. Приложение A.3, «MySQL 8.4 FAQ: Режим SQL сервера».
При работе с InnoDB таблицами, также обратите внимание на системную переменную innodb_strict_mode. Она включает дополнительные проверки ошибок для InnoDB таблиц.
Установка режима SQL
По умолчанию режим SQL в MySQL 8.4 включает следующие режимы: ONLY_FULL_GROUP_BY, STRICT_TRANS_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO и NO_ENGINE_SUBSTITUTION.
Чтобы установить режим SQL при запуске сервера, используйте параметр --sql-mode=" в командной строке или modes"sql-mode=" в файле параметров, таком как modes"my.cnf (Unix-системы) или my.ini (Windows). modes — это список различных режимов, разделенных запятыми. Чтобы явно очистить режим SQL, установите его в пустую строку, используя --sql-mode="" в командной строке или sql-mode="" в файле параметров.
Программы установки MySQL могут настроить режим SQL во время процесса установки.
Если режим SQL отличается от значения по умолчанию или от ожидаемого, проверьте настройки в файле параметров, который сервер читает при запуске.
Чтобы изменить режим SQL во время выполнения, установите глобальную или сеансовую системную переменную sql_mode, используя оператор SET:
SET GLOBAL sql_mode = 'modes';
SET SESSION sql_mode = 'modes';
Установка переменной GLOBAL требует привилегии SYSTEM_VARIABLES_ADMIN (или устаревшей привилегии SUPER) и влияет на работу всех клиентов, подключающихся с этого момента. Установка переменной SESSION влияет только на текущего клиента. Каждый клиент может в любое время изменить значение сеансовой переменной sql_mode.
Чтобы определить текущее глобальное или сеансовое значение sql_mode, выберите его значение:
SELECT @@GLOBAL.sql_mode;
SELECT @@SESSION.sql_mode;
Режим SQL и пользовательское разбиение на разделы. Изменение режима SQL сервера после создания и вставки данных в таблицы с разбиением на разделы может вызвать существенные изменения в поведении таких таблиц и может привести к потере или повреждению данных. Сильно рекомендуется никогда не менять режим SQL после создания таблиц, использующих пользовательское разбиение на разделы.
При репликации таблиц с разбиением на разделы разные режимы SQL на источнике и реплике также могут привести к проблемам. Для наилучших результатов вы всегда должны использовать одинаковый режим SQL сервера на источнике и реплике.
Дополнительную информацию см. в Разделе 26.6, «Ограничения и пределы разбиения на разделы».
Наиболее важные режимы SQL
Вероятно, наиболее важными значениями sql_mode являются следующие:
-
Этот режим изменяет синтаксис и поведение, чтобы более точно соответствовать стандарту SQL. Это один из специальных комбинированных режимов, перечисленных в конце этого раздела.
-
Если значение не может быть вставлено в транзакционную таблицу, как указано, прервите выполнение оператора. Для не транзакционной таблицы прервите оператор, если значение встречается в операторе с единственной строкой или в первой строке оператора с множеством строк. Более подробные сведения приведены позже в этом разделе.
-
Заставьте MySQL работать как “традиционная” система управления базами данных SQL. Простым описанием этого режима является “выдавать ошибку вместо предупреждения” при вставке некорректного значения в столбец. Это один из специальных комбинированных режимов, перечисленных в конце этого раздела.
ПримечаниеПри включенном режиме
TRADITIONAL, операторINSERTилиUPDATEпрерывается как только возникает ошибка. Если вы используете движок хранения, не поддерживающий транзакции, это может быть не то, что вам нужно, потому что изменения данных, внесенные до ошибки, могут не быть отменены, что приведет к “частичному выполнению” обновления.
Когда в этом руководстве упоминается “строгий режим”, это означает режим, в котором включен либо STRICT_TRANS_TABLES, либо STRICT_ALL_TABLES, или оба.
Полный список режимов SQL
В данном списке описаны все поддерживаемые режимы SQL:
-
Не выполнять полную проверку дат. Проверять только, что месяц находится в диапазоне от 1 до 12, а день — в диапазоне от 1 до 31. Это может быть полезно для веб-приложений, которые получают год, месяц и день в трех отдельных полях и сохраняют именно то, что ввел пользователь, без проверки даты. Этот режим применяется к столбцам типа
DATEиDATETIME. Он не применяется к столбцам типаTIMESTAMP, которые всегда требуют корректной даты.При отключенном режиме
ALLOW_INVALID_DATESсервер требует, чтобы значения месяца и дня были допустимыми, а не просто находились в диапазоне от 1 до 12 и от 1 до 31 соответственно. При отключенном строгом режиме некорректные даты, такие как'2004-04-31', преобразуются в'0000-00-00', и генерируется предупреждение. При включенном строгом режиме некорректные даты вызывают ошибку. Для разрешения таких дат включитеALLOW_INVALID_DATES. -
Обрабатывать
"как символ кавычек для идентификаторов (как символ кавычек`), а не как символ кавычек для строк. Вы по-прежнему можете использовать`для выделения идентификаторов при включенном этом режиме. При включенном режимеANSI_QUOTES, вы не можете использовать двойные кавычки для выделения строковых литералов, поскольку они интерпретируются как идентификаторы. -
Режим
ERROR_FOR_DIVISION_BY_ZEROвлияет на обработку деления на ноль, что включаетMOD(. Для операций изменения данных (N,0)INSERT,UPDATE) его действие также зависит от того, включен ли строгий режим SQL.Если этот режим не включен, деление на ноль вставляет
NULLи не генерирует предупреждение.Если этот режим включен, деление на ноль вставляет
NULLи генерирует предупреждение.Если этот режим и строгий режим включены, деление на ноль приводит к ошибке, если также не указано
IGNORE. ДляINSERT IGNOREиUPDATE IGNOREделение на ноль вставляетNULLи генерирует предупреждение.
Для
SELECTделение на ноль возвращаетNULL. ВключениеERROR_FOR_DIVISION_BY_ZEROтакже вызывает генерацию предупреждения, независимо от того, включен ли строгий режим.ERROR_FOR_DIVISION_BY_ZEROустарел.ERROR_FOR_DIVISION_BY_ZEROне является частью строгого режима, но должен использоваться совместно со строгим режимом и включен по умолчанию. Предупреждение возникает, еслиERROR_FOR_DIVISION_BY_ZEROвключен без включения строгого режима или наоборот.Поскольку
ERROR_FOR_DIVISION_BY_ZEROустарел, ожидается, что он будет удален в будущей версии MySQL как отдельный режим, а его эффект будет включен в эффект строгого режима SQL. -
Приоритет оператора
NOTтаков, что выражения, такие какNOT a BETWEEN b AND c, анализируются какNOT (a BETWEEN b AND c). В некоторых более старых версиях MySQL выражение анализировалось как(NOT a) BETWEEN b AND c. Старое поведение с более высоким приоритетом можно получить, включив режим SQLHIGH_NOT_PRECEDENCE.mysql>
SET sql_mode = '';mysql>SELECT NOT 1 BETWEEN -5 AND 5;-> 0 mysql>SET sql_mode = 'HIGH_NOT_PRECEDENCE';mysql>SELECT NOT 1 BETWEEN -5 AND 5;-> 1 -
Разрешить пробелы между именем функции и символом
(. Это заставляет имена встроенных функций обрабатываться как зарезервированные слова. В результате идентификаторы, совпадающие с именами функций, должны быть заключены в кавычки, как описано в Разделе 11.2, «Имена объектов схемы». Например, поскольку существует функцияCOUNT(), использованиеcountв качестве имени таблицы в следующем операторе приводит к ошибке:mysql>
CREATE TABLE count (i INT);ERROR 1064 (42000): You have an error in your SQL syntaxИмя таблицы должно быть заключено в кавычки:
mysql>
CREATE TABLE `count` (i INT);Query OK, 0 rows affected (0.00 sec)Режим SQL
IGNORE_SPACEприменяется к встроенным функциям, а не к загружаемым или хранимым функциям. Размещение пробелов после имени загружаемой или хранимой функции всегда допустимо, независимо от того, включен лиIGNORE_SPACE.Для получения дополнительной информации о
IGNORE_SPACEсм. Раздел 11.2.5, «Разбор и разрешение имён функций». -
NO_AUTO_VALUE_ON_ZEROвлияет на обработку столбцовAUTO_INCREMENT. Обычно вы генерируете следующий номер последовательности для столбца, вставляя либоNULL, либо0в него.NO_AUTO_VALUE_ON_ZEROподавляет это поведение для0, так что толькоNULLгенерирует следующий номер последовательности.Этот режим может быть полезен, если
0было сохранено в столбцеAUTO_INCREMENTтаблицы. (Сохранение0, кстати, не рекомендуется.) Например, если вы экспортируете таблицу с помощью mysqldump и затем загружаете ее, MySQL обычно генерирует новые номера последовательности при встрече значений0, что приводит к таблице с содержимым, отличным от содержимого экспорта. ВключениеNO_AUTO_VALUE_ON_ZEROперед загрузкой файла экспорта решает эту проблему. По этой причине mysqldump автоматически включает в свой вывод оператор, который включаетNO_AUTO_VALUE_ON_ZERO. -
Включение этого режима отключает использование обратного слэша (
\) в качестве символа экранирования внутри строк и идентификаторов. При включенном этом режиме обратный слэш становится обычным символом, как и любой другой, и последовательность экранирования по умолчанию для выраженийLIKEизменяется так, что символ экранирования не используется. -
При создании таблицы игнорировать все директивы
INDEX DIRECTORYиDATA DIRECTORY. Эта опция полезна на серверах репликации. -
Управление автоматической заменой движка хранения по умолчанию, когда оператор, например,
CREATE TABLEилиALTER TABLEуказывает движок хранения, который отключен или не скомпилирован.По умолчанию
NO_ENGINE_SUBSTITUTIONвключен.Так как движки хранения могут подключаться во время выполнения, недоступные движки обрабатываются аналогично:
При отключенном
NO_ENGINE_SUBSTITUTION, дляCREATE TABLEиспользуется движок по умолчанию, а если нужный движок недоступен, возникает предупреждение. ДляALTER TABLEвозникает предупреждение, и таблица не изменяется.При включенном
NO_ENGINE_SUBSTITUTION, возникает ошибка, и таблица не создается или не изменяется, если нужный движок недоступен.
-
Вычитание между целочисленными значениями, где одно из них имеет тип
UNSIGNED, по умолчанию дает беззнаковый результат. Если результат в противном случае был бы отрицательным, возникает ошибка:mysql>
SET sql_mode = '';Query OK, 0 rows affected (0.00 sec) mysql>SELECT CAST(0 AS UNSIGNED) - 1;ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '(cast(0 as unsigned) - 1)'Если включен режим SQL
NO_UNSIGNED_SUBTRACTION, результат будет отрицательным:mysql>
SET sql_mode = 'NO_UNSIGNED_SUBTRACTION';mysql>SELECT CAST(0 AS UNSIGNED) - 1;+-------------------------+ | CAST(0 AS UNSIGNED) - 1 | +-------------------------+ | -1 | +-------------------------+Если результат такой операции используется для обновления столбца целых чисел
UNSIGNED, результат усекается до максимального значения для типа столбца или усекается до 0, если включенNO_UNSIGNED_SUBTRACTION. При включенном строгом режиме SQL возникает ошибка, и столбец остается неизменным.Когда включен
NO_UNSIGNED_SUBTRACTION, результат вычитания является знаковым, даже если любой операнд является беззнаковым. Например, сравните тип столбцаc2в таблицеt1с типом столбцаc2в таблицеt2:mysql>
SET sql_mode='';mysql>CREATE TABLE test (c1 BIGINT UNSIGNED NOT NULL);mysql>CREATE TABLE t1 SELECT c1 - 1 AS c2 FROM test;mysql>DESCRIBE t1;+-------+---------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+---------------------+------+-----+---------+-------+ | c2 | bigint(21) unsigned | NO | | 0 | | +-------+---------------------+------+-----+---------+-------+ mysql>SET sql_mode='NO_UNSIGNED_SUBTRACTION';mysql>CREATE TABLE t2 SELECT c1 - 1 AS c2 FROM test;mysql>DESCRIBE t2;+-------+------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+------------+------+-----+---------+-------+ | c2 | bigint(21) | NO | | 0 | | +-------+------------+------+-----+---------+-------+Это означает, что
BIGINT UNSIGNEDне на 100% пригоден во всех контекстах. См. Раздел 14.10, «Функции и операторы преобразования типов». -
Режим
NO_ZERO_DATEвлияет на то, разрешает ли сервер'0000-00-00'в качестве допустимой даты. Его влияние также зависит от того, включен ли строгий режим SQL.Если этот режим не включен,
'0000-00-00'разрешен, и вставки не вызывают предупреждений.Если этот режим включен,
'0000-00-00'разрешен, и вставки вызывают предупреждение.Если включены этот режим и строгий режим,
'0000-00-00'не разрешен, и вставки вызывают ошибку, если только не указано такжеIGNORE. ДляINSERT IGNOREиUPDATE IGNORE,'0000-00-00'разрешен, и вставки вызывают предупреждение.
NO_ZERO_DATEустарел.NO_ZERO_DATEне является частью строгого режима, но должен использоваться вместе со строгим режимом и включен по умолчанию. Предупреждение возникает, еслиNO_ZERO_DATEвключен без включения строгого режима или наоборот.Поскольку
NO_ZERO_DATEустарел, следует ожидать, что он будет удален в будущей версии MySQL как отдельное имя режима, а его эффект будет включен в эффекты строгого режима SQL. -
Режим
NO_ZERO_IN_DATEвлияет на то, разрешает ли сервер даты, в которых год отличен от нуля, но месяц или день равны 0. (Этот режим влияет на даты, такие как'2010-00-01'или'2010-01-00', но не'0000-00-00'. Чтобы управлять тем, разрешает ли сервер'0000-00-00', используйте режимNO_ZERO_DATE.) ВлияниеNO_ZERO_IN_DATEтакже зависит от того, включен ли строгий режим SQL.Если этот режим не включен, даты с нулевыми частями разрешены, и вставки не вызывают предупреждений.
Если этот режим включен, даты с нулевыми частями вставляются как
'0000-00-00'и вызывают предупреждение.Если включены этот режим и строгий режим, даты с нулевыми частями не разрешены, и вставки вызывают ошибку, если только не указано также
IGNORE. ДляINSERT IGNOREиUPDATE IGNORE, даты с нулевыми частями вставляются как'0000-00-00'и вызывают предупреждение.
NO_ZERO_IN_DATEустарел.NO_ZERO_IN_DATEне является частью строгого режима, но должен использоваться вместе со строгим режимом и включен по умолчанию. Предупреждение возникает, еслиNO_ZERO_IN_DATEвключен без включения строгого режима или наоборот.Поскольку
NO_ZERO_IN_DATEустарел, следует ожидать, что он будет удален в будущей версии MySQL как отдельное имя режима, а его эффект будет включен в эффекты строгого режима SQL. -
Отклонять запросы, для которых список select, условие
HAVINGили списокORDER BYссылаются на неагрегированные столбцы, которые не указаны в предложенииGROUP BYи не функционально зависят (однозначно определяются) от столбцовGROUP BY.Расширение MySQL для стандартного SQL допускает ссылки в предложении
HAVINGна выражения с псевдонимами в списке select. ПредложениеHAVINGможет ссылаться на псевдонимы независимо от того, включен лиONLY_FULL_GROUP_BY.Для дополнительного обсуждения и примеров см. Раздел 14.19.3, «Обработка GROUP BY в MySQL».
-
По умолчанию, конечные пробелы обрезаются из значений столбцов
CHARпри извлечении. Если включенPAD_CHAR_TO_FULL_LENGTH, обрезка не происходит, и извлеченные значенияCHARдополняются до полной длины. Этот режим не применяется к столбцамVARCHAR, для которых конечные пробелы сохраняются при извлечении.ПримечаниеPAD_CHAR_TO_FULL_LENGTHустарел. Ожидается его удаление в будущей версии MySQL.mysql>
CREATE TABLE t1 (c1 CHAR(10));Query OK, 0 rows affected (0.37 sec) mysql>INSERT INTO t1 (c1) VALUES('xy');Query OK, 1 row affected (0.01 sec) mysql>SET sql_mode = '';Query OK, 0 rows affected (0.00 sec) mysql>SELECT c1, CHAR_LENGTH(c1) FROM t1;+------+-----------------+ | c1 | CHAR_LENGTH(c1) | +------+-----------------+ | xy | 2 | +------+-----------------+ 1 row in set (0.00 sec) mysql>SET sql_mode = 'PAD_CHAR_TO_FULL_LENGTH';Query OK, 0 rows affected (0.00 sec) mysql>SELECT c1, CHAR_LENGTH(c1) FROM t1;+------------+-----------------+ | c1 | CHAR_LENGTH(c1) | +------------+-----------------+ | xy | 10 | +------------+-----------------+ 1 row in set (0.00 sec) -
Рассматривать
||как оператор конкатенации строк (то же самое, что иCONCAT()), а не как синоним дляOR. -
Рассматривать
REALкак синоним дляFLOAT. По умолчанию MySQL рассматриваетREALкак синоним дляDOUBLE. -
Включить строгий режим SQL для всех движков хранения. Недопустимые значения данных отклоняются. Подробнее см. Строгий режим SQL.
-
Включить строгий режим SQL для транзакционных движков хранения и, по возможности, для нетранзакционных движков хранения. Подробнее см. Строгий режим SQL.
-
Управлять тем, происходит ли округление или усечение при вставке значения
TIME,DATEилиTIMESTAMPс дробной частью секунд в столбец того же типа, но с меньшим количеством дробных разрядов. Поведение по умолчанию — использовать округление. Если этот режим включен, вместо этого происходит усечение. Следующая последовательность операторов иллюстрирует разницу:CREATE TABLE t (id INT, tval TIME(1)); SET sql_mode=''; INSERT INTO t (id, tval) VALUES(1, 1.55); SET sql_mode='TIME_TRUNCATE_FRACTIONAL'; INSERT INTO t (id, tval) VALUES(2, 1.55);
Результирующее содержимое таблицы выглядит следующим образом, где первое значение было подвергнуто округлению, а второе — усечению:
mysql>
SELECT id, tval FROM t ORDER BY id;+------+------------+ | id | tval | +------+------------+ | 1 | 00:00:01.6 | | 2 | 00:00:01.5 | +------+------------+См. также Раздел 13.2.6, «Дробные секунды в значениях времени».
Комбинации режимов SQL
Следующие специальные режимы предоставляются в виде сокращений для комбинаций значений режимов из предыдущего списка.
-
Эквивалентно
REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACEиONLY_FULL_GROUP_BY.Режим
ANSIтакже заставляет сервер возвращать ошибку для запросов, где агрегирующая функцияSс внешней ссылкойне может быть агрегирована во внешнем запросе относительно внешней ссылки. Вот пример такого запроса:S(outer_ref)SELECT * FROM t1 WHERE t1.a IN (SELECT MAX(t1.b) FROM t2 WHERE ...);
Здесь функция
MAX(t1.b)не может быть агрегирована во внешнем запросе, потому что она появляется в фрагментеWHEREэтого запроса. Стандарт SQL требует ошибки в этой ситуации. Если режимANSIне включен, сервер обрабатываетв таких запросах так же, как интерпретировал быS(outer_ref).S(const) -
TRADITIONALэквивалентноSTRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZEROиNO_ENGINE_SUBSTITUTION.
Жесткий режим SQL
Жесткий режим контролирует, как MySQL обрабатывает недопустимые или отсутствующие значения в операциях изменения данных, таких как INSERT или UPDATE. Значение может быть недопустимым по нескольким причинам. Например, оно может иметь неверный тип данных для столбца или выходить за пределы допустимого диапазона. Значение отсутствует, когда новая строка, подлежащая вставке, не содержит значения для столбца, не являющегося NULL, который не имеет явного DEFAULT в своем определении. (Для столбца NULL вставляется NULL, если значение отсутствует.) Жесткий режим также влияет на операторы DDL, такие как CREATE TABLE.
Если жесткий режим неактивен, MySQL вставляет скорректированные значения для недопустимых или отсутствующих значений и генерирует предупреждения (см. Раздел 15.7.7.42, «Оператор SHOW WARNINGS»). В жестком режиме вы можете получить такое поведение, используя INSERT IGNORE или UPDATE
IGNORE.
Для операторов, таких как SELECT, которые не изменяют данные, недопустимые значения генерируют предупреждение в жестком режиме, а не ошибку.
Жесткий режим генерирует ошибку при попытке создать ключ, длина которого превышает максимальную длину ключа. При отключенном жестком режиме это приводит к предупреждению и усечению ключа до максимальной длины.
Жесткий режим не влияет на проверку ограничений внешнего ключа. Для этого можно использовать foreign_key_checks. (См. Раздел 7.1.8, «Системные переменные сервера».)
Жесткий режим SQL активен, если включены либо STRICT_ALL_TABLES, либо STRICT_TRANS_TABLES, хотя их воздействие несколько различается:
Для транзакционных таблиц при включении
STRICT_ALL_TABLESилиSTRICT_TRANS_TABLESвозникает ошибка для недопустимых или отсутствующих значений в операторе изменения данных. Оператор прерывается и отменяется.-
Для не транзакционных таблиц поведение одинаково для обоих режимов, если некорректное значение встречается в первой строке, подлежащей вставке или обновлению: оператор прерывается, и таблица остаётся без изменений. Если оператор вставляет или изменяет несколько строк, а некорректное значение встречается во второй или последующей строке, результат зависит от того, какой режим жесткости включён:
Для
STRICT_ALL_TABLESMySQL возвращает ошибку и игнорирует остальные строки. Однако, так как предыдущие строки были вставлены или обновлены, результатом является частичное обновление. Для избежания этого используйте операторы с одной строкой, которые могут быть прерваны без изменения таблицы.Для
STRICT_TRANS_TABLESMySQL преобразует недопустимое значение в ближайшее допустимое значение для столбца и вставляет скорректированное значение. Если значение отсутствует, MySQL вставляет неявное значение по умолчанию для типа данных столбца. В любом случае MySQL генерирует предупреждение, а не ошибку, и продолжает обработку оператора. Неявные значения по умолчанию описаны в Разделе 13.6, «Значения по умолчанию типов данных».
Жесткий режим влияет на обработку деления на ноль, нулевых дат и нулей в датах следующим образом:
-
Жесткий режим влияет на обработку деления на ноль, включая
MOD(:N,0)Для операций изменения данных (
INSERT,UPDATE):Если жесткий режим не включён, деление на ноль вставляет
NULLи не генерирует предупреждение.Если жесткий режим включён, деление на ноль приводит к ошибке, если не указано
IGNORE. ДляINSERT IGNOREиUPDATE IGNOREделение на ноль вставляетNULLи генерирует предупреждение.
Для
SELECT, деление на ноль возвращаетNULL. Включение жесткого режима также вызывает генерацию предупреждения. -
Жесткий режим влияет на то, допускает ли сервер
'0000-00-00'как допустимую дату:Если жесткий режим не включён,
'0000-00-00'допускается, и вставки не генерируют предупреждение.Если жесткий режим включён,
'0000-00-00'не допускается, и вставки генерируют ошибку, если не указаноIGNORE. ДляINSERT IGNOREиUPDATE IGNORE,'0000-00-00'допускается, и вставки генерируют предупреждение.
-
Жесткий режим влияет на то, допускает ли сервер даты, в которых часть года отлична от нуля, но часть месяца или дня равна 0 (даты, такие как
'2010-00-01'или'2010-01-00'):Если жесткий режим не включён, даты с нулевыми частями допускаются, и вставки не генерируют предупреждение.
Если жесткий режим включён, даты с нулевыми частями не допускаются, и вставки генерируют ошибку, если не указано
IGNORE. ДляINSERT IGNOREиUPDATE IGNOREдаты с нулевыми частями вставляются как'0000-00-00'(что считается допустимым сIGNORE) и генерируют предупреждение.
Дополнительную информацию о жестком режиме по отношению к IGNORE см. в Сравнении ключевого слова IGNORE и жесткого режима SQL.
Жесткий режим влияет на обработку деления на ноль, нулевых дат и нулей в датах в сочетании с режимами ERROR_FOR_DIVISION_BY_ZERO, NO_ZERO_DATE и NO_ZERO_IN_DATE.
Сравнение ключевого слова IGNORE и строгого режима SQL
В этом разделе сравнивается влияние ключевого слова IGNORE (которое понижает ошибки до предупреждений) и строгого режима SQL (который повышает предупреждения до ошибок) на выполнение операторов. В нём описывается, какие операторы они затрагивают и к каким ошибкам они применяются.
В следующей таблице представлено сравнение поведения операторов, когда по умолчанию возникает ошибка и когда по умолчанию возникает предупреждение. Пример, когда по умолчанию возникает ошибка — вставка NULL в столбец типа NOT
NULL. Пример, когда по умолчанию возникает предупреждение — вставка значения неправильного типа данных в столбец (например, вставка строки 'abc' в столбец целого типа).
| Режим работы | Когда по умолчанию возникает ошибка | Когда по умолчанию возникает предупреждение |
|---|---|---|
Без ключевого слова IGNORE или строгого режима SQL | Ошибка | Предупреждение |
С ключевым словом IGNORE | Предупреждение | Предупреждение (так же, как и без IGNORE или строгого режима SQL) |
| Со строгим режимом SQL | Ошибка (так же, как и без IGNORE или строгого режима SQL) | Ошибка |
С ключевым словом IGNORE и строгим режимом SQL | Предупреждение | Предупреждение |
Вывод из таблицы состоит в том, что когда ключевое слово IGNORE и строгий режим SQL оба активны, приоритет имеет IGNORE. Это означает, что, хотя ключевое слово IGNORE и строгий режим SQL могут считаться имеющими противоположное влияние на обработку ошибок, они не отменяют друг друга при совместном использовании.
Влияние ключевого слова IGNORE на выполнение операторов
Некоторые операторы в MySQL поддерживают необязательное ключевое слово IGNORE. Это ключевое слово заставляет сервер понижать определенные типы ошибок до предупреждений. Для операторов, работающих с несколькими строками, понижение ошибки до предупреждения может позволить обработать строку. В противном случае IGNORE заставляет оператор перейти к следующей строке вместо прерывания. (Для неизменяемых ошибок ошибка возникает независимо от ключевого слова IGNORE).
Пример: Если таблица t имеет столбец первичного ключа i, содержащий уникальные значения, попытка вставить одно и то же значение i в несколько строк обычно приводит к ошибке дублирования ключа:
mysql> CREATE TABLE t (i INT NOT NULL PRIMARY KEY);
mysql> INSERT INTO t (i) VALUES(1),(1);
ERROR 1062 (23000): Duplicate entry '1' for key 't.PRIMARY'
С IGNORE строка, содержащая дублирующий ключ, всё равно не вставляется, но вместо ошибки возникает предупреждение:
mysql> INSERT IGNORE INTO t (i) VALUES(1),(1);
Query OK, 1 row affected, 1 warning (0.01 sec)
Records: 2 Duplicates: 1 Warnings: 1
mysql> SHOW WARNINGS;
+---------+------+-----------------------------------------+
| Level | Code | Message |
+---------+------+-----------------------------------------+
| Warning | 1062 | Duplicate entry '1' for key 't.PRIMARY' |
+---------+------+-----------------------------------------+
1 row in set (0.00 sec)
Пример: Если таблица t2 имеет столбец NOT
NULL типа id, попытка вставить NULL приводит к ошибке в строгом режиме SQL:
mysql> CREATE TABLE t2 (id INT NOT NULL);
mysql> INSERT INTO t2 (id) VALUES(1),(NULL),(3);
ERROR 1048 (23000): Column 'id' cannot be null
mysql> SELECT * FROM t2;
Empty set (0.00 sec)
Если режим SQL не строгий, IGNORE приводит к вставке NULL в качестве неявного значения столбца по умолчанию (0 в данном случае), что позволяет обработать строку без пропуска:
mysql> INSERT INTO t2 (id) VALUES(1),(NULL),(3);
mysql> SELECT * FROM t2;
+----+
| id |
+----+
| 1 |
| 0 |
| 3 |
+----+
Эти операторы поддерживают ключевое слово IGNORE:
CREATE TABLE ... SELECT:IGNOREне применяется к частям оператораCREATE TABLEилиSELECT, но к вставкам в таблицу строк, полученных операторомSELECT. Строки, дублирующие существующую строку по значению уникального ключа, отбрасываются.DELETE:IGNOREзаставляет MySQL игнорировать ошибки во время удаления строк.-
INSERT: СIGNOREстроки, дублирующие существующую строку по значению уникального ключа, отбрасываются. Строки, заданные значениями, которые вызовут ошибки преобразования данных, устанавливаются на ближайшие допустимые значения.Для разнесённых таблиц, в которых не найдено разнесённой части, соответствующей заданному значению,
IGNOREзаставляет операцию вставки безмолвно завершаться для строк, содержащих несоответствующее значение. LOAD DATA,LOAD XML: СIGNOREстроки, дублирующие существующую строку по значению уникального ключа, отбрасываются.UPDATE: СIGNOREстроки, для которых возникают конфликты дублирования ключей по уникальному значению ключа, не обновляются. Строки, обновленные до значений, которые могут вызвать ошибки преобразования данных, обновляются до ближайших допустимых значений.
Ключевое слово IGNORE применяется к следующим игнорируемым ошибкам:
Влияние строгого режима SQL на выполнение операторов
MySQL-сервер может работать в различных режимах SQL и применять их по-разному для разных клиентов в зависимости от значения системной переменной sql_mode. В режиме “строгий” SQL-режим сервер повышает некоторые предупреждения до ошибок.
Например, в нестрогом режиме SQL вставка строки 'abc' в столбец целого типа приводит к преобразованию значения в 0 и предупреждению:
mysql> SET sql_mode = '';
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO t (i) VALUES('abc');
Query OK, 1 row affected, 1 warning (0.01 sec)
mysql> SHOW WARNINGS;
+---------+------+--------------------------------------------------------+
| Level | Code | Message |
+---------+------+--------------------------------------------------------+
| Warning | 1366 | Incorrect integer value: 'abc' for column 'i' at row 1 |
+---------+------+--------------------------------------------------------+
1 row in set (0.00 sec)
В строгом режиме SQL недопустимое значение отклоняется с ошибкой:
mysql> SET sql_mode = 'STRICT_ALL_TABLES';
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO t (i) VALUES('abc');
ERROR 1366 (HY000): Incorrect integer value: 'abc' for column 'i' at row 1
Дополнительную информацию о возможных значениях системной переменной sql_mode см. в разделе 7.1.11 «Режим SQL сервера».
Строгий режим SQL применяется к следующим операторам в условиях, когда некоторое значение может быть вне диапазона или некорректная строка вставляется или удаляется из таблицы:
В хранимых процедурах отдельные операторы перечисленных типов выполняются в строгом режиме SQL, если процедура была определена, когда был включен строгий режим.
Строгий режим SQL применяется к следующим ошибкам, которые представляют класс ошибок, в которых входное значение является либо недопустимым, либо отсутствует. Значение считается недопустимым, если оно имеет неправильный тип данных для столбца или может быть вне диапазона. Значение считается отсутствующим, если новая строка, подлежащая вставке, не содержит значения для столбца NOT
NULL, у которого нет явного DEFAULT-пункта в его определении.
Поскольку дальнейшее развитие MySQL определяет новые ошибки, могут быть ошибки, не включенные в предыдущий список, к которым применяется строгий режим SQL.
© 2025 Oracle
Licensed under the GPLv2 License.