轉自http://blog.csdn.net/maxint64/article/details/8643288
今天在mysql中嘗試使用check約束時,才知道在MySQL中CHECK約束是無效的,例如下面一段代碼,在創建表table1時添加了CHECK約束,要求field1字段的值大於零,隨后向field1字段插入-1,這明顯違反CHECK約束,但這段代碼在MySQL中卻可以執行成功。
- CREATE TABLE table1
- (
- field1 INT,
- CHECK (field1 > 0)
- );
- INSERT INTO table1 VALUES (-1);
- SELECT * FROM table1;
運行結果:
- +--------+
- | field1 |
- +--------+
- | -1 |
- +--------+
- 1 row in set (0.00 sec)
解決這個問題有兩種方式。如果需要設置CHECK約束的字段值離散的,並且能很容易列舉全部可能值,就可以考慮將該字段的類型設置為枚舉類型enum()或集合類型set()。比如性別字段可以這樣設置,插入枚舉值以外值的操作將不被允許:
- (
- gender ENUM('男', '女')
- );
- INSERT INTO table1 VALUES ('秀吉');-- 此次插入操作將失敗
不過enum()類型和set()類型之間還有些小區別,官方文檔上有說明。
如果需要設置CHECK約束的字段是連續的,或者列舉全部值很困難,比如正實數或正整數,那就只能用觸發器來代替約束實現數據有效性了。下面這段代碼創建了一個叫做TestField1_BeforeInsert的約束器,它將保證新插入的數據中field1字段的值不小於零。
- DELIMITER $$
- CREATE TRIGGER TestField1_BeforeInsert BEFORE INSERT ON table1
- FOR EACH ROW
- BEGIN
- IF NEW.field1 < 0 THEN
- SET NEW.field1 = 0;
- END IF;
- END$$