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

SQL Server:触发器错误无效的对象名称';删除';,sql,sql-server,tsql,triggers,Sql,Sql Server,Tsql,Triggers,我有以下问题:我正在尝试使用一个触发器,该触发器将从逻辑表Delete插入一个新表(表名from变量) 旧触发器始终有效,但对于新触发器,我得到以下信息: 味精208,第16级,状态1,第1行 无效的对象名称“已删除” 具有两个触发器的代码段(第一个仍在工作): 在dbo.tblSpending表上触发,该表将为任何更新创建一个新表tblSpendingRaw+日期戳-不工作: CREATE TRIGGER dbo.SaveTable ON dbo.tblSpending FOR UPDAT

我有以下问题:我正在尝试使用一个触发器,该触发器将从逻辑表Delete插入一个新表(表名from变量) 旧触发器始终有效,但对于新触发器,我得到以下信息:

味精208,第16级,状态1,第1行
无效的对象名称“已删除”

具有两个触发器的代码段(第一个仍在工作):

dbo.tblSpending
表上触发,该表将为任何更新创建一个新表
tblSpendingRaw+日期戳
-不工作:

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
提前谢谢你的帮助


Gabriel

因为动态SQL在不同的作用域下执行,所以您无法在其中找到插入或删除的魔法表。所以,您需要将所有记录复制到临时表中,然后将临时表用于动态查询。然后你的代码就是这样的

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

一句话:不要这样做!!触发器应该非常灵活、小巧、快速——不要在触发器内进行任何繁重的处理或耗时的工作(比如创建或删除表!)!另外:为每个
更新创建一个新表似乎也太过分了。。。。。。重新思考您的代码-更改它-此代码在繁忙的系统中永远不会运行,也永远不会可靠地工作谢谢您的建议Marc,我永远不会在生产表上使用此触发器。它只是用于测试,我必须尝试不同的方法来计算方案的忠诚度。Gabriel谢谢你的解释和解决方案Rahul,我永远不会在生产表上使用此触发器。它只是用于测试,我必须尝试不同的方法来计算方案的忠诚度点数。因此,我发现将历史快照进行比较并最终选择最合适的方式非常方便:)。
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