全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

SQL Server实现用触发器捕获DML操作的会话信息【实例】

需求背景

上周遇到了这样一个需求,维护人员发现一个表的数据经常被修改,由于历史原因;文档缺少;以及维护人员的经常变更,导致他们对系统也业务也不完全熟悉,他们也不完全清楚哪些系统和应用程序会对这个表的数据进行操作。现在他们想找出有哪些服务器,哪些应用程序会对这个表进行INSERT、UPDATE操作。那么问题来了,怎么去解决这个问题呢?

解决方案

由于数据库版本是标准版,我们选择了使用触发器来捕获进行DML操作的会话的相关信息,例如,Host_Name、Program_Name等 ,选择触发器是因为简单直接。我们先创建一个表名为TEST的表,假设我们想监控有哪些应用服务器,以及那些应用程序会对表TEST进行INSERT、UPDATE操作。

USE [AdventureWorks2014]

GO

 

IF NOT EXISTS (SELECT 1 FROM sys.sysobjects WHERE id=object_id(N'[dbo].[TEST]') AND OBJECTPROPERTY(id, N'IsTable')=1 )

BEGIN

CREATE TABLE [dbo].[TEST](

  [OBJECT_ID] [INT] NOT NULL,

  [NAME] [VARCHAR](8) NULL,

  CONSTRAINT PK_TEST  PRIMARY KEY (OBJECT_ID)

) 

END

GO

 

INSERT INTO dbo.TEST

SELECT 1, 'kerry' UNION ALL

SELECT 2, 'jimmy'

那么我们接下来在表上面新增几个字段 [HOST_NAME]、[PROGRAM_NAME]、LOGIN_NAME用来记录最后一次修改该记录的会话信息,另外创建触发器TRG_TEST来更新这几个字段

ALTER TABLE TEST ADD [HOST_NAME] NVARCHAR(256)

ALTER TABLE TEST ADD [PROGRAM_NAME] NVARCHAR(256);

ALTER TABLE TEST ADD LOGIN_NAME NVARCHAR(256);

 

CREATE TRIGGER TRG_TEST ON dbo.TEST AFTER 

INSERT,UPDATE

AS 

 

IF (EXISTS(SELECT 1 FROM INSERTED))

BEGIN

 

  UPDATE dbo.TEST

  SET   dbo.TEST.[HOST_NAME] = ( SELECT host_name

                   FROM  sys.dm_exec_sessions

                   WHERE session_id = @@SPID

                  ) ,

      dbo.TEST.PROGRAM_NAME = ( SELECT  program_name

                   FROM   sys.dm_exec_sessions

                   WHERE   session_id = @@SPID

                  ) ,

      dbo.TEST.LOGIN_NAME = ( SELECT login_name

                  FROM  sys.dm_exec_sessions

                  WHERE  session_id = @@SPID

                 )

  FROM  dbo.TEST t

      INNER JOIN INSERTED i ON t.OBJECT_ID = i.OBJECT_ID

END

GO

接下来,我们来简单测试一下,如下所示,分布插入、更新一条记录

INSERT INTO dbo.TEST(OBJECT_ID,NAME)

SELECT 3,'ken'

 

UPDATE dbo.TEST SET NAME='Richard' WHERE OBJECT_ID=2;

如下所示,因为我只是用SSMS更新,插入数据,所以捕获的是Microsoft SQL Server Management Studio - Query。

这这种方式还有一个弊端,那就是如果应用程序的SQL,写得不够健壮的话,那么增加字段就会导致以前的应用程序出现问题,例如,应用程序有下面这样的SQL,增加字段后,它就会报错。

INSERT INTO dbo.TEST

SELECT 3,'ken'

所以这种方案不太可行,会增加应用程序出现Bug的风险。那么其实我们可以新建一个表,每当原表TEST有INSERT、UPDATE操作时,通过触发器捕获会话进程信息,然后插入该表(注意,新建的表包含源表的主键字段,例如这里TEST的主键字段为OBJECT_ID,那么我们下面就包含OBJECT_ID)

USE [AdventureWorks2014]

GO

 

DROP TABLE dbo.[TRG_TEST_SESSION_INFO];

GO

 

IF NOT EXISTS (SELECT 1 FROM sys.sysobjects WHERE id=object_id(N'[dbo].[TRG_TEST_SESSION_INFO]') AND OBJECTPROPERTY(id, N'IsTable')=1 )

BEGIN

CREATE TABLE [TRG_TEST_SESSION_INFO](

  [ID]        INT NOT NULL IDENTITY(1,1),

  [OBJECT_ID]    INT,

  [HOST_NAME]    NVARCHAR(256),

  [PROGRAM_NAME]   NVARCHAR(256),

  [LOGIN_NAME]    NVARCHAR(256),

  CONSTRAINT PK_TRG_TEST_SESSION_INFO  PRIMARY KEY (ID)

) 

END

GO

 

CREATE TRIGGER TRG_TEST_SESSION ON dbo.TEST

AFTER INSERT ,UPDATE

AS

 

IF (EXISTS(SELECT 1 FROM INSERTED))

BEGIN

 

  /*

  INSERT INTO dbo.[TRG_TEST_SESSION_INFO]

  SELECT (SELECT I.OBJECT_ID FROM INSERTED I), HOST_NAME,program_name,login_name

                   FROM  sys.dm_exec_sessions

                   WHERE session_id = @@SPID*/

  INSERT INTO dbo.[TRG_TEST_SESSION_INFO]

  SELECT I.OBJECT_ID, S.HOST_NAME,S.PROGRAM_NAME,S.LOGIN_NAME

                   FROM  sys.dm_exec_sessions s,

                      Inserted i

                   WHERE session_id = @@SPID

 

 

END

GO

在运行一小段时间后,如果已经找出了哪些服务器、哪些应用程序会对这些表操作后,那么就必须马上删除这些表和触发器,避免长时间运行,影响性能。

以上这篇SQL Server实现用触发器捕获DML操作的会话信息【实例】就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。


# sqlserver  # 触发器  # 关于喜忧参半的SQL Server触发器详解  # 利用SQL Server触发器实现表的历史修改痕迹记录  # SQLSERVER对加密的存储过程、视图、触发器进行解密(推荐)  # SQL Server 使用触发器(trigger)发送电子邮件步骤详解  # SQL Server:触发器实例详解  # SqlServer触发器详解  # SqlServer实现类似Oracle的before触发器示例  # SQL SERVER中各类触发器的完整语法及参数说明  # SQL SERVER 触发器介绍  # SQL Server误区30日谈 第4天 DDL触发器就是INSTEAD OF触发器  # SQL Server 触发器详情  # 应用程序  # 会对  # 也不  # 宋体  # 给大家  # 所示  # 标准版  # 的是  # 主键  # 几个  # 就会  # 来了  # 是因为  # 有哪些  # 出了  # 不太  # 长时间  # 我们可以  # 希望能  # 这样一个 


相关文章: 如何在西部数码注册域名并快速搭建网站?  建站主机默认首页配置指南:核心功能与访问路径优化  专业型网站制作公司有哪些,我设计专业的,谁给推荐几个设计师兼职类的网站?  建站之星后台密码遗忘或太弱?如何重置与强化?  怎么制作网站设计模板图片,有电商商品详情页面的免费模板素材网站推荐吗?  如何快速生成橙子建站落地页链接?  建站之星安装路径如何正确选择及配置?  详解ASP.NET 生成二维码实例(采用ThoughtWorks.QRCode和QrCode.Net两种方式)  宝塔面板创建网站无法访问?如何快速排查修复?  如何在腾讯云服务器快速搭建个人网站?  专业企业网站设计制作公司,如何理解商贸企业的统一配送和分销网络建设?  c# 在高并发下使用反射发射(Reflection.Emit)的性能  宝华建站服务条款解析:五站合一功能与SEO优化设置指南  如何在香港服务器上快速搭建免备案网站?  如何在景安云服务器上绑定域名并配置虚拟主机?  如何零成本快速生成个人自助网站?  如何制作算命网站,怎么注册算命网站?  MySQL查询结果复制到新表的方法(更新、插入)  关于BootStrap modal 在IOS9中不能弹出的解决方法(IOS 9 bootstrap modal ios 9 noticework)  建站中国官网:模板定制+SEO优化+建站流程一站式指南  零服务器AI建站解决方案:快速部署与云端平台低成本实践  Swift中循环语句中的转移语句 break 和 continue  建站之星安装后如何配置SEO及设计样式?  如何在Windows虚拟主机上快速搭建网站?  如何在宝塔面板中修改默认建站目录?  为什么Go需要go mod文件_Go go mod文件作用说明  建站主机无法访问?如何排查域名与服务器问题  c# F# 的 MailboxProcessor 和 C# 的 Actor 模型  如何选择高效稳定的ISP建站解决方案?  如何在阿里云虚拟机上搭建网站?步骤解析与避坑指南  建站之星如何助力网站排名飙升?揭秘高效技巧  建站之星×万网:智能建站系统+自助建站平台一键生成  非常酷的网站设计制作软件,酷培ai教育官方网站?  洛阳网站制作公司有哪些,洛阳的招聘网站都有哪些?  如何挑选优质建站一级代理提升网站排名?  如何通过万网虚拟主机快速搭建网站?  网站制作壁纸教程视频,电脑壁纸网站?  沈阳个人网站制作公司,哪个网站能考到沈阳事业编招聘的信息?  建站主机选虚拟主机还是云服务器更好?  手机怎么制作网站教程步骤,手机怎么做自己的网页链接?  制作旅游网站html,怎样注册旅游网站?  如何用IIS7快速搭建并优化网站站点?  在线教育网站制作平台,山西立德教育官网?  宝塔建站助手安装配置与建站模板使用全流程解析  建站之星手机一键生成:多端自适应+小程序开发快速建站指南  如何快速搭建二级域名独立网站?  外贸公司网站制作哪家好,maersk船公司官网?  建站之星后台管理:高效配置与模板优化提升用户体验  定制建站流程解析:需求评估与SEO优化功能开发指南  股票网站制作软件,网上股票怎么开户? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。