2014-04-02 53 views
0

我正在开发一个使用MySQL数据库存储数据的程序。我有一张桌子(在这里简化):在MySQL中限制字段值?

+---------+------------------+------+-----+---------+----------------+ 
| Field | Type    | Null | Key | Default | Extra   | 
+---------+------------------+------+-----+---------+----------------+ 
| dataId | int(10) unsigned | NO | PRI | NULL | auto_increment | 
| someNum | tinyint(4)  | NO |  | 0  |    | 
+---------+------------------+------+-----+---------+----------------+ 

现在,我用这样的查询更新表。

UPDATE table SET someNum=someNum+2 WHERE dataId=78225; 

该ID和数量someNum更改动态从代码。

现在,我想要做的是将someNum的值限制在-3和3之间,特别是在那个UPDATE中。这不是必需的,我的软件可以处理它在这个范围之外,但是数据会随着这个限制更清晰。如果someNum+2将超过3,我只是想将其设置为3

数字MIN/MAX将使它容易:

UPDATE table SET someNum=MAX(-3,MIN(3,someNum+2)) WHERE dataId=78225; 

我看了看文档here,但似乎有号码为MIN/MAXMINMAX被发现here,但他们似乎并不适合这一点。

什么是最好的方式(如果有的话)在MySQL中实现这样的限制(而不是调用MySQL的代码)?

回答

2

第一种方式:用LEAST()GREATEST()

UPDATE t SET someNum=GREATEST(-3,LEAST(3,someNum+2)) WHERE dataId=78225; 

这是最简单的方法,因为你里面存储所有的逻辑一个UPDATE查询。

方式二:创建trigger

DELIMITER // 
CREATE TRIGGER catCheck BEFORE UPDATE ON t 
    FOR EACH ROW 
    BEGIN 
     IF NEW.someNum<-3 THEN 
      NEW.someNum=-3; 
     END IF; 

     IF NEW.someNum>3 THEN 
      NEW.someNum=3; 
     END IF; 
    END;// 
DELIMITER ; 

你也可以更换IFCASE - 但我留下了两个独立的约束-33。这里的好处是 - DBMS将自行处理您的数据 - 并且您将能够传递数据,不用担心范围。但是 - 也有弱点:在第一种情况下,您可以更改查询文本以调整所需的范围,第二种情况下,如果您想要更改该约束(如此,灵活性较低),则必须再次重新创建触发器。

此外,您可能还想要检查您的数据不仅UPDATE陈述,但INSERT也。

1

使用GREATESTLEAST,而不是MAX和MIN

你也可以使用一个CASE WHEN

update table 
set someNum = CASE WHEN SomeNum +2 > 3 THEN 3 
        WHEN SomeNum +2 < -3 THEN -3 
        ELSE someNum + 2 
       END) 
1

在MySQL适当的功能是greatest()least(),不max()/min()。但是,我认为这是只是一个case声明更加清晰:

UPDATE table 
    SET someNum = (case when someNum + 2 < -3 then -3 
         when someNum + 2 > 3 then 3 
         else someNum + 2 
        end) 
    WHERE dataId=78225;