2017-06-02 72 views
0

我需要在我的SQLite3數據庫中進行檢查,以確保用戶無法輸入重疊間隔的數據。在SQLite3中輸入數據時如何檢查重疊間隔?

例如:

hole # Sample From To 
1   1  1  2    
1   2  2  3    
1   3 2.2 2.9  

利用上述我有代替檢查,將捕獲任何重複的「從」中的每個孔的例子,但樣品#3不是重複,所以它不會被捕獲,但它是一個重疊區間。

我不希望這個查詢,而是作爲內置到表中的數據輸入檢查。

到目前爲止,我已經嘗試添加('From' NOT BETWEEN 'From' and 'To)的約束檢查,但無濟於事。我不明白這個檢查是試圖在一行一行的基礎上應用,或者是基於主鍵。

這裏是我想表定義:

CREATE TABLE assay (
    BHID  TEXT NOT NULL 
         CONSTRAINT [Check BHID] REFERENCES collar (BHID) ON DELETE CASCADE 
                     ON UPDATE CASCADE 
                     MATCH SIMPLE, 
    [Sample #] TEXT UNIQUE, 
    [FROM]  NUMERIC NOT NULL 
         CONSTRAINT [Interval Check] CHECK (("TO" > "FROM")), 
    [TO]  NUMERIC NOT NULL, 
    Ag   NUMERIC CONSTRAINT [Max Silver] CHECK ((Ag < 1000)), 
    Zn   NUMERIC CONSTRAINT [Max Zinc] CHECK ((Zn < 50)), 
    Pb   NUMERIC CONSTRAINT [Max Lead] CHECK ((Pb < 50)), 
    Fe   NUMERIC, 
    PRIMARY KEY (
     BHID, 
     [FROM] 
    ) 
); 

這裏是用更新的約束表(commiting前):

CREATE TABLE assay (
    BHID  TEXT NOT NULL 
         CONSTRAINT [Check BHID] REFERENCES collar (BHID) ON DELETE CASCADE 
                     ON UPDATE CASCADE 
                     MATCH SIMPLE, 
    [Sample #] TEXT UNIQUE, 
    [FROM]  NUMERIC NOT NULL 
         CONSTRAINT [Interval Check] CHECK (("TO" > "FROM")) 
         CONSTRAINT [Not Between] CHECK (('From' NOT BETWEEN 'From' AND 'To')), 
    [TO]  NUMERIC NOT NULL, 
    Ag   NUMERIC CONSTRAINT [Max Silver] CHECK ((Ag < 1000)), 
    Zn   NUMERIC CONSTRAINT [Max Zinc] CHECK ((Zn < 50)), 
    Pb   NUMERIC CONSTRAINT [Max Lead] CHECK ((Pb < 50)), 
    Fe   NUMERIC, 
    PRIMARY KEY (
     BHID, 
     [FROM] 
    ) 
); 

我刪除的數據行與衝突數據(從:2.2,到:2.9),並在嘗試添加新的約束檢查之前進行更改。但它不會讓我犯下新的限制,我相信它是因爲它試圖將其應用到整個專欄。

所以我的問題應該是這樣的:有沒有辦法在sql中逐行應用約束檢查?

+0

你試過了什麼?你卡在哪裏? –

+0

我試過('從'不'從'和'到'),但它不起作用,我不知道下一步該怎麼做。 – joswhite

+0

顯示實際的表格定義以及您嘗試添加的實際約束。 –

回答

0

在SQL中,雙引號用於引用表名和列名;單引號用於字符串值。所以檢查

('FROM' NOT BETWEEN 'FROM' AND 'TO') 

只是比較這些恆定的字符串值。此檢查總是失敗。

無論如何,CHECK約束只能訪問當前行中的值。 爲了能夠查看其他行,您必須使用觸發器:

CREATE TRIGGER no_overlaps 
BEFORE INSERT ON Assay 
WHEN EXISTS (SELECT * 
      FROM Assay 
      WHERE "From" <= NEW."To" 
       AND "To" >= NEW."From") 
BEGIN 
    SELECT RAISE(FAIL, "overlapping intervals"); 
END; 
+0

感謝您提供有效的反饋和答案! – joswhite