2013-10-08 41 views
1

案例行更改插入记录到另一个表与触发器,如果​​只是一列

我有以下的(我删除34并没有质疑相关的其他列)

Table1 
------ 
Id 
LastAccessed 
Data1 
Data2 

Table1_History 
------ 
_Id 
Action 
Id 
LastAccessed 
Data1 
Data2 

两个表每次用户读取记录(使用特定步骤)时,时间戳将会改变。

我附加了一个触发器到Table1如果Data1Data2(或在我的情况下任何其他列更改)复制记录到历史表;但是我不想要一个副本或记录,以防LastAccessed更改。

这里是我的触发

CREATE TRIGGER [TRIGGER!] 
    ON TABLE1 
    AFTER UPDATE, DELETE 
AS 
BEGIN 
    SET NOCOUNT ON; 
    IF NOT UPDATE([LastAccessed]) BEGIN 
     IF EXISTS(SELECT * FROM inserted) BEGIN 
      INSERT INTO [Table1_Hist](
       Action, Id, LastAccessed, Data1, Data2 
      ) SELECT 
       'EDIT', Id, LastAccessed, Data1, Data2 
      FROM deleted 
     END ELSE BEGIN 
      INSERT INTO [Table1_Hist](
       Action, Id, LastAccessed, Data1, Data2 
      ) SELECT 
       'DELETE', Id, LastAccessed, Data1, Data2 
      FROM deleted 
     END 
    END 
END 

这个触发不会复制行如果上次访问和数据1两种变化(我想)。要解决这个问题,我可以改变IF声明

IF UPDATE(Id) OR UPDATE(Data1) OR UPDATE(Data2) ... BEGIN 

在这种情况下,它会工作打算

问题: 正如我在我的表34列,不容易指定每在IF声明中列。 有没有更简单的方法来做到这一点?

回答

3

希望有人有一个更优雅的回答比这个,但最坏的情况下,可以生成一个丑陋的IF语句对所有34列用一个简单的查询:

SELECT CASE WHEN column_id = 1 THEN 'IF ' ELSE 'OR ' END + 'UPDATE(' + name + ')' 
    FROM sys.columns 
    WHERE object_id = OBJECT_ID(N'[dbo].[Table1]') 
     AND name <> 'LastUpdated' 
    ORDER BY column_id 

然后,你可以剪切和粘贴IF语句的结果......不是一个优雅的解决方案,但它比手动输入更快。

+0

谢谢你法案,我写了一个应用程序(在C#中),已经这样做。它是自动的,但是输出非常大。我希望看起来更简单的解决方案 – AaA

0
CREATE TRIGGER [TRIGGER!] 
    ON TABLE1 
    AFTER UPDATE 
AS 
BEGIN 

INSERT INTO Table1_Hist (
Action 
Id 
LastAccessed 
Data1 
Data2 
) 
SELECT 'UPDATE',d.ID,d.LastAccessed,d.Data1,d.Data2, etc., etc. 
FROM DELETED d 
INNER JOIN INSERTED i ON d.id = i.id 
WHERE 
COALESCE(d.data1,'') <> COALESCE(i.data1,'') OR 
COALESCE(d.data2,'') <> COALESCE(i.data2,'') OR 
<repeat for every attribute EXCEPT LastAccessed> 
END 

这也将努力为刀片或多行的更新,而您的方法将有可能插入行,其中的数据并没有真正改变。

另外,您希望具有单独的UPDATE和DELETE触发器,因为在实际DELETE情况下,您的查询应该只从DELETED中转储完整的行集合。

+0

请注意,您可以省略COALESCE以定义为NOT NULL的任何属性。 –

+0

乔恩,谢谢你的回答,但是'<为每个属性重复EXCEPT LastAccessed>'是我试图避免的部分 – AaA

+0

有没有避免它,不幸:)我发布的是最干净的方式仍然保持理想的结果。 UPDATE(colname)的问题是,无论数据是否真正改变,它都会返回true。 –

相关问题