【问题标题】:How to make triggers based on the number of tables in stored procedure如何根据存储过程中的表数进行触发器
【发布时间】:2019-02-28 16:42:09
【问题描述】:

我有如下 3 个表

CREATE TABLE [dbo].[AuditTrail]
(
    [AuditId] [INT] IDENTITY(1,1) NOT NULL,
    [DateTime] [DATETIME] NOT NULL,
    [TableName] [NVARCHAR](255) NOT NULL,
    [AuditEntry] [XML] NULL,

    CONSTRAINT [PK_AuditTrail] 
        PRIMARY KEY CLUSTERED (
)

CREATE TABLE [dbo].[Employee]
(
     [ID] [UNIQUEIDENTIFIER] NOT NULL DEFAULT (NEWID()),
     [NameEmployee] [NVARCHAR](255) NOT NULL,

     CONSTRAINT [PK_Employee] PRIMARY KEY CLUSTERED (
)

CREATE TABLE [dbo].[Transaction]
(
     [ID] [UNIQUEIDENTIFIER] NOT NULL DEFAULT (NEWID()),
     [NameTransaction] [NVARCHAR](255) NOT NULL,

     CONSTRAINT [PK_Transaction] 
         PRIMARY KEY CLUSTERED (
)

我已经为我的表创建了 2 个触发器来处理一些删除,这是我做得很好的触发器。我的触发器在下面

CREATE TRIGGER AuditEmployee 
ON [dbo].[Employee]
AFTER INSERT, DELETE, UPDATE
AS 
BEGIN
    SET NOCOUNT ON;

    IF (SELECT COUNT(*) FROM deleted) > 0 
    BEGIN
        DECLARE @AuditMessage XML
        SET @AuditMessage = (select * from deleted for xml auto) 

        INSERT INTO AuditTrail (DateTime, TableName, AuditEntry)  
        VALUES (GETDATE(), 'Simple', @AuditMessage)
    END
END
GO

CREATE TRIGGER AuditTransaction 
ON [dbo].[Transaction]
AFTER INSERT,DELETE,UPDATE
AS 
BEGIN
    SET NOCOUNT ON;

    IF (SELECT COUNT(*) FROM deleted) > 0 
    BEGIN
        DECLARE @AuditMessage XML
        SET @AuditMessage = (select * from deleted for xml auto) 

        INSERT INTO AuditTrail (DateTime, TableName, AuditEntry)  
        VALUES (GETDATE(), 'Simple', @AuditMessage )
end

END
GO

在上面的查询中,我为两个表(Employee 和 Transaction)创建了两个触发器。如果两个表中的数据都被删除,数据将被插入到 AuditAll 表中。

我想问的是,如果我们有 10 个表,我必须做 10 个触发器吗?是否可以在存储过程中创建它,这样我就不会根据我的表数手动触发?

如果可能,如何使用存储过程来做到这一点?请帮忙:)

【问题讨论】:

  • 如果删除的表为空,为什么要创建不执行任何操作的插入触发器?似乎处理插入有点愚蠢。但是对于您的问题,触发器正在处理表上的事件。因此,如果您想跟踪给定表中的删除,那么是的,您需要在该表上使用触发器。如果您从 10 个表中删除,则需要在每个要跟踪的表上设置一个触发器。您可以在您的过程中使用 OUTPUT 子句执行此操作,但这不会捕获在您的过程之外发生的删除。
  • 你必须做 10 件事。在存储过程中,您可以将merge$action.deleted OUTPUT 存储到临时表中,并在audittrail 中运行最终插入,但是您仍然需要在存储过程中执行10 个merge 语句。
  • 你能给我一个示例过程来为我上面的表格动态创建触发器吗? @TJB

标签: sql-server stored-procedures database-trigger


【解决方案1】:

要做你目前正在做的事情,只有 10 个表,是的,你必须创建 10 个触发器。

您可以通过多种不同方式动态生成触发器。你可以把你的表名放在一个表变量中,并以你最舒服的任何方式(WHILE 循环、CURSOR、OUTER APPLY)遍历它,并构建一个 sql 字符串,将表名合并到你拥有的 TRIGGER 脚本中,然后执行它.

因为这显然是一个临时操作,所以我不会担心循环和游标的性能问题,只要你写最容易写的就行。

【讨论】:

  • 你能给我一个示例循环查询来为我上面的表动态创建触发器吗?
  • 不,我没有这个方便的例子。如果您尝试编写它并遇到错误,请返回并将错误和您的代码作为新问题发布,我们将提供帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-07-18
  • 1970-01-01
  • 1970-01-01
  • 2013-01-22
  • 2016-06-25
  • 2010-12-09
  • 1970-01-01
相关资源
最近更新 更多