多くの人が誤解していることを覚えておくべき重要なポイントの 1 つは、SQL Server のトリガーは、行ごとではなく、ステートメントごとに 1 回呼び出されることです。
したがって、一度に 50 行を挿入または更新するINSERT
orUPDATE
ステートメントがある場合、トリガーは一度呼び出され、疑似テーブル (Inserted
およびDeleted
UPDATE の場合) には 50 行が含まれます。トリガーを作成するときは、それを考慮する必要があります。
INSERT の場合はより単純です。つまり、次のようになります。
-- CREATE after INSERT trigger
CREATE TRIGGER trgCustomerInsert
ON dbo.Customer AFTER INSERT
AS
-- update your "Customer" table
UPDATE dbo.Customer
SET SomeDateColumn = GETDATE() -- set date column to GETDATE()
FROM dbo.Customer c
INNER JOIN Inserted i ON c.cust_no = i.cust_no -- on all those rows inserted
WHERE c.Email IS NOT NULL -- where the e-mail address is NOT NULL
基本的に、Inserted
疑似テーブル (挿入されたすべての行とそのすべての列値を含む) を「実際の」顧客テーブルに対して結合し、挿入されたばかりのすべての顧客行を更新します。ここで、電子メール列はありません。ヌル。
更新は少し複雑です。なぜなら、e-mail 列が以前は NULL で、更新後は現在は NOT NULL である行だけを更新したいからです。Deleted
そのため、(UPDATE の前に) 「古い」値を含む疑似テーブルに参加する必要があります。
更新され、電子メールの古い値Deleted
が NULL で、Customer テーブルの現在の値が NOT NULL であるすべての行 - これらは、日付列を更新する行です。
-- CREATE after UPDATE trigger
CREATE TRIGGER trgCustomerUpdate
ON dbo.Customer AFTER UPDATE
AS
-- update your "Customer" table
UPDATE dbo.Customer
SET SomeDateColumn = GETDATE() -- set date column to GETDATE()
FROM dbo.Customer c
INNER JOIN Deleted d ON c.cust_no = d.cust_no
WHERE
-- where new value of e-mail is NOT NULL
-- and the old value (in "Deleted") was in fact NULL
c.Email IS NOT NULL AND d.EMail IS NULL