Ограничение CHECK в MySQL не работает - PullRequest
121 голосов
/ 22 января 2010

Сначала я создал таблицу типа

CREATE TABLE Customer (
  SD integer CHECK (SD > 0),
  Last_Name varchar (30),
  First_Name varchar(30)
);

и затем вставленные значения в эту таблицу

INSERT INTO Customer values ('-2','abc','zz');

MySQL не показывает ошибку, он принял значения.

Ответы [ 8 ]

128 голосов
/ 22 января 2010

MySQL 8.0.16 - первая версия, поддерживающая ограничения CHECK.

Чтение https://dev.mysql.com/doc/refman/8.0/en/create-table-check-constraints.html

Если вы используете MySQL 8.0.15 или более раннюю версию, Справочное руководство MySQL говорит:

Предложение CHECK анализируется, но игнорируется всеми механизмами хранения.

Попробуйте триггер ...

mysql> delimiter //
mysql> CREATE TRIGGER trig_sd_check BEFORE INSERT ON Customer 
    -> FOR EACH ROW 
    -> BEGIN 
    -> IF NEW.SD<0 THEN 
    -> SET NEW.SD=0; 
    -> END IF; 
    -> END
    -> //
mysql> delimiter ;

Надеюсь, это поможет.

72 голосов
/ 10 января 2013

К сожалению, MySQL не поддерживает ограничения проверки SQL. Вы можете определить их в своем запросе DDL по причинам совместимости, но они просто игнорируются.

Существует простая альтернатива

Вы можете создавать триггеры BEFORE INSERT и BEFORE UPDATE, которые либо вызывают ошибку, либо устанавливают для поля значение по умолчанию, если требования данных не выполняются.

Пример BEFORE INSERT работы после MySQL 5.5

DELIMITER $$
CREATE TRIGGER `test_before_insert` BEFORE INSERT ON `Test`
FOR EACH ROW
BEGIN
    IF CHAR_LENGTH( NEW.ID ) < 4 THEN
        SIGNAL SQLSTATE '12345'
            SET MESSAGE_TEXT := 'check constraint on Test.ID failed';
    END IF;
END$$   
DELIMITER ;  

До MySQL 5.5 вы должны были вызвать ошибку, например, вызвать неопределенную процедуру.

В обоих случаях это вызывает неявный откат транзакции. MySQL не разрешает сам оператор ROLLBACK в процедурах и триггерах.

Если вы не хотите откатывать транзакцию (INSERT / UPDATE должна проходить даже при неудачном «проверочном ограничении», вы можете перезаписать значение, используя SET NEW.ID = NULL, которое установит id в значение по умолчанию для полей, не действительно имеет смысл для id tho

Edit: Убрал блуждающую цитату.

Относительно оператора :=:

В отличие от =, оператор := никогда не интерпретируется как оператор сравнения. Это означает, что вы можете использовать := в любом допустимом операторе SQL (не только в инструкциях SET), чтобы присвоить значение переменной.

https://dev.mysql.com/doc/refman/5.6/en/assignment-operators.html

Относительно кавычек идентификатора обратного удара:

Символом кавычки идентификатора является обратный тик («` »)

Если включен режим SQL ANSI_QUOTES, также допустимо заключать идентификаторы в двойные кавычки

http://dev.mysql.com/doc/refman/5.6/en/identifiers.html

50 голосов
/ 10 января 2013

CHECK ограничения игнорируются MySQL, как объяснено в небольшом комментарии в документации: CREATE TABLE

Предложение CHECK анализируется, но игнорируется всеми механизмами хранения.

15 голосов
/ 22 января 2010

Ограничение CHECK не реализовано в MySQL.

См. Этот отчет об ошибке: https://bugs.mysql.com/bug.php?id=3464

8 голосов
/ 02 июня 2017

Как уже упоминалось, joanq MariaDB теперь поддерживает ограничения CHECK среди других полезностей:

"Поддержка CHECK CONSTRAINT ( MDEV-7563 )."

https://mariadb.com/kb/en/mariadb/mariadb-1021-release-notes/

1 голос
/ 04 февраля 2019

Обновление до MySQL 8.0.16 для использования checks:

Начиная с MySQL 8.0.16, CREATE TABLE разрешает основные функции таблицы ограничения столбца CHECK для всех механизмов хранения. СОЗДАТЬ СТОЛ разрешает следующий синтаксис CHECK для обеих таблиц ограничения и ограничения столбцов

Документация по проверке MySQL

1 голос
/ 30 января 2019

Проверка ограничений поддерживается начиная с версии 8.0.15 (еще не выпущена)

https://bugs.mysql.com/bug.php?id=3464

[23 января 16:24] Пол Дюбуа

Опубликовано разработчиком: Исправлено в 8.0.15.

Ранее MySQL разрешал ограниченную форму синтаксиса ограничения CHECK, но разобрал и проигнорировал это. MySQL теперь реализует основные функции ограничения CHECK для таблицы и столбца для всех механизмов хранения. Ограничения определяются с помощью операторов CREATE TABLE и ALTER TABLE.

0 голосов
/ 29 января 2012

попробуй с set sql_mode = 'STRICT_TRANS_TABLES' ИЛИ SET sql_mode='STRICT_ALL_TABLES'

...