如果一个程式在运行,你没有source code,看不到相关的SQL语句或与DB交互的命令,有没有办法追踪数据的来龙去脉呢?下面介绍一个简单的方法来收集Insert/Update/Delete操作所引起的数据变化,以便你熟悉程式运行的每一步所引起的数据变化。下面以表PERSON为例:
建PERSON表:
USE [TESTDB] GO /****** Object: Table [dbo].[PERSON] Script Date: 2012/10/11 14:11:58 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO SET ANSI_PADDING ON GO CREATE TABLE [dbo].[PERSON]( [ID] [int] NULL, [NAME] [varchar](50) NULL ) ON [PRIMARY] GO SET ANSI_PADDING OFF GO
建表PERSON_LOG,用于存放PERSON数据变化前后的数据:
USE [TESTDB] GO /****** Object: Table [dbo].[PERSON_LOG] Script Date: 2012/10/11 14:12:42 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO SET ANSI_PADDING ON GO CREATE TABLE [dbo].[PERSON_LOG]( [ID] [int] NULL, [NAME] [varchar](50) NULL, [DAT] [varchar](8) NULL, [TIM] [varchar](6) NULL ) ON [PRIMARY] GO SET ANSI_PADDING OFF GO ALTER TABLE [dbo].[PERSON_LOG] ADD CONSTRAINT [DF_TRIGGER_LOG_DAT] DEFAULT (CONVERT([char](8),getdate(),(112))) FOR [DAT] GO ALTER TABLE [dbo].[PERSON_LOG] ADD CONSTRAINT [DF_TRIGGER_LOG_TIM] DEFAULT (replace(CONVERT([char](8),getdate(),(108)),':','')) FOR [TIM] GO
建表LOGR,用于存放SQL:
USE [TESTDB] GO /****** Object: Table [dbo].[LOGR] Script Date: 2012/10/11 14:11:18 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO SET ANSI_PADDING ON GO CREATE TABLE [dbo].[LOGR]( [USRNAM] [varchar](50) NULL, [STATMT] [varchar](max) NULL, [UPDDAT] [datetime] NULL, [TBLNAM] [varchar](50) NULL ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] GO SET ANSI_PADDING OFF GO
在PERSON表里建4个Trigger:
PERSON_LOGR用于收集SQL
USE [TESTDB] GO /****** Object: Trigger [dbo].[PERSON_LOGR] Script Date: 2012/10/11 14:14:03 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TRIGGER [dbo].[PERSON_LOGR] ON [dbo].[PERSON] FOR INSERT, UPDATE, DELETE AS DECLARE @CLIENT AS VARCHAR(50) DECLARE @DATETIME AS DATETIME DECLARE @USERNAME AS VARCHAR(50) DECLARE @STATMT AS VARCHAR(max) DECLARE @strSQL AS VARCHAR(100) SET @CLIENT = HOST_NAME() SET @DATETIME = GETDATE() SET @strSQL='DBCC INPUTBUFFER('+CAST(@@SPID AS VARCHAR(20))+')' CREATE TABLE #STATEMENT (C1 VARCHAR(50),C2 VARCHAR(50),C3 VARCHAR(500)) INSERT INTO #STATEMENT EXEC(@strSQL) SELECT @STATMT=C3 FROM #STATEMENT INSERT INTO LOGR(USRNAM,STATMT,UPDDAT,TBLNAM) VALUES(@CLIENT,@STATMT,@DATETIME,'PERSON') GO
PERSON_Insert用于收集INSERT的信息:
USE [TESTDB] GO /****** Object: Trigger [dbo].[PERSON_Insert] Script Date: 2012/10/11 14:13:41 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO -- ============================================= -- Author: <Author,,Name> -- Create date: <Create Date,,> -- Description: <Description,,> -- ============================================= CREATE TRIGGER [dbo].[PERSON_Insert] ON [dbo].[PERSON] FOR INSERT AS BEGIN SET NOCOUNT ON; INSERT [dbo].[PERSON_LOG](ID,NAME) SELECT * FROM INSERTED END GO
PERSON_UPDATE用于收集Update前后的数据:
USE [TESTDB] GO /****** Object: Trigger [dbo].[PERSON_UPDATE] Script Date: 2012/10/11 14:14:36 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO -- ============================================= -- Author: <Author,,Name> -- Create date: <Create Date,,> -- Description: <Description,,> -- ============================================= CREATE TRIGGER [dbo].[PERSON_UPDATE] ON [dbo].[PERSON] FOR UPDATE AS BEGIN SET NOCOUNT ON; INSERT [dbo].[PERSON_LOG](ID,NAME) SELECT * FROM INSERTED INSERT [dbo].[PERSON_LOG](ID,NAME) SELECT * FROM DELETED END GO
PERSON_DELETE 用于收集DELETE的信息:
USE [TESTDB] GO /****** Object: Trigger [dbo].[PERSON_DELETE] Script Date: 2012/10/11 14:13:07 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO -- ============================================= -- Author: <Author,,Name> -- Create date: <Create Date,,> -- Description: <Description,,> -- ============================================= CREATE TRIGGER [dbo].[PERSON_DELETE] ON [dbo].[PERSON] FOR DELETE AS BEGIN SET NOCOUNT ON; INSERT [dbo].[PERSON_LOG](ID,NAME) SELECT * FROM DELETED END GO