0

0

触发器实现记录操作表的日志

php中文网

php中文网

发布时间:2016-06-07 15:09:48

|

1722人浏览过

|

来源于php中文网

原创

这个功能我是琢磨了好久,本来我的sqlserver方面的知识深入了解的就不多,关键的难点是用变量代替字段名,然后获取字段在表中存的值,再赋给另外一个变量,我之所以这么做,因为后面好几处要用到这个字段的名称,我才用变量代替,便于修改,可就是 实现 花费

这个功能我是琢磨了好久,本来我的sqlserver方面的知识深入了解的就不多,关键的难点是用变量代替字段名,然后获取字段在表中存的值,再赋给另外一个变量,我之所以这么做,因为后面好几处要用到这个字段的名称,我才用变量代替,便于修改,可就是实现花费了很长时间,网上这么方面的资料又少,可终究还是找到了解决方案,希望大家以后遇到同样的问题不至于头大,把具体的实现分享给大家

CREATE trigger [dbo].[trg_new_course]

on [dbo].[course]

for insert,delete,update

as

begin

declare @tabname varchar(50),

    @pkname varchar(20),

    @pkvalue varchar(20),

           @opttype int,

          @optip varchar(20),

          @optsql varchar(200),

    @xmlstr nvarchar(500);

declare @optinfo nvarchar(500), @id_i int, @id_d int;

declare @min_id int, --最小的字段号

    @total int, --记录总数

    @row_count int, --循环变量

    @temp_name varchar(100), --临时字段名

    @temp_pre_name varchar(100), --带字段类型前缀的变量

    @temp_type varchar(100), --临时字段类型

    @temp_value varchar(100), --临时字段值

    @xmlnode_value varchar(100), --xml的节点值

    @sql_name varchar(100), --sql操作相关的字段

    @sql_value varchar(100), --sql操作相关的字段值

    @sql nvarchar(200), --存储动态

    sql @pk_pre_name varchar(20) --带类型前缀的关键字段名

    set @sql_name = '';

set @sql_value = '';

set @row_count = 1;

set @pkname = 'id'; --关键字名称

set @tabname = 'course'; --操作的表名

set @optinfo = '';

 

select @id_i=id from inserted; select @id_d=id from deleted;

select @temp_type = data_type from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = @tabname and column_name = @pkname;

if (@temp_type = 'int')

 begin

  set @pk_pre_name = 'i' + @pkname

end

else if(@temp_type = 'float')

begin

  set @pk_pre_name = 'f' + @pkname

end

else if(@temp_type = 'decimal')

begin

  set @pk_pre_name = 'd' + @pkname

end

else if(@temp_type = 'datetime')

begin

  set @pk_pre_name = 'da' + @pkname

end

else

begin

  set @pk_pre_name = 'c' + @pkname

end

if @id_i is null and @id_d is not null --删除操作

begin

  set @pkvalue = @id_d;

  set @opttype = 1;

  --若变量的类型不是字符串型

  set @pkvalue = convert(varchar(200),@pkvalue);

   --生成执行删除操作的sql语句

  set @optsql = 'delete from ' + @tabname + ' where ' + @pkname + '=' + @pkvalue;

  --生成删除操作字段信息的xml表示

   set @optinfo = @optinfo + '';

  set @optinfo = @optinfo + @pkvalue;

  set @optinfo = @optinfo + '' + @pkname +'>';

end

else

begin

  set @pkvalue = @id_i;

   select * into temps from inserted;--这句必须写动态sql中时找不到inerted这个逻辑表的

  select @min_id = max(ordinal_position) from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = @tabname;

  select @total = count(1) from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = @tabname;

   while(@row_count

  begin

    select @temp_name = column_name,@temp_type = data_type from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = @tabname and                ordinal_position = @min_id;

    if(@temp_type = 'int')

    begin

      declare @temp_in int;

      SET @sql = 'select @temp_in = ' + @temp_name + ' from temps;';

      EXEC SP_EXECUTESQL @Sql, N'@temp_in int OUTPUT', @temp_in OUTPUT;

       set @xmlnode_value = convert(varchar(100),@temp_in);

      set @temp_value = @xmlnode_value;

      set @temp_pre_name = 'i' + @temp_name;

    end

万兴爱画
万兴爱画

万兴爱画AI绘画生成工具

下载

    else if(@temp_type = 'float')

    begin

      declare @temp_inf float;

      SET @sql = 'select @temp_inf = ' + @temp_name + ' from temps;';

      EXEC SP_EXECUTESQL @Sql, N'@temp_inf float OUTPUT', @temp_inf OUTPUT;

      set @xmlnode_value = convert(varchar(100),@temp_inf);

      set @temp_value = @xmlnode_value;

      set @temp_pre_name = 'f' + @temp_name;

    end

    else if(@temp_type = 'decimal')

    begin

      declare @temp_ind float;

      SET @sql = 'select @temp_ind = ' + @temp_name + ' from temps;';

      EXEC SP_EXECUTESQL @Sql, N'@temp_ind decimal(18,0) OUTPUT', @temp_ind OUTPUT;

      set @xmlnode_value = convert(varchar(100),@temp_ind);

      set @temp_value = @xmlnode_value;

      set @temp_pre_name = 'd' + @temp_name;

    end

    else

    begin

      declare @temp_inc varchar(200);

      SET @sql = 'select @temp_inc = ' + @temp_name + ' from temps;';

      EXEC SP_EXECUTESQL @Sql, N'@temp_inc varchar(200) OUTPUT', @temp_inc OUTPUT;

      set @xmlnode_value = convert(varchar(100),@temp_inc);

      set @temp_value = '''' + @xmlnode_value + '''';

      set @temp_pre_name = 'c' + @temp_name;

    end

    --生成插入/修改操作相关数据信息的xml表示

    set @optinfo = @optinfo + '';

    set @optinfo = @optinfo + @xmlnode_value;

    set @optinfo = @optinfo + '' + @temp_pre_name + '>';

    if @id_i is not null and @id_d is null -- 插入操作

    begin

      --生成插入操作执行的sql语句

      if(@temp_name @pkname)

      begin

        set @sql_name = @sql_name + ',' + @temp_name;

        set @sql_value = @sql_value + ',' + @temp_value;

      end

    end

    else if @id_i is not null and @id_d is not null --更新操作

    begin

      --生成修改操作执行的sql语句

      if(@temp_name @pkname)

      begin

        set @sql_name = @sql_name + ',' + @temp_name + '=' + @temp_value;

      end

    end

    select @min_id = ordinal_position from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = 'course' and ordinal_position

    set @row_count = @row_count + 1;

  end

  if @id_i is not null and @id_d is null -- 插入操作

  begin

    --生成执行插入操作的sql语句

    set @opttype = 0;

    set @optsql = 'insert into ' + @tabname + '(' + substring(@sql_name,2,len(@sql_name)) + ')' + ' values(' + substring(@sql_value,2,len               (@sql_value)) +')';

  end

  else if @id_i is not null and @id_d is not null --更新操作

  begin

    --生成执行修改操作的sql语句

    set @opttype = 3;

    set @optsql = 'update ' + @tabname + ' set ' + substring(@sql_name,2,len(@sql_name)) + ' where ' + @pkname + '=' + @pkvalue;

  end

drop table temps;

end

set @xmlstr = '';

set @xmlstr = @xmlstr + ''; set @xmlstr = @xmlstr + '' + convert(varchar(3),@opttype) + '';

set @xmlstr = @xmlstr + '' + @tabname + '';

set @xmlstr = @xmlstr + '' + @pk_pre_name + '';

set @xmlstr = @xmlstr + ''; set @xmlstr = @xmlstr + '';

set @xmlstr = @xmlstr + @optinfo;

set @xmlstr = @xmlstr + '';

set @xmlstr = @xmlstr + '';

select @optip=client_net_address from sys.dm_exec_connections where Session_id=@@spid;

if(@pkvalue is null)

begin

  set @pkvalue = -1;

end

insert into optlog values(@tabname,@pkname,@pkvalue,@opttype,@optip,getdate(),@optsql,@xmlstr);

print '操作执行成功';

end

 

红色标注的部分我认识是实现的难点,就是用到了sqlserver的系统存储过程sp_executesql,具体的用法网上有的可以查下,这只是我的一家之言,或许大家还有很好的实现,欢迎大家提意见啊!我知道这里很多大牛,可能我的想法会比较拙劣,但希望能够帮助到大家,只此记录我的技术成长历程。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
C++ 设计模式与软件架构
C++ 设计模式与软件架构

本专题深入讲解 C++ 中的常见设计模式与架构优化,包括单例模式、工厂模式、观察者模式、策略模式、命令模式等,结合实际案例展示如何在 C++ 项目中应用这些模式提升代码可维护性与扩展性。通过案例分析,帮助开发者掌握 如何运用设计模式构建高质量的软件架构,提升系统的灵活性与可扩展性。

14

2026.01.30

c++ 字符串格式化
c++ 字符串格式化

本专题整合了c++字符串格式化用法、输出技巧、实践等等内容,阅读专题下面的文章了解更多详细内容。

9

2026.01.30

java 字符串格式化
java 字符串格式化

本专题整合了java如何进行字符串格式化相关教程、使用解析、方法详解等等内容。阅读专题下面的文章了解更多详细教程。

12

2026.01.30

python 字符串格式化
python 字符串格式化

本专题整合了python字符串格式化教程、实践、方法、进阶等等相关内容,阅读专题下面的文章了解更多详细操作。

4

2026.01.30

java入门学习合集
java入门学习合集

本专题整合了java入门学习指南、初学者项目实战、入门到精通等等内容,阅读专题下面的文章了解更多详细学习方法。

20

2026.01.29

java配置环境变量教程合集
java配置环境变量教程合集

本专题整合了java配置环境变量设置、步骤、安装jdk、避免冲突等等相关内容,阅读专题下面的文章了解更多详细操作。

18

2026.01.29

java成品学习网站推荐大全
java成品学习网站推荐大全

本专题整合了java成品网站、在线成品网站源码、源码入口等等相关内容,阅读专题下面的文章了解更多详细推荐内容。

19

2026.01.29

Java字符串处理使用教程合集
Java字符串处理使用教程合集

本专题整合了Java字符串截取、处理、使用、实战等等教程内容,阅读专题下面的文章了解详细操作教程。

3

2026.01.29

Java空对象相关教程合集
Java空对象相关教程合集

本专题整合了Java空对象相关教程,阅读专题下面的文章了解更多详细内容。

6

2026.01.29

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Node.js 教程
Node.js 教程

共57课时 | 9.8万人学习

ASP 教程
ASP 教程

共34课时 | 4.2万人学习

【web前端】Node.js快速入门
【web前端】Node.js快速入门

共16课时 | 2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号