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

问题描述 投票:0回答:2

我有以下问题:我正在尝试使用一个触发器,将逻辑表删除中的所有内容插入到新表中(变量中的表名称) 旧的触发器始终有效,但对于这个新的触发器,我得到以下信息:

消息 208,第 16 级,状态 1,第 1 行
对象名称“已删除”无效。

具有两个触发器的代码片段(第一个仍然有效):

/* 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

预先感谢您的帮助

加布里埃尔

sql sql-server t-sql triggers
2个回答
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

0
投票

光标方式适合我。 (我正在从另一个相关数据库中删除行)

DECLARE @DeletedCursor_Id INT

DECLARE DeletedCursor CURSOR FOR

SELECT 
    d.id
FROM DELETED d

OPEN DeletedCursor
FETCH NEXT FROM DeletedCursor 
INTO
    @DeletedCursor_Id

WHILE @@FETCH_STATUS = 0
BEGIN

    DECLARE @SQLString VARCHAR(500)    = 
        'DELETE TOP(1) FROM ' + @TargetDbName + '.dbo.AnotherDbTable WHERE id = ' + (CAST(@DeletedCursor_Id AS VARCHAR(MAX)));
    
    EXECUTE (@SQLString)

    FETCH NEXT FROM DeletedCursor 
    INTO
        @DeletedCursor_Id
END

CLOSE DeletedCursor
DEALLOCATE DeletedCursor
© www.soinside.com 2019 - 2024. All rights reserved.