2017-07-17 15 views
1

製品の機能が指定されたsqliteテーブルがあります。特徴、例えば。色はブール値の列になります。列は「1」または「NULL」です。一部の機能は排他的です。テーブルの構造は固定されているので、例外を発生させるトリガを作成しようとしましたが、これは動作しません。私は間違って何をしていますか?Sqlite:行の値の数を制限するためのトリガー

例:

CREATE TABLE productColor(
    productId INTEGER PRIMARY KEY, 
    isRed INTEGER, 
    isBlue INTEGER, 
    isYellow INTEGER, 
    isBrown INTEGER) 

製品は、唯一の色を有することができます。私の考えは、2つ以上の色が指定されている列を数えることです。つまり、3つ以下のNULL値です。このような行が少なくとも1つ存在する場合、トリガーは例外を発生させることが予想されます。これは私のトリガーのようなものです:

CREATE TRIGGER onlyOneColor 
    BEFORE INSERT ON productColor 
    WHEN 
     (SELECT COUNT (*) FROM 
     (SELECT ((CASE WHEN isBrown IS NULL THEN 1 ELSE 0 END) + 
     (CASE WHEN isRed IS NULL THEN 1 ELSE 0 END) + 
     (CASE WHEN isBlue IS NULL THEN 1 ELSE 0 END) + 
     (CASE WHEN isYellow IS NULL THEN 1 ELSE 0 END)) 
     AS sumOfNulls FROM productColor) WHERE sumOfNulls<3) 
    >=1 
    BEGIN 
    SELECT RAISE(FAIL, 'More then one color specified'); 
    END; 
+0

チェックする行はどれですか?挿入されるもの、または他のものはどれですか? –

+0

挿入されたもので十分です。私はトリガがすべての行をチェックするように設定されていると思いますが、一度に1つの問題に取り組んでいました – Fab

答えて

0

トリガーは必要ありません。

CREATE TABLE productColor (
    productId INTEGER PRIMARY KEY, 
    isRed  INTEGER CHECK (isRed = 1 OR isRed IS NULL), 
    isBlue INTEGER CHECK (isBlue = 1 OR isBlue IS NULL), 
    isYellow INTEGER CHECK (isYellow = 1 OR isYellow IS NULL), 
    isBrown INTEGER CHECK (isBrown = 1 OR isBrown IS NULL), 
    CHECK (ifnull(isRed, 0) + ifnull(isBlue, 0) + 
      ifnull(isYellow, 0) + ifnull(isBrown, 0) <= 1) 
); 

すべての値を0または1として保存した場合、これらのチェックはより簡単になります。 (0NULLよりも、それ以上のストレージスペースを必要としません。)


をあなたが本当にトリガーが必要な場合は、WHEN句に反転の条件を置くことができます。 (挿入する行の値にはNEW.isRedなどでアクセスできます)

+0

チェック制約を適用したソリューションは素晴らしいですが、 – Fab

関連する問題