おそらく愚かな質問です!
挿入後トリガー(T-SQL)からストアドプロシージャを呼び出す場合、「挿入されたばかりの」データの値を取得するにはどうすればよいですか?例えば.
CREATE TRIGGER dbo.MyTrigger
ON dbo.MyTable
AFTER INSERT
AS
BEGIN
EXEC createAuditSproc 'I NEED VALUES HERE!'
心配するID列はありません。「挿入したばかりの」値のいくつかを使用してsprocに渡したいだけです。
編集:明確にするために-sprocは複数のことを行うため、これはsprocを呼び出し、テーブルに直接挿入しないために必要です。私は現在、物事を「適切に」行うために修正できないいくつかのレガシーテーブル(時間/リソース/レガシーコード)を使用しているので、私が持っているものを使用する必要があります:(
INSERTED and DELETED pseudo-tablesを使用して、新しく「変更された」データにアクセスします。
CREATE TRIGGER dbo.MyTrigger
ON dbo.MyTable
AFTER INSERT
AS
BEGIN
INSERT INTO myTableAudit(ID, Name)
SELECT i.ID, i.Name
FROM inserted i;
END
与えられたサンプルテーブル
create table myTable
(
ID INT identity(1,1),
Name varchar(10)
)
GO
create table myTableAudit
(
ID INT,
Name varchar(10),
TimeChanged datetime default CURRENT_TIMESTAMP
)
GO
Edit:申し訳ありませんが、ストアドプロシージャの呼び出しについては少し触れませんでした。 marc_sのコメントによると、挿入/削除には複数の行が含まれる可能性があるため、SPROCの問題が複雑になることに注意してください。個人的には、SPROCをカプセル化せずに、トリガーを監査テーブルに直接挿入したままにします。ただし、SQL 2008を使用している場合は、次のようにテーブル値パラメーターを使用できます。
CREATE TYPE MyTableType AS TABLE
(
ID INT,
Name varchar(10)
);
GO
CREATE PROC dbo.MyAuditProc @MyTableTypeTVP MyTableType READONLY
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO myTableAudit(ID, Name)
SELECT mtt.ID, mtt.Name
FROM @MyTableTypeTVP mtt;
END
GO
そして、トリガーは次のように変更されます。
ALTER TRIGGER dbo.MyTrigger
ON dbo.MyTable
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;
DECLARE @MyTableTypeTVP AS MyTableType;
INSERT INTO @MyTableTypeTVP(ID, Name)
SELECT i.ID, i.Name
FROM inserted i;
EXEC dbo.MyAuditProc @MyTableTypeTVP;
END
次に、これが単一の挿入と複数の挿入の両方で機能することをテストできます。
insert into dbo.MyTable values ('single');
insert into dbo.MyTable
select 'double'
union
select 'insert';
ただし、SQL 2005以下を使用している場合は、カーソルを使用して、挿入された受け渡し行をSPROCにループする必要があります。これは、考えられないほど恐ろしいことです。
ちなみに、SQL 2008を使用している場合は、 データキャプチャの変更 を参照してください。
編集#2:procを呼び出す必要があるため、1行しか挿入しないことが確実な場合...
ALTER TRIGGER dbo.MyTrigger
ON dbo.MyTable
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;
DECLARE @SomeInt INT;
DECLARE @SomeName VARCHAR(10);
SELECT TOP 1 @SomeInt = i.ID, @SomeName = i.Name
FROM INSERTED i;
EXEC dbo.MyAuditProc @SomeInt, @SomeName;
END;