7.1.11 Режимы SQL сервера
Сервер MySQL может работать в разных режимах SQL и применять эти режимы по-разному для разных клиентов, в зависимости от значения системной переменной sql_mode. Администраторы баз данных могут установить глобальный режим SQL, соответствующий требованиям операционной системы сервера сайта, а каждое приложение может установить свой сессионный режим SQL в соответствии со своими потребностями.
Режимы влияют на синтаксис SQL, поддерживаемый MySQL, и проверки валидности данных, которые он выполняет. Это упрощает использование MySQL в разных средах и совместную работу MySQL с другими серверами баз данных.
Для ответов на часто задаваемые вопросы о режимах SQL сервера в MySQL, см. Приложение А.3, «MySQL 9.2 FAQ: Режим SQL сервера».
При работе с InnoDB таблицами, рассмотрите также системную переменную innodb_strict_mode. Она включает дополнительные проверки ошибок для InnoDB таблиц.
Установка режима SQL
По умолчанию режим SQL в MySQL 9.2 включает следующие режимы: 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.