2013-01-15 61 views
3

我正在使用SQL Server 2008,並且我有一個觸發器,我想將My_Table中的任何行復制到一個存檔History_Table表中。使用觸發器如何複製剛纔插入的行

如何在每次有人插入新行時將表的整個舊內容複製到存檔中?

我的表結構

CREATE TABLE [dbo].[Stu_Table] 
    (
    [Stu_Id] [int] NOT NULL, 
    [Stu_Name] [varchar] (15) COLLATE SQL_Latin1_General_CP1_CI_AS NULL, 
    [Stu_Class] [int] NULL 
    ) ON [PRIMARY] 
    GO 

ALTER TABLE [dbo].[Stu_Table] ADD CONSTRAINT [PK_Stu_Table] PRIMARY KEY CLUSTERED ([Stu_Id]) ON [PRIMARY] 
GO 

我的存檔表結構

CREATE TABLE [dbo].[Stu_TableHistory] 
(
[Stu_Id] [int] NOT NULL, 
[Stu_Name] [varchar] (15) COLLATE SQL_Latin1_General_CP1_CI_AS NULL, 
[Stu_Class] [int] NULL 
) ON [PRIMARY] 
GO 
ALTER TABLE [dbo].[Stu_TableHistory] ADD CONSTRAINT [PK_Stu_TableHistory] PRIMARY KEY CLUSTERED ([Stu_Id]) ON [PRIMARY] 
GO 

我的觸發語法

Create TRIGGER [dbo].[HistoryKeep] 
    ON [dbo].[Stu_Table] 
    INSTEAD OF INSERT 
AS 
BEGIN 
    IF((SELECT COUNT(*) FROM Stu_Table WHERE Stu_Id = (SELECT Stu_Id FROM INSERTED)) >= 1) 
    BEGIN 
     INSERT INTO dbo.Stu_TableHistory(Stu_Id, Stu_Name, Stu_Class) 
     SELECT Stu_Id, Stu_Name, Stu_Class FROM Stu_Table WHERE Stu_Id = (SELECT Stu_Id FROM INSERTED) 

     UPDATE x 
     SET x.Stu_Name = i.Stu_Name 
     FROM dbo.Stu_Table AS x 
     INNER JOIN inserted AS i ON i.Stu_Id = x.Stu_Id 

    END 
    ELSE 
    BEGIN 
     INSERT INTO dbo.Stu_Table(Stu_Id, Stu_Name, Stu_Class) 
     SELECT Stu_Id, Stu_Name, Stu_Class FROM INSERTED 
    END 
END 

一句話需要幫助轉移,從學生的舊數據表格歸檔表。我上面的觸發語法不能滿足我。

如有任何疑問請提前致謝。

+3

'INSERTED'是一個僞表,可以包含*多*行。你需要編寫接受現實的查詢。假設來自INSERTED的'SELECT STU_ID將返回1個結果,你的代碼就被破壞了。它可能包含行的混合 - 一些適合'UPDATE'的行,另一些適用於普通的'INSERT'。 –

+0

Damien_The_Unbeliever感謝您的回覆,不明白您的評論說明,您是否會喜歡分享一些語法與詳細說明。謝謝 – shamim

+0

檢查此問題http://stackoverflow.com/questions/3336319/using-inserted-and-deleted-觸發器中的表 – Geethanga

回答

3

而非目前的觸發的,你應該是這樣的:

Create TRIGGER [dbo].[HistoryKeep] 
    ON [dbo].[Stu_Table] 
    INSTEAD OF INSERT 
AS 
BEGIN 
DECLARE @History table (
    Action sysname not null, 
    STU_ID [int] NULL, 
    [Stu_Name] [varchar] (15) COLLATE SQL_Latin1_General_CP1_CI_AS NULL, 
    [Stu_Class] [int] NULL 
) 

;MERGE INTO Stu_Table t 
USING INSERTED i ON t.STU_ID = i.STU_ID 
WHEN MATCHED THEN UPDATE SET STU_Name = i.STU_Name 
WHEN NOT MATCHED THEN INSERT (STU_ID,STU_NAME,STU_CLASS) VALUES (i.STU_ID,i.STU_NAME,i.STU_CLASS) 
OUTPUT $Action,deleted.stu_id,deleted.stu_name,deleted.stu_class INTO @History; 

INSERT INTO stu_TableHistory (stu_id,stu_name,stu_class) 
select stu_id,stu_name,stu_class from @History where Action='UPDATE' 
END 

另請注意,你將需要刪除您當前的PK約束上STU_TableHistory,因爲一旦一個行更多,更新的比一次,會有兩個條目包含相同的STU_ID


按我的意見,這把INSERTED貫穿包含多個行的表。所以,如果Stu_Table包含一排STU_ID 1,以下插入:

INSERT INTO STU_Table (STU_ID,STU_Name,STU_Class) VALUES 
(1,'abc',null), 
(2,'def',null) 

更新的行STU_ID 1,插入STU_ID 2行,並插入一個一行到stu_tableHistory(用於STU_ID 1)

+0

感謝您的回覆 – shamim

相關問題