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

一言で言えば、学生のテーブルからアーカイブのテーブルに古いデータを転送するための助けが必要です。上記のトリガー構文では満足できません。

質問がある場合は、事前に感謝を聞いてください。

4

1 に答える 1

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行が複数回更新されるとすぐに、同じを含む2つのエントリが存在するためSTU_IDです。


私のコメントによると、これはINSERTED全体に複数の行を含むテーブルとして扱われます。したがって、 1Stu_Tableの行が含まれている場合はSTU_ID、次のように挿入します。

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

1の行を更新、 2の行を挿入し、 (1の)に1つの行を挿入しますSTU_IDSTU_IDstu_tableHistorySTU_ID

于 2013-01-15T09:11:53.183 に答える