我正在我的数据库中使用某个范围的许多字段,例如:
CREATE TABLE figures (
deg FLOAT,-- between 0 and pi
prc FLOAT,-- between 0 and 1
.......
);
CREATE TRIGGER filter1 BEFORE UPDATE ON figures FOR EACH ROW SET
NEW.deg=IF(NEW.deg>3.1415926 OR NEW.deg<0, OLD.deg,NEW.deg),
NEW.prc=IF(NEW.prc>1 OR NEW.prc<0, OLD.prc,NEW.prc),
..........;
CREATE TRIGGER filter2 BEFORE INSERT ON figures FOR EACH ROW SET
NEW.deg=IF(NEW.deg>3.1415926 OR NEW.deg<0, NULL,NEW.deg),
NEW.prc=IF(NEW.prc>1 OR NEW.prc<0, NULL,NEW.prc),
.........;
有没有办法更清楚地写出来? 类似的东西:
--CREATE PROCEDURE/FUNCTION between()..................
CREATE TABLE figures (
deg FLOAT between(0,3.1415),
prc FLOAT between(0,1),
.......
至少,我不想两次写每个过滤器。 (ON INSERT,ON UPDATE)
答案 0 :(得分:2)
目前,触发器是最佳解决方案。
Re:检查约束......
'CHECK子句被解析但被所有存储引擎忽略。'。*。
'接受但忽略语法子句的原因是兼容性,以便更容易从其他SQL服务器移植代码,以及运行创建带引用的表的应用程序。 “
直接取消:http://dev.mysql.com/doc/refman/5.1/en/alter-table.html
答案 1 :(得分:1)
至少,我不想两次写每个过滤器。 (ON INSERT,ON UPDATE)
您可以编写存储的函数并在触发器中调用它。
DELIMITER $$
CREATE FUNCTION check_deg (degree FLOAT, olddegree FLOAT) RETURNS FLOAT
BEGIN
DECLARE result FLOAT;
result = IF(degree>3.1415926 OR degree <0, olddegree,degree);
RETURN result;
END$$
DELIMITER ;
这样你就有了一个定义限制的点,如果有任何变化,你只需要在一个地方改变边界。
答案 2 :(得分:1)
最好的解决方案是使用CHECK()约束,但MySQL不支持CHECK()约束。 (MySQL解析它们,然后忽略它们。)
在某些情况下,您可以使用包含所有有效值的表的外键引用替换CHECK()约束。不过,浮点数不是这种解决方案的理想候选者。
留下触发器。在您的情况下,最好的办法是使用调用存储函数的触发器。
答案 3 :(得分:0)
我有一个未完成的想法:
CREATE PROCEDURE check_constraint (table VARCHAR,field VARCHAR,condition VARCHAR)
BEGIN
SET @update_trigger = CONCAT ("
IF EXIST TRIGGER check_constraint_",table,"_",field,"
BEGIN /*I don't know yet what to do*/ END
ELSE /*IF TRIGGER DONT EXIST*/
BEGIN
CREATE TRIGGER check_constraint_",table,"_",field,"
BEFORE UPDATE ON ",table," FOR EACH ROW SET
NEW.",field,"=IF("condition, ", OLD.",field,",NEW.",field,");
END
");
PREPARE update_trigger FROM @update_trigger;
EXECUTE update_trigger;
DEALLOCATE PREPARE update_trigger;
SET @insert_trigger = ..............................
END
在我们有一个完成的函数之后,我们可以在创建数据库期间调用它:
CALL check_constraint("table","field","NEW.field<34567");