在软件实施过程中,也许会有这样的问题: 表中数据出现非预期的结果,此时不确定是程序问题,哪个程序,存储过程,触发器.. 或还是人为修改的结果,此时可以用触发器对特定的表字段做跟踪监视,记录每次新增,修改,删除此字段值的操作详细信息(含登录名,主机名,IP地址,执行的TSQL语句,程序名等等), 以利于问题的排查.

-- 建测试表
CREATE TABLE sto
    (
        id INT NOT NULL, -- 主键字段
        de DATETIME -- 被跟踪的字段
            CONSTRAINT pk_sto
            PRIMARY KEY (id)
    );

-- 建日志表
CREATE TABLE log_sto
    (
        logid      INT          NOT NULL IDENTITY(1, 1), -- 日志序号(日志主键)
        operate    VARCHAR(10),                          -- 操作类型 如Insert,Update,Delete.
        id         INT,                                  -- 原表ID(主键)
        old_de     DATETIME,                             -- de字段旧值
        new_de     DATETIME,                             -- de字段新值
        spid       INT          NOT NULL,                -- spid
        login_name VARCHAR(100),                         -- 登录名
        prog_name  VARCHAR(100),                         -- 程序名
        hostname   VARCHAR(100),                         -- 主机名
        ipaddress  VARCHAR(100),                         -- IP地址
        runsql     VARCHAR(4000),                        -- 执行的TSQL代码
        UDate      DATETIME -- 操作日期时间
            CONSTRAINT pk_logsto
            PRIMARY KEY (logid)
    );
GO

-- 建跟踪触发器
CREATE TRIGGER tr_sto
ON sto
AFTER UPDATE, INSERT, DELETE
AS
    BEGIN
        DECLARE @di TABLE
            (
                et VARCHAR(200),
                pt VARCHAR(200),
                ei VARCHAR(MAX)
            );
        INSERT INTO @di
        EXEC ('dbcc inputbuffer(@@spid)');

DECLARE @op VARCHAR(10);
        SELECT
            @op = CASE WHEN EXISTS ( SELECT 1 FROM inserted ) AND EXISTS (SELECT 1 FROM deleted)
                            THEN 'Update'
                       WHEN EXISTS ( SELECT 1 FROM inserted ) AND NOT EXISTS (SELECT 1 FROM deleted)
                            THEN 'Insert'
                       WHEN NOT EXISTS(SELECT 1 FROM inserted ) AND EXISTS (SELECT 1 FROM deleted)
                          THEN 'Delete'
                  END;

IF @op IN (
                      'Update', 'Insert'
                  )
            BEGIN
                INSERT INTO log_sto
                    (
                        operate,
                        id,
                        old_de,
                        new_de,
                        spid,
                        login_name,
                        prog_name,
                        hostname,
                        ipaddress,
                        runsql,
                        UDate
                    )
                            SELECT
                                @op,
                                n.id,
                                o.de,
                                n.de,
                                @@spid,
                                (
                                    SELECT
                                        login_name
                                    FROM
                                        sys.dm_exec_sessions
                                    WHERE
                                        session_id = @@spid
                                ),
                                (
                                    SELECT
                                        program_name
                                    FROM
                                        sys.dm_exec_sessions
                                    WHERE
                                        session_id = @@spid
                                ),
                                (
                                    SELECT
                                        hostname
                                    FROM
                                        sys.sysprocesses
                                    WHERE
                                        spid = @@spid
                                ),
                                (
                                    SELECT
                                        client_net_address
                                    FROM
                                        sys.dm_exec_connections
                                    WHERE
                                        session_id = @@spid
                                ),
                                (
                                    SELECT TOP 1
                                        ISNULL(ei, '')
                                    FROM
                                        @di
                                ),
                                GETDATE()
                            FROM
                                inserted n
                                LEFT JOIN
                                    deleted o
                                        ON o.id = n.id;
            END;
        ELSE
            BEGIN
                INSERT INTO log_sto
                    (
                        operate,
                        id,
                        old_de,
                        new_de,
                        spid,
                        login_name,
                        prog_name,
                        hostname,
                        ipaddress,
                        runsql,
                        UDate
                    )
                            SELECT
                                @op,
                                o.id,
                                o.de,
                                NULL,
                                @@spid,
                                (
                                    SELECT
                                        login_name
                                    FROM
                                        sys.dm_exec_sessions
                                    WHERE
                                        session_id = @@spid
                                ),
                                (
                                    SELECT
                                        program_name
                                    FROM
                                        sys.dm_exec_sessions
                                    WHERE
                                        session_id = @@spid
                                ),
                                (
                                    SELECT
                                        hostname
                                    FROM
                                        sys.sysprocesses
                                    WHERE
                                        spid = @@spid
                                ),
                                (
                                    SELECT
                                        client_net_address
                                    FROM
                                        sys.dm_exec_connections
                                    WHERE
                                        session_id = @@spid
                                ),
                                (
                                    SELECT TOP 1
                                        ISNULL(ei, '')
                                    FROM
                                        @di
                                ),
                                GETDATE()
                            FROM
                                deleted o;
            END;
    END;
GO

--> 测试DML操作

-- 操作1
INSERT INTO sto
    (
        id,
        de
    )
VALUES
    (
        1, '2012-01-01 05:06:07'
    );
GO

-- 操作2
INSERT INTO sto
    (
        id,
        de
    )
VALUES
    (
        2, '2012-01-01 06:06:07'
    );
GO

-- 操作3
UPDATE
    sto
SET
    de = getdate()
WHERE
    id = 2;
GO

-- 操作4
UPDATE
    sto
SET
    de = getdate()
WHERE
    id = 1;
GO

-- 操作5
INSERT INTO sto
    (
        id,
        de
    )
VALUES
    (
        5, '2012-01-01 15:26:37'
    );
GO

-- 操作6
DELETE sto
WHERE
    id = 2;
GO

MSSQL记录表字段数据变化的相关SQl的更多相关文章

  1. ms_sql 触发器记录表字段数据变化的日志 -针对一张表操作

    create table sto (id int not null, -- 主键字段 de datetime -- 被跟踪的字段 constraint pk_sto primary key(id)) ...

  2. resultset 对象获取行字段数据时报:java.sql.SQLException: Column 'id' not found.

    resultset 对象获取行字段数据时报:java.sql.SQLException: Column 'id' not found. 代码: String sql="SELECT d.co ...

  3. 触发器记录表某一个字段数据变化的日志 包括插入insert 修改update 删除delete 操作

    本文参考:http://www.cnblogs.com/lyhabc/articles/3236985.html ,),  ),               ),           ),       ...

  4. Entity Framework使用EntityState和Attach来保存数据变化以及更新实体的个别字段

    在使用Entity Framework作为ORM来存取数据的过程中,最常规的操作就是对数据对象的更新.本文将会包含如何Attach Entity到一个数据Context中,以及如何使用EntitySt ...

  5. Sql Server 添加、更新、查询表注释、字段注释相关sql

    /*******************字段添加注释*********************/ if not exists (SELECT C.value AS column_description ...

  6. 小程序的数据监听 用法和vue中的watch一样====使用通配符监听所有自数据字段的变化

    使用通配符监听所有自数据字段的变化

  7. mssql与mysql 数据迁移

    概要: mssql向mysql迁移的实例,所要用到的工具bcp和load data local infile. 由于订单记录的数据是存放在mssql服务器上的,而项目需求把数据迁移到mysql ser ...

  8. MSSQL批量写入数据方案

    近来有一个项目Feature需要有批量写入数据的场景,正巧整理资料发现自己以前也类似实现的项目,在重构的同时把相关资料做了一个简单的梳理,方便大家参考. 循环写入(简单粗暴,毕业设计就这样干的)(不推 ...

  9. Adapter数据变化改变现有View的实现原理及案例

    首先说说Adapter详细的类的继承关系.例如以下图 Adapte为接口它的实现类的对象作为AdapterView和View的桥梁,Adapter是装载了View(比方ListView和girdVie ...

随机推荐

  1. maxima已知方程,计算结果

  2. 论文阅读笔记六十四: Architectures for deep neural network based acoustic models defined over windowed speech waveforms(INTERSPEECH 2015)

    论文原址:https://pdfs.semanticscholar.org/eeb7/c037e6685923c76cafc0a14c5e4b00bcf475.pdf 摘要 本文研究了利用深度神经网络 ...

  3. leetcode752. 打开转盘锁

    我们可以将 0000 到 9999 这 10000 状态看成图上的 10000 个节点,两个节点之间存在一条边,当且仅当这两个节点对应的状态只有 1 位不同,且不同的那位相差 1(包括 0 和 9 也 ...

  4. NOIP201110观光公交

    题目描述 Description 风景迷人的小城Y市,拥有n个美丽的景点.由于慕名而来的游客越来越多,Y市特意安排了一辆观光公交车,为游客提供更便捷的交通服务.观光公交车在第0分钟出现在1号景点,随后 ...

  5. 9.第一个vue-cli项目

    1.什么是vue-cli vue-cli 官方提供的一个脚手架,用于快速生成一个 vue 的项目模板; 预先定义好的目录结构及基础代码,就好比咱们在创建 Maven 项目时可以选择创建一个骨架项目,这 ...

  6. tecplot——Fluent重叠网格解决方案

    算例来源:http://blog.sina.com.cn/s/blog_af99efb50102xoh3.html 受上篇博文的启发,在tecplot当中也能采用类似的方法处理Fluent的重叠网格计 ...

  7. html5预加载图片的写法

    插件还是用 jquery.imgpreload.min.js 只不过初始化加载 必须用window.onload 图片dom都加载完成再显示 不然会有bug <pre> window.on ...

  8. linux centos安装教程

    linux centos安装教程1 CentOS-7-x86_64-DVD-1511.iso 这个是dvd版本 2 CentOS-7-x86_64-Minimal-1511.iso 这个迷你版 是没有 ...

  9. linux中断子系统

    参考引用:http://www.wowotech.net/sort/irq_subsystem wowotech:一个很好的linux技术博客. 一.概述 目的 kernel管理硬件设备的方式:轮询. ...

  10. 阿里云ECS服务器CentOS7.2安装Python2.7.13

    阿里云ECS服务器CentOS7.2安装Python2.7.13 yum中最新的也是Python 2.6.6,只能下载Python 2.7.9的源代码自己编译安装. 操作步骤如下: 检查CentOS7 ...