2015-07-03 55 views
0

我是新編寫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
...

我在做什麼錯? :(

+0

請忽略表中的架構名稱。我知道它說TDR_USERS 。我已經糾正它在我的結束,但錯誤仍然存​​在。在觸發器的代碼中想想它的東西。 – user5078178

+1

你的觸發器有** MAJOR **缺陷,你似乎認爲它會被稱爲**每次如果你的INSERT語句影響了25行,你將觸發一次觸發** ** **,這樣**就不會觸發**,但是然後'Inserted'將會包含25行,這25行中的哪一行會在這裏選擇?'SELECT @ DN = i.distinguish edName FROM插入我;' - 它是非確定性的 - 你會得到一行並忽略所有其他24個!你需要重寫你的觸發器來考慮這個問題! –

+0

以另一種方式採取marc_s評論。將歷史表視爲不是增量表。所以總是在每次更改時插入一行。這意味着歷史表將需要一個不同的主鍵,例如員工ID和更改日期GetDate()。在歷史表概念中,您永遠不需要事先知道主鍵。我所有的最好和最長持久最高音量最穩定的數據庫項目中都有零觸發器 –

回答

1

我認爲你需要把選擇與表中,而不是使用inserted.x來表示插入。

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] 
     ) 

     select 
      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' 
From inserted 
    END 
END 
GO 
+0

您應該刪除這兩行:SELECT @ DN = i.distinguishedName FROM inserted i; SELECT @ObjectGUID = i.objectGUID FROM inserted i;'因爲他們確實沒有做任何事情,並且如果'inserted'有多行,他們將**失敗** .... –