我是新編寫SQL Server觸發器。我有一張名爲USERS
的表格,我也有另一張名爲USERS_DELTA
的表格。兩者之間的差異是USERS_DELTA
有一個額外的列名爲change_type
。插入觸發器導致問題
下面是表模式:
USERS
表:
CREATE TABLE [dbo].[TDR_Users]
(
[objectGUID] [varbinary](50) NOT NULL,
[distinguishedName] [nvarchar](255) NOT NULL,
[adForest] [nvarchar](50) NULL,
[adDomain] [nvarchar](50) NULL,
[accountExpires] [datetime] NULL,
[adminCount] [int] NULL,
[cn] [nvarchar](64) NULL,
[company] [nvarchar](64) NULL,
[description] [nvarchar](448) NULL,
[displayName] [nvarchar](256) NULL,
[division] [nvarchar](256) NULL,
[employeeID] [nvarchar](16) NULL
)
而且USERS_DELTA
表:
CREATE TABLE [dbo].[TDR_Users]
(
[objectGUID] [varbinary](50) NOT NULL,
[distinguishedName] [nvarchar](255) NOT NULL,
[adForest] [nvarchar](50) NULL,
[adDomain] [nvarchar](50) NULL,
[accountExpires] [datetime] NULL,
[adminCount] [int] NULL,
[cn] [nvarchar](64) NULL,
[company] [nvarchar](64) NULL,
[description] [nvarchar](448) NULL,
[displayName] [nvarchar](256) NULL,
[division] [nvarchar](256) NULL,
[employeeID] [nvarchar](16) NULL,
[change_Type] [nvarchar](10) NULL
)
我將在USERS
表中創建記錄的應用程序。但我想要做的是將插入到USERS_DELTA
。我已經寫了扳機上USERS
表:
CREATE TRIGGER [dbo].[TR_INSERTS_DELTAS]
ON [dbo].[Users]
FOR INSERT
AS
DECLARE @ObjectGUID varbinary(50), @DN varchar(255), @memcount int;
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Get the primary and unique keys from the inserted rows.
SELECT @DN=i.distinguishedName FROM inserted i;
SELECT @ObjectGUID = i.objectGUID FROM inserted i;
-- Check if a row already exists in the TDR_Users_Delta table with those values.
SELECT @memcount=COUNT(*) FROM Users
WHERE Users.distinguishedName = @DN
AND Users.objectGUID = @ObjectGUID ;
if(@memcount = 0)
BEGIN
INSERT INTO [dbo].[Users_Delta]
(
[objectGUID],
[distinguishedName],
[adForest],
[adDomain],
[accountExpires],
[adminCount],
[cn] ,
[company],
[description],
[displayName],
[division],
[employeeID],
[change_type]
)
VALUES
(
INSERTED.[objectGUID],
INSERTED.[distinguishedName],
INSERTED.[adForest],
INSERTED.[adDomain],
INSERTED.[accountExpires],
INSERTED.[adminCount],
INSERTED.[cn] ,
INSERTED.[company],
INSERTED.[description],
INSERTED.[displayName],
INSERTED.[division],
INSERTED.[employeeID],
'Add'
);
END
END
GO
當我執行這個觸發,我得到以下錯誤:
Msg 4104, Level 16, State 1, Procedure TR_INSERTS_DELTAS, Line 94
The multi-part identifier "Inserted.objectGUID" could not be bound.Msg 4104, Level 16, State 1, Procedure TR_INSERTS_DELTAS, Line 95
The multi-part identifier "INSERTED.distinguishedName" could not be bound.Msg 4104, Level 16, State 1, Procedure TR_INSERTS_DELTAS, Line 96
The multi-part identifier "INSERTED.adForest" could not be bound.Msg 4104, Level 16, State 1, Procedure TR_INSERTS_DELTAS, Line 97
The multi-part identifier "INSERTED.adDomain" could not be bound.Msg 4104, Level 16, State 1, Procedure TR_INSERTS_DELTAS, Line 98
...
我在做什麼錯? :(
請忽略表中的架構名稱。我知道它說TDR_USERS 。我已經糾正它在我的結束,但錯誤仍然存在。在觸發器的代碼中想想它的東西。 – user5078178
你的觸發器有** MAJOR **缺陷,你似乎認爲它會被稱爲**每次如果你的INSERT語句影響了25行,你將觸發一次觸發** ** **,這樣**就不會觸發**,但是然後'Inserted'將會包含25行,這25行中的哪一行會在這裏選擇?'SELECT @ DN = i.distinguish edName FROM插入我;' - 它是非確定性的 - 你會得到一行並忽略所有其他24個!你需要重寫你的觸發器來考慮這個問題! –
以另一種方式採取marc_s評論。將歷史表視爲不是增量表。所以總是在每次更改時插入一行。這意味着歷史表將需要一個不同的主鍵,例如員工ID和更改日期GetDate()。在歷史表概念中,您永遠不需要事先知道主鍵。我所有的最好和最長持久最高音量最穩定的數據庫項目中都有零觸發器 –