SQL Server:触发错误无效对象名称'已删除'

时间:2016-01-10 11:29:01

标签: sql sql-server tsql triggers

我有以下问题:我正在尝试使用一个触发器,它将所有从逻辑表Delete插入到一个新表(变量中的表名) 旧触发器始终有效,但对于这个新触发器,我得到以下结果:

  

Msg 208,Level 16,State 1,Line 1
  无效的对象名称'DELETED'。

带有两个触发器的代码段(首先仍然有效):

/* TRIGGER on dbo.tblSpending table to Create Backup/Clone - WORKING */
CREATE TRIGGER dbo.CloneTable 
ON dbo.tblSpending
FOR UPDATE
AS
BEGIN
    IF (EXISTS(SELECT *
               FROM INFORMATION_SCHEMA.TABLES
               WHERE TABLE_SCHEMA = 'dbo'
                 AND TABLE_NAME = 'tblSpendingRaw'))
    BEGIN
        DROP TABLE dbo.tblSpendingRaw;     

        SELECT *
        INTO dbo.tblSpendingRaw
        FROM Deleted;
   END;
END;
GO

dbo.tblSpending表上触发,为任何更新创建新表tblSpendingRaw + Date Stamp - 不工作:

CREATE TRIGGER dbo.SaveTable 
ON dbo.tblSpending 
FOR UPDATE AS
BEGIN       
    DECLARE @table_name VARCHAR(MAX);

    SET @table_name = (SELECT 'tblSpendingRaw'
                              + CAST(DATEPART(DAY, GETDATE()) AS VARCHAR(2))
                              + LEFT(UPPER(DATENAME(MONTH, GETDATE())), 3)
                              + CAST(DATEPART(HOUR, GETDATE()) AS VARCHAR(2))
                              + CAST(DATEPART(MINUTE, GETDATE()) AS VARCHAR(2))
                              + CAST(DATEPART(SECOND, GETDATE()) AS VARCHAR(2))
                              );

    EXEC('SELECT * INTO ' + @table_name + ' FROM Deleted');
END;
GO

提前感谢您提供任何帮助

加布里埃尔

1 个答案:

答案 0 :(得分:0)

由于动态SQL在不同的范围内执行,因此您无法找到Inserted或Deleted魔术表。因此,您需要将所有记录复制到临时表中,然后将临时表用于动态查询。然后你的代码就像那样

CREATE TRIGGER dbo.SaveTable 
ON dbo.tblSpending 
FOR UPDATE AS
BEGIN       
    DECLARE @table_name VARCHAR(MAX);

    SET @table_name = (SELECT 'tblSpendingRaw'
                              + CAST(DATEPART(DAY, GETDATE()) AS VARCHAR(2))
                              + LEFT(UPPER(DATENAME(MONTH, GETDATE())), 3)
                              + CAST(DATEPART(HOUR, GETDATE()) AS VARCHAR(2))
                              + CAST(DATEPART(MINUTE, GETDATE()) AS VARCHAR(2))
                              + CAST(DATEPART(SECOND, GETDATE()) AS VARCHAR(2))
                              );
SELECT * INTO dbo.temptbl FROM Deleted; 
    EXEC('SELECT * INTO ' + @table_name + ' FROM temptbl');
     DROP TABLE dbo.temptbl;

END;
GO