2017-06-02 5 views
0

ユーザーが重複する間隔でデータを入力できないように、SQLite3データベースにチェックを入れる必要があります。例えばSQLite3にデータを入力する際に​​重複する間隔を確認する方法は?

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

私は各ホールでFromを重複をキャッチします代わりに小切手を持っていますが、それがキャッチされませんので、サンプル#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] 
    ) 
); 

そして、ここでは、(コミットの前に)更新された制約を持つテーブルである:

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] 
    ) 
); 

私は矛盾してデータ行を削除しましたデータ(From:2.2、To:2.9)を変更し、新しい制約チェックを追加する前に変更をコミットしました。しかし、新しい制約をコミットすることはできません。それは、それを列全体に適用しようとしているからです。

私の質問はこれでなければなりません:sqlの行ごとに制約チェックを適用する方法はありますか?

+0

何を試しましたか?どこで立ち往生しましたか? –

+0

私は( 'From'と 'To'ではなく) '試してみましたが、うまくいかず、次に何をすべきかわかりません。 – 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

関連する問題