2011-01-26 13 views
18

私はbit IsDefaultの列を持っています。テーブル内の1行のデータだけが1に設定されたこのビット列を有することができ、他のすべては0でなければならない。SQL Serverのビット列制約、1行= 1、他すべて0

これを強制するにはどうすればよいですか?

+6

代替アーキテクチャを検討しましたか? 「デフォルト」の行を指し示す参照を他の場所に持つとします。 –

+1

SQL Serverのバージョンを教えてください。 – gbn

+0

どのような大きな質問です!私は他の+99点の評価を表現するためにこれを書いているだけです。 –

答えて

30

すべてのバージョン:

  • トリガー
  • インデックス付きビュー
  • ストアドプロシージャ(書き込み上の例えばテスト)

のSQL Server 2008:a filtered index

CREATE UNIQUE INDEX IX_foo ON bar (MyBitCol) WHERE MyBitCol = 1 
+0

さて、それは確かに彼らがデフォルトで複数のレコードを保存しないようにするでしょう。 – NotMe

+1

フィルタリングされたインデックスは、ANSIパディングをオンにする必要があります。フィルタリングされたインデックスを作成する前に 'SET ANSI PADDING ON'を実行してください。 – naXa

1

あなたは可能性があり代わりにトリガーを挿入し、それがに来るよう値を確認してください。

Create Trigger TRG_MyTrigger 
on MyTable 
Instead of Insert 
as 
Begin 

    --Check to see if the row is marked as active.... 
    If Exists(Select * from inserted where IsDefault= 1) 
    Begin 
    Update Table Set IsDefault=0 where ID= (select ID from inserted); 

    insert into Table(Columns) 
    select Columns from inserted 
    End 

End 

また、列に一意制約を適用することができます。あなたのPKを想定し

16

は、単一の、数値列である、あなたは、あなたのテーブルに計算列を追加することができます。

ALTER TABLE YourTable 
    ADD IsDefaultCheck AS CASE IsDefault 
    WHEN 1 THEN -1 
    WHEN 0 THEN YourPK 
    END 

を次に計算列に一意のインデックスを作成します。

私があれば、すなわち(あなたが挿入/新しいものを更新するとき、あなたは一つのレコードは、常にその値を持っていることを確認したい場合は0に、古いデフォルトのレコードを変更したい場合は、トリガは最高のアイデアだと思います
CREATE UNIQUE INDEX IX_DefaultCheck ON YourTable(IsDefaultCheck) 
+0

+1これは決して考えなかった。フィルタリングされたインデックスを持たないDRIソリューション – gbn

+0

+1素晴らしいソリューション。 –

+0

これはトリガーを必要としないので、私の意見ではこれが最良の解決策です。実際、このソリューションで提供されるすべてのものは、元のテーブル定義でインラインで実装される可能性があります。 – Tripartio

2

別のレコードに割り当てる値でレコードを削除します)。そうするためのルールを決める必要があります。これらのトリガーは、挿入されたテーブルと削除されたテーブルの複数のレコードを考慮する必要があるため、扱いにくいことがあります。したがって、バッチ内の3つのレコードがデフォルトのレコードになるように更新しようとすると、どちらが勝ちますか?

誰かがそれを変更しようとしたときに、1つのデフォルトレコードが変更されないようにしたい場合は、フィルタリングされたインデックスが良い考えです。

1

以下の質問への受け入れ答えは面白いと関連の両方である:

Constraint for only one record marked as default

「しかし、単に別のテーブルにする必要があります深刻な関係の人々はあなたにこの情報 を教えてくれます。」

「デフォルト」のレコードを示す別の1行テーブルがあります。 Anonはこれについて彼のコメントで触れた。

シンプルでクリーンな&は、これが最善のアプローチだと思います。エラーや誤解を招くような「巧妙な」難解な解決策は必要ありません。 IsDefualt列を削除することもできます。

関連する問題