2016-07-28 21 views
0

私は、構造体のような種類を持つテーブルを持っている:SQL Serverのチェック制約ロジック

CREATE TABLE #Mine 
(
    ProductID INT 
    , CountryID INT 
    , ApplicationID INT 
); 

は、次のようにのは、それがデータを持っていると仮定しましょう:

ProductID CountryID ApplicationID 
1   2   -1 
1   3   -1 
1   3   2 

私は、このような強制したいのですが論理が無いとProductID/CountryIDの組み合わせで全テーブルがある場合はApplicationID = -1となります。私の例では、2行目と3行目はこれを渡しません。

これを検証し、CHECKの制約を外すカスタム関数を作成することができました。おそらくそれを行うよりエレガントな方法はありますか?

+0

私は答えましたが、今、私はそれが有効だそうわかりません。 'ApplicationID'が-1である行だけが存在するようにしたいと言っていますか? – DavidG

+0

@DavidG正しいですが、-1以外の他のApplicationIDとの「ProductID」/「CountryID」の組み合わせが複数行あることがあります。 –

+0

私の編集は今これを行うと思います。 – DavidG

答えて

0

私はあなたの仕事を分割します。まず、ユニーク制約を割り当てます(これはテーブルキーになります)。

CREATE UNIQUE INDEX IX_UQ ON Mine(ProductId, CountryId, ApplicationId) 

これは簡単な検証とトリガークエリの改善です。

第2に、多くのレコードが必要です(CHECK制約はありません)。マークが何かに評価し、APPLICATIONID = -1を持つすべてのレコードがある= 0。この - 2つの以上のレコード(1> 0 COUNT(*))が存在する場合には

CREATE TRIGGER trMine 
ON Mine FOR INSERT,UPDATE 
IF (EXISTS(
     SELECT Mark FROM 
     (
      SELECT MAX(CASE WHEN M.ApplicationId=-1 THEN 1 ELSE 0 END)*(COUNT(*)-1) Mark 
      FROM Mine M 
      JOIN inserted I ON M.ProductId=I.ProductId AND M.CountryId=I.CountryId 
      GROUP BY M.ProductId,M.CountryId 
     ) Q 
     WHERE Mark != 0 
    )) THROW 50000, 'Validation error', 1 

:これは、トリガーのための作業です!あなたの違反のルールです。

+0

これはちょうど私が望んでいたようにエレガントではないようですが、仕事をしています。 –

0

あなただけのユニークなFiltered Indexを使用することができます。

CREATE UNIQUE INDEX IX_UniqueNegativeApp ON Mine(ProductID, CountryID) WHERE ApplicationID = -1