【问题标题】:INSTEAD OF : for each row in SQL Server 2012INSTEAD OF :对于 SQL Server 2012 中的每一行
【发布时间】:2016-02-24 09:09:36
【问题描述】:

如果我使用示例中的INSTEAD OF DELETE 触发器,这是否适用于我已删除记录的每一行,还是我必须指定它?如果没有,我该怎么办?使用 select distinct ?谢谢你:)

ALTER TRIGGER "rdowner"."TriggerDelete" ON "rdowner"."V_MyTable" 
INSTEAD OF DELETE
AS 
BEGIN TRY
    DECLARE @idActivity INT

    SELECT  @idActivity = rdowner.V_MyTable.Id,
    FROM deleted

    BEGIN 
         myDeleteRoutine
    END  
END TRY

BEGIN CATCH
    SELECT 
            ERROR_NUMBER() AS ErrorNumber,
            ERROR_SEVERITY() AS ErrorSeverity,
            ERROR_STATE() as ErrorState,
            ERROR_PROCEDURE() as ErrorProcedure,
            ERROR_LINE() as ErrorLine,
            ERROR_MESSAGE() as ErrorMessage
END CATCH

我的触发器需要将每个已删除行的@idActivity、时间戳和 varchar 变量记录到另一个表中

【问题讨论】:

  • SQL Server 触发器 NEVER “在每一行上”工作 - 每个语句都调用它们 ONCE,所以如果您的 DELETE 语句删除 50 行,您的触发器称为 ONCEDeleted 伪表包含 50 行,您需要以 基于集合的方式处理这些行
  • 是的。编写触发器并且不知道绝对基础。拜托,你可以做得更好。
  • @marc_s 非常感谢 marc,这对我有帮助!
  • @TomTom 我会做得更好,这只是因为我看到甲骨文代码使用 for each row 这就是为什么我想知道是否有办法做到这一点,反正我是只是一个初学者。
  • 如果您搜索“每行的 SQL Server 触发器”,您会找到很多答案。顺便说一句,您的触发器不使用 deleted

标签: sql-server triggers sql-server-2012


【解决方案1】:

基于此:

我的触发器需要将每个已删除行的@idActivity、时间戳和 varchar 变量记录到另一个表中

那么在BEGIN TRYEND TRY 之间你只需要这个:

INSERT INTO MyLogTable (ID, Column1,Column2, TimeStampColumn)
SELECT ID, Column1,Column2,GETDATE()
FROM DELETED

还建议更改您的错误日志以记录到表或完全删除它

【讨论】:

  • 非常感谢尼克,这正是我需要的。
【解决方案2】:

我们打算对基表执行何种操作,而不是触发器允许我们执行何种操作。请注意,此操作不会影响基表。如果我们执行此删除,我们将有权访问将被删除的数据。以下是一些可能对您有所帮助的示例

--创建基本触发器:

create trigger trg_insd_test
on dbo.test1
instead of delete
as
begin
select 'trigger fired'
select * from deleted
end

--现在让我们删除所有行并查看触发器是如何触发的

delete from test1

输出:
即使我尝试删除所有行触发器仅触发一次,并且我可以访问所有已删除的行

现在让我们批量删除:

delete top(10) from test1
go 10

输出:
您可以看到每批次触发触发器

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-24
    • 1970-01-01
    • 1970-01-01
    • 2017-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多