SQL存储过程更改日志记录触发器不保存所有文本

时间:2015-05-12 13:11:37

标签: sql tsql sql-server-2012

我创建了一个存储过程来记录对存储过程所做的更改。问题在于,较大的那些并没有被完整保存,而是被砍掉了。

我需要能够保存整个过程文本,它还可以用作恢复先前版本的方法。

触发器:

/****** Object:  DdlTrigger [StoredProcUpdateInsert]    Script Date: 12/05/2015 14:05:05 ******/
DROP TRIGGER [StoredProcUpdateInsert] ON DATABASE
GO

/****** Object:  DdlTrigger [StoredProcUpdateInsert]    Script Date: 12/05/2015 14:05:05 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO



CREATE TRIGGER [StoredProcUpdateInsert]
ON DATABASE
FOR CREATE_PROCEDURE, ALTER_PROCEDURE

AS
BEGIN
SET NOCOUNT ON


DECLARE @data XML
SET @data=EVENTDATA()

INSERT INTO dbo.ProcedureChanges
        ( ProcName ,
          ProcText ,
          ModifiedBy ,
          DateTimeLastUpdated
        )
VALUES  ( @data.value('(/EVENT_INSTANCE/ObjectName)[1]','nvarchar(max)') , -- ProcName - nvarchar(450)
          (SELECT TOP 1 text FROM syscomments WHERE id=OBJECT_ID(@data.value('(/EVENT_INSTANCE/ObjectName)[1]','nvarchar(max)'))) , -- ProcText - nvarchar(max)
          @data.value('(/EVENT_INSTANCE/LoginName)[1]','nvarchar(max)') , -- ModifiedBy - nvarchar(250)
          GETDATE()  -- DateTimeLastUpdated - datetime
        )



END 


GO

SET ANSI_NULLS OFF
GO

SET QUOTED_IDENTIFIER OFF
GO

ENABLE TRIGGER [StoredProcUpdateInsert] ON DATABASE
GO

1 个答案:

答案 0 :(得分:2)

根据这篇文章:https://msdn.microsoft.com/en-us/library/ms186293.aspx你不应该使用syscomments,而应该使用sys.sqlmodules

上述文章中syscomments.text的定义称其定义为nvarchar(4000)。据推测,这意味着任何超过4000个字符的DDL都会被截断,因此您只能获得日志表中的前4000个字符。

我还没有对此进行过测试,但您可以尝试:

INSERT INTO dbo.ProcedureChanges
        ( ProcName ,
          ProcText ,
          ModifiedBy ,
          DateTimeLastUpdated
        )
VALUES  ( @data.value('(/EVENT_INSTANCE/ObjectName)[1]','nvarchar(max)') , -- ProcName - nvarchar(450)
          (SELECT Definition FROM sys.sql_modules WHERE object_id=OBJECT_ID(@data.value('(/EVENT_INSTANCE/ObjectName)[1]','nvarchar(max)'))) , -- ProcText - nvarchar(max)
          @data.value('(/EVENT_INSTANCE/LoginName)[1]','nvarchar(max)') , -- ModifiedBy - nvarchar(250)
          GETDATE()  -- DateTimeLastUpdated - datetime
        )