2014-04-02 56 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;