まず、次のようなテーブルを作成しました
CREATE TABLE Customer (
SD integer CHECK (SD > 0),
Last_Name varchar (30),
First_Name varchar(30)
);
そして、そのテーブルに値を挿入しました
INSERT INTO Customer values ('-2','abc','zz');
MySQLはエラーを表示せず、値を受け入れました。
まず、次のようなテーブルを作成しました
CREATE TABLE Customer (
SD integer CHECK (SD > 0),
Last_Name varchar (30),
First_Name varchar(30)
);
そして、そのテーブルに値を挿入しました
INSERT INTO Customer values ('-2','abc','zz');
MySQLはエラーを表示せず、値を受け入れました。
回答:
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 ;
お役に立てば幸いです。
CHECK
定義された制約に遭遇した場合に警告をスローするのは、MySQLでの開発が10分か15分かと思います。ああ、それはあまりにも簡単です...
残念ながら、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
編集: 抜けた引用を削除しました。
:=
オペレーターに関して:
とは異なり
=
、:=
演算子は比較演算子として解釈されません。つまり:=
、(SETステートメントだけでなく)有効なSQLステートメントで変数に値を割り当てることができます。
https://dev.mysql.com/doc/refman/5.6/en/assignment-operators.html
バックティック識別子の引用について:
識別子の引用文字はバックティック(「 `」)です
ANSI_QUOTES SQLモードが有効になっている場合は、二重引用符で識別子を引用することもできます。
DELIMITER
ですか?
CHECK
ドキュメントのごくわずかなコメントで説明されているように、MySQLでは制約は無視されます。 CREATE TABLE
CHECK
句は、すべてのストレージエンジンによって解析されますが、無視されます。
CHECK
制約が適切に実装された他のDBMS では、がCHECK
評価されたFALSE
場合、挿入(または更新)は行われず、エラーが発生します。
CHECK
制約は、MySQLで実装されていないようです。
このバグレポートを参照してください:https : //bugs.mysql.com/bug.php?id=3464
joanq MariaDBによって言及されているように、他の利点の中でも特にCHECK制約をサポートするようです:
https://mariadb.com/kb/en/mariadb/mariadb-1021-release-notes/
チェック制約はバージョン8.0.15でサポートされています(まだリリースされていません)。
https://bugs.mysql.com/bug.php?id=3464
[1月23日16:24]ポールデュボア
開発者による投稿:8.0.15で修正されました。
以前は、MySQLは限定された形式のCHECK制約構文を許可していましたが、構文解析して無視していました。MySQLは現在、すべてのストレージエンジンに対して、テーブルと列のCHECK制約のコア機能を実装しています。制約は、CREATE TABLEおよびALTER TABLEステートメントを使用して定義されます。
MySQL 8.0.16にアップデートして使用しますchecks
。
MySQL 8.0.16以降、CREATE TABLEはすべてのストレージエンジンに対して、テーブルとカラムのCHECK制約のコア機能を許可します。CREATE TABLEは、テーブル制約と列制約の両方に対して、次のCHECK制約構文を許可します
set sql_mode = 'STRICT_TRANS_TABLES'
ORで試すSET sql_mode='STRICT_ALL_TABLES'
CHECK
制約を満たさないデータの入力を防止しない