1

制約ではできないと思う方法でテーブルの整合性を強制しようとしています...

CREATE TABLE myData
(
   id             INTEGER IDENTITY(1,1) NOT NULL,
   fk_item_id     INTEGER               NOT NULL,
   valid_from     DATETIME              NOT NULL,
   invlaid_from   DATETIME              NOT NULL
)

私が適用したい制約は、日付が重複する同じ「fk_item_id」のエントリがあってはならないということです。

ノート:

invalid_from は、有効期間の直後の瞬間です。
これは、次の 2 つの期間が問題ないことを意味します...

  • '2008 Jan 01 00:00' -> '2008 Feb 01 00:00' (1 月全体)
  • '2008 Feb 01 00:00' -> '2008 Mar 01 00:00' (2月全体)

トリガーでそのルールを確認できます。ただし、トリガーが不正な挿入/更新を検出した場合、「不正な」挿入/更新が発生しないようにする最善の方法は何ですか?

(挿入されたレコードが 2 つの有効なレコードと 2 つの無効なレコードを含む場合、2 つの無効なレコードだけを停止できますか?)

乾杯、
民主党。

編集:

上記の場合、関数を使用した制約がうまく機能しました。しかし、トリガー バージョンで RAISERROR が機能しなかった理由がわかりませんでした。

トリガーがAFTERトリガーであり、BEFOREトリガーが必要なためだと思いましたが、それはオプションではないようです...

4

4 に答える 4

3

挿入されたものから直接削除することはできません(論理テーブルを更新するとエラーが発生します)が、以下に示すようにソーステーブルに結合し直すことはできます。

create table triggertest (id int null, val varchar(20))
Go
create trigger after  on [dbo].triggertest
for Update  
as
Begin

    delete tt from triggertest tt inner join 
    inserted i on tt.id = i.id 
    where i.id = 9

End
GO
insert into triggertest values (1,'x')
insert into triggertest values (2,'y')
Update triggertest set id = 9 where id = 2
select * from triggertest
1, x

また、トリガールートを使用する必要はありません。また、チェック制約を関数の戻り値にバインドすることもできます。

Alter table myData WITH NOCHECK add 
Constraint  CHK_VALID CHECK (dbo.fx_CheckValid(id, valid_from , invalid_from) = 1 );
于 2009-01-09T15:07:42.113 に答える
3

挿入されたテーブルからレコードを削除しないでください...それはサイレントエラーです。地獄への道は部分コミットで舗装されています。

RAISERRORが必要です。これは、本質的に制約が行うことです。

于 2009-01-09T15:19:38.763 に答える
0

エラーを発生させます。

于 2009-01-09T15:08:15.357 に答える
0

トリガーによって、「違法な」レコードのvalid_fromおよび/またはが特別な値に変更される可能性があります。invlaid_from DATETIME後続のクリーンアップ手順で、「違法な」レコードを特定できます。

于 2009-01-09T15:09:18.833 に答える