首先在master库下建立表ProcSqlTable和BackProcSqlTable。ProcSqlTable存放存储过程当前版本代码,BackProcSqlTable存放历史版本代码。
USE [master] GO CREATE TABLE [dbo].[BackProcSqlTable]( [id] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY ,--编号 [dbName] [nvarchar](150) NOT NULL,--数据库名 [ProcSQL] [ntext] NOT NULL,--存储过程的SQL [ProcName] [nvarchar](150) NOT NULL,--存储过程名字 [AlterDate] [datetime] NOT NULL,--修改时间 [AlterUser] [nvarchar](150) NULL--修改人 ) GO USE [master] GO CREATE TABLE [dbo].[ProcSqlTable]( [id] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,--编号 [dbName] [nvarchar](150) NOT NULL,--数据名 [ProcSQL] [ntext] NOT NULL,--存储过程SQL [ProcName] [nvarchar](150) NOT NULL--存储过程名字 ) GO
接下来需要建立两个库级(DDL)触发器:tr_saveProcSql和tr_saveBackProcSql。tr_saveProcSql将新建存储过程代码写入ProcSqlTable,tr_saveBackProcSql将ProcSqlTable表中保存的代码写到BackProcSqlTable中作为历史版本代码,同时将存储过程当前代码更新到ProcSqlTable。
USE [master] GO create trigger [tr_saveProcSql] on all server --作用于SQL Server实例下所有库 for CREATE_PROCEDURE as --获取事件数据 DECLARE @data XML SET @data = EVENTDATA() declare @dbName nvarchar(50) declare @ProcName nvarchar(150) declare @ProcSQL nvarchar(max) --获取新建存储过程的数据库名 SET @dbName = @data.value('(/EVENT_INSTANCE/DatabaseName)[1]', 'sysname') --获取新建存储过程的名字 set @ProcName= @data.value('(/EVENT_INSTANCE/ObjectName)[1]', 'sysname') --获取新建存储过程的内容 set @ProcSQL = @data.value('(/EVENT_INSTANCE/TSQLCommand/CommandText)[1]', 'sysname') --将数据库名、存储过程名以及存储过程内容插入ProcSqlTable表 insert into [master].[dbo].[ProcSqlTable]([dbName],[ProcName],[ProcSQL]) values(@dbName,@ProcName,@ProcSQL) GO ENABLE TRIGGER [tr_saveProcSql] ON ALL SERVER GO
USE [master] GO create trigger [tr_saveBackProcSql] on all server --作用于SQL Server实例下所有库 for ALTER_PROCEDURE as --获取事件数据 DECLARE @data XML SET @data = EVENTDATA() declare @dbName nvarchar(50) declare @ProcName nvarchar(150) declare @LoginName nvarchar(150) declare @ProcSQL nvarchar(max) --存储过程内容 declare @OldProcSQL nvarchar(max)--修改前的存储过程内容 --获取修改存储过程的数据库名 SET @dbName = @data.value('(/EVENT_INSTANCE/DatabaseName)[1]', 'sysname') --获取修改存储过程的名字 set @ProcName= @data.value('(/EVENT_INSTANCE/ObjectName)[1]', 'sysname') --获取修改存储过程的内容 set @ProcSQL = @data.value('(/EVENT_INSTANCE/TSQLCommand/CommandText)[1]', 'sysname') --获取用户名 set @LoginName = @data.value('(/EVENT_INSTANCE/LoginName)[1]', 'sysname') if exists(select 1 from [master].[dbo].[ProcSqlTable] where [dbName]=@dbName and [ProcName]=@ProcName) begin --如果系统里有该存储过程的记录,获取修改前的存储过程内容 select @OldProcSQL=[ProcSQL] from [master].[dbo].[ProcSqlTable] where [dbName]=@dbName and [ProcName]=@ProcName end else begin --如果没有将数据库名、存储过程名以及存储过程内容插入ProcSqlTable表 insert into [master].[dbo].[ProcSqlTable]([dbName],[ProcName],[ProcSQL]) values(@dbName,@ProcName,@ProcSQL) --退出 return end --更新ProcSqlTable表存储过程的内容供下次使用 update [master].[dbo].[ProcSqlTable] set [ProcSQL]=@ProcSQL where [dbName]=@dbName and [ProcName]=@ProcName --将数据库名、存储过程名以及修改前的存储过程内容插入BackProcSqlTable表 insert into [master].[dbo].[BackProcSqlTable]([dbName],[ProcName],[ProcSQL],[AlterDate],[AlterUser]) values(@dbName,@ProcName,@OldProcSQL,GETDATE(),@LoginName) GO ENABLE TRIGGER [tr_saveBackProcSql] ON ALL SERVER GO
=====================================================================================
本文只代表本人的见解,可能存在错误,仅用于技术交流。如果你喜欢该文,可以扫下面的二维码打赏我(打赏敬请备注“博客园打赏”五字)。