2012-02-21 8 views
2

私はこれに対するいくつかの答えをネットで検索してきました。しかし私が得るのは単純な答えです。 SQL制約チェックまたはトリガー?

は、私が彼らの最大値に制約を持つべきであるが、別の列は、例えば偽

に設定されていない場合は、私のデータベース内にいくつかの列を持っています。私は、したがって、それが値を制限する、しかし、その行の値がFALSEに設定され、行2はValueAが最初に5000で外部のプログラムによって提供されるこのテーブルでテーブル

ROW ValueA   TRUE/FALSE  ValueB 
0  3750   TRUE    0 
1  5000   TRUE    0 
2  5000   FALSE    0 [INITIAL VALUES PROVIDED] 
2  3750   FALSE    1250 [ACTUAL VALUES ACCEPTED] 

に以下の値を有しますValueBに1250を追加します。

これをtrueに設定すると、チェックをバイパスできます。 しかし、その行に対してfalseに設定されていて、値が3750より大きい場合、ValueAを3750に戻して残りをValueBに入れます。

これはConstraint Check式で可能ですか、これに対してBefore Updateトリガを使用する方が賢明でしょうか?

答えて

1

を別の列の値を設定することはできませんので、あなたが、私は2つのテーブル持ってお勧めこのためのトリガーを必要とする:生を保持するステージング表を外部プログラムからのデータと、ビジネスルールが適用された第2のテーブルとを含む。この第2のテーブルは、単純に例えばVIEWとすることができる。 (私はCTEを使用してサンプルデータでステージングテーブルをシミュレートしていますが、SQL Serverは真のブール型ではないため、CHAR(1)列を使用してシミュレーションしています。 some_flagにそれを変更):!

WITH Staging 
    AS 
    (
     SELECT * 
     FROM (
       VALUES (0, 3750, 'T'), 
        (1, 5000, 'T'), 
        (2, 5000, 'F') 
      ) AS T (ROW, ValueA, some_flag) 
    ) 
SELECT ROW, ValueA, some_flag, 
     0 AS ValueB 
    FROM Staging 
WHERE (ValueA <= 3750 OR some_flag = 'T') 
UNION 
SELECT ROW, 3750 AS ValueA, some_flag, 
     (ValueA - 3750) AS ValueB 
    FROM Staging 
WHERE ValueA > 3750 AND some_flag = 'F'; 

2番目のテーブルには、ベーステーブルになりたい場合は、伝統的なロジックを使用して、次の制約は、()を適用するように見えるでしょう:

IF some_flag = 'F' THEN ValueA <= 3750 
IF some_flag = 'T' THEN ValueB = 0 
IF some_flag = 'F' AND ValueA < 3750 THEN ValueB = 0 

SQLのようにCHECK制約(私はいくつかの '常識'のビジネスルールを推測しています):

CREATE TABLE MyTable 
(
ROW INTEGER NOT NULL UNIQUE, 
ValueA INTEGER NOT NULL CHECK (ValueA > 0), 
some_flag CHAR(1) NOT NULL CHECK (some_flag IN ('T', 'F')), 
ValueB INTEGER NOT NULL CHECK (ValueB >= 0), 
CHECK (some_flag <> 'F' OR ValueA <= 3750), 
CHECK (some_flag <> 'T' OR ValueB = 0), 
CHECK (some_flag <> 'F' OR ValueA >= 3750 OR ValueB = 0) 
); 

上記のクエリを使用して、ステージングテーブルからベーステーブルにデータをコピーできます。ただし、制約に違反することはありませんが、クエリが間違っていると失敗することはありません。

+0

ありがとう、真の偽のビットのためのより良い名前を思い付くことができませんでした、それは確かにTまたはFを含むcharフィールドです。あなたの洞察力をありがとう。私は例としてこれを私の答えとしてマークします。 – Raskaroth

1

私の意見では、これは「複雑な」ビジネスロジックのように思えます。

複雑で、私はいくつかのチェック、いくつかのルールに基づいて異なる動作を意味します。

この場合、私はトリガーでチェックを行います。

+0

あなたのスイッチ応答に感謝します。私はトリガーに向かって傾いていましたが、私はそれらについて非常に否定的なことを読むように使用するのが悪いかどうかは分かりません。 – Raskaroth

+0

このタイプの使用は素晴らしいです - パフォーマンスを低下させる膨大な手続き的な動作を埋め込むと、人は困ってしまいます。 – Randy

+0

ありがとう、私は答えが必要です! – Raskaroth

1

(あなたがここでやっているような)制約条件に基づいて

関連する問題