设置列的范围

时间:2011-10-10 08:00:59

标签: mysql sql

我正在我的数据库中使用某个范围的许多字段,例如:

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)

4 个答案:

答案 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");