2

私はこのトリガーを持っています:

CREATE trigger [dbo].[DeriveTheAge] on [dbo].[Student]
after insert,update
as
begin
    declare @sid as int;
    declare @sdate as date;
    select @sid= [Student ID] from inserted;
    select @sdate=[Date of Birth] from inserted;
    commit TRANSACTION
    if(@sdate is not null)
    begin
        update Student set Age=DATEDIFF(YEAR,@sdate,GETDATE()) where [Student ID]=@sid;
    end
    print 'Successfully Done'
end

おっしゃる通り、トリガーは生年月日から派生属性「年齢」を自動計算します。しかし、挿入を行うと次のエラーが発生します。

(1 row(s) affected)
Successfully Done
Msg 3609, Level 16, State 1, Line 1
The transaction ended in the trigger. The batch has been aborted.

エラーにもかかわらず行が更新されていたため、最初はこのエラーを回避しました。しかし、FORNT END からレコードを挿入すると、レコードが更新されません。代わりに、次の例外をスローします。ここに画像の説明を入力

誰でも私を助けてもらえますか?

ところで、私のは SQL Server 2008 R2 と Visual Studio 2010 です。

訂正: レコードはまだ更新中です。しかし、例外はヴィランです。

アップデート

CREATE TRIGGER [dbo].[DeriveTheAge] 
ON [dbo].[Student]
FOR INSERT, UPDATE
AS
BEGIN
    UPDATE s 
      SET Age = DATEDIFF(YEAR, [Date of Birth], CURRENT_TIMESTAMP)
      FROM dbo.Student AS s
      INNER JOIN inserted AS i
      ON s.[Student ID] = i.[Student ID]
      WHERE i.[Date of Birth] IS NOT NULL;
      commit transaction
END
GO
4

1 に答える 1

8

なぜトリガーでコミットしているのですか?複数行の挿入または更新を処理しないのはなぜですか? 変数を宣言して、挿入されたものから代入するだけではいけません。2 行、15 行、または 6000 行を更新すると、どの値が割り当てられると思いますか?

CREATE TRIGGER [dbo].[DeriveTheAge] 
ON [dbo].[Student]
FOR INSERT, UPDATE
AS
BEGIN
    UPDATE s 
      SET Age = DATEDIFF(YEAR, [Date of Birth], CURRENT_TIMESTAMP)
      FROM dbo.Student AS s
      INNER JOIN inserted AS i
      ON s.[Student ID] = i.[Student ID]
      WHERE i.[Date of Birth] IS NOT NULL;
END
GO

とはいえ、いったいなぜ誰かの年齢を計算するためにトリガーが必要になるのでしょうか? これは、クエリ時に生年月日から取得でき、テーブルに保存したこの古い値とは異なり、正確であることがわかります。行が 1 年以上更新されていない場合は、テーブルに入力した年齢が古くなっていることに注意してください。テーブル内のすべての行の Age を更新するのはいつですか? 一日一回?それ以下の場合、年齢列はまったく信頼できず、無意味です。

また、DATEDIFF(YEARそもそも年齢を計算する信頼できる方法ではありません。超えた年の数を数えるだけで、その人の実際の誕生日が 1 月 1 日なのか 12 月 31 日なのか、あるいはその中間なのかはわかりません。

最後に、トリガーからは印刷しません。あなたがデバッグしていないとき、誰がその print ステートメントを消費するのでしょうか?

于 2011-09-05T17:14:05.247 に答える