业务系统最终都会反馈到DB上,观察DB变化,可以知道业务系统的处理逻辑和处理方法。下面的代码,用来对MYSQL所有表建立触发器,结合JSP可以观察到DB的变化。附件是效果图。
引用
下面的SQL脚本,做两件事,生成存储记录变化的表,和生成触发器SQL的存储过程
drop TABLE if EXISTS zz_modify;
CREATE TABLE `zz_modify` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`content` text,
`createtime` datetime DEFAULT NULL,
`tablename` varchar(4000) DEFAULT NULL,
`oprtype` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
-- 存储过程,用来生成删除触发器的SQL。
drop PROCEDURE if EXISTS p_droptrgs;
CREATE PROCEDURE `p_droptrgs`()
BEGIN
-- 定义变量
declare tab_name varchar(400);
declare tmp_tabschema varchar(400) DEFAULT 'rmp_2';
declare v_sql_all text DEFAULT '';
declare cur_tab_done int DEFAULT 0;
-- 定义所有表的遍历游标
DECLARE cur_tab cursor for select table_name from information_schema.`TABLES` where TABLE_SCHEMA = tmp_tabschema and TABLE_NAME != 'zz_modify';
-- 将结束标志绑定到游标
declare continue handler FOR SQLSTATE '02000' SET cur_tab_done = 1;
-- 打开游标
OPEN cur_tab;
REPEAT
FETCH cur_tab into tab_name;
-- call p_createtrgsbytable(tmp_tabName, tmp_tabschema);
set v_sql_all = CONCAT(v_sql_all,'drop trigger if EXISTS trg_insert_', tab_name, '; \n');
set v_sql_all = CONCAT(v_sql_all,'drop trigger if EXISTS trg_update_', tab_name, '; \n');
set v_sql_all = CONCAT(v_sql_all,'drop trigger if EXISTS trg_delete_', tab_name, '; \n');
UNTIL cur_tab_done
end REPEAT;
CLOSE cur_tab;
select v_sql_all;
END;
drop FUNCTION if EXISTS f_createtrgsbytable;
CREATE FUNCTION `f_createtrgsbytable`(tab_name varchar(400), tab_schema varchar(400)) RETURNS text CHARSET utf8
DETERMINISTIC
BEGIN
-- 定义变量
declare tmp_col_name varchar(4000);
DECLARE v_sql_all longtext DEFAULT '';
declare v_sql_insert longtext DEFAULT '';
declare v_sql_update longtext DEFAULT '';
declare v_sql_delete longtext DEFAULT '';
declare cur_tab_done int DEFAULT 0;
-- 定义所有表的遍历游标
DECLARE cur_tab cursor for select COLUMN_NAME from information_schema.`COLUMNS` where table_name = tab_name and TABLE_SCHEMA = tab_schema;
-- 将结束标志绑定到游标
declare continue handler FOR SQLSTATE '02000' SET cur_tab_done = 1;
set v_sql_insert = CONCAT(v_sql_insert,'drop trigger if EXISTS trg_insert_', tab_name, ';');
set v_sql_update = CONCAT(v_sql_update,'drop trigger if EXISTS trg_update_', tab_name, ';');
set v_sql_delete = CONCAT(v_sql_delete,'drop trigger if EXISTS trg_delete_', tab_name, ';');
set v_sql_insert = concat(v_sql_insert, 'create trigger trg_insert_', tab_name, ' after insert on ', tab_name, ' for each row begin insert into zz_modify(content, createtime, tablename, oprtype) value(concat(');
set v_sql_update = concat(v_sql_update, 'create trigger trg_update_', tab_name, ' after update on ', tab_name, ' for each row begin insert into zz_modify(content, createtime, tablename, oprtype) value(concat(');
set v_sql_delete = concat(v_sql_delete, 'create trigger trg_delete_', tab_name, ' after delete on ', tab_name, ' for each row begin insert into zz_modify(content, createtime, tablename, oprtype) value(concat(');
-- 打开游标
OPEN cur_tab;
REPEAT
FETCH cur_tab into tmp_col_name;
set v_sql_insert = CONCAT(v_sql_insert, '\'#&old.', tmp_col_name, '=\',', '\'-\'', ',\'~new.', tmp_col_name, '=\',', 'IFNULL(new.', tmp_col_name, ', \'nu-ll\'),');
set v_sql_update = CONCAT(v_sql_update, '\'#&old.', tmp_col_name, '=\',', 'IFNULL(old.', tmp_col_name, ', \'nu-ll\') ,\'~new.', tmp_col_name, '=\',', 'IFNULL(new.', tmp_col_name, ', \'nu-ll\'),');
set v_sql_delete = CONCAT(v_sql_delete, '\'#&old.', tmp_col_name, '=\',', 'IFNULL(old.', tmp_col_name, ', \'nu-ll\') ,\'~new.', tmp_col_name, '=\',', '\'-\'', ',');
UNTIL cur_tab_done
end REPEAT;
CLOSE cur_tab;
-- 截取处理
set v_sql_insert = CONCAT(SUBSTRING(v_sql_insert,1,LENGTH(v_sql_insert) - 1), ') ,now(), \'', tab_name, '\', \'insert\' ); end;\n');
set v_sql_update = CONCAT(SUBSTRING(v_sql_update,1,LENGTH(v_sql_update) - 1), ') ,now(), \'', tab_name, '\', \'update\' ); end;\n');
set v_sql_delete = CONCAT(SUBSTRING(v_sql_delete,1,LENGTH(v_sql_delete) - 1), ') ,now(), \'', tab_name, '\', \'delete\' ); end;\n');
return CONCAT(v_sql_insert,v_sql_update,v_sql_delete);
END;
-- 执行存储过程,用来生成产生触发器的SQL。
drop PROCEDURE if EXISTS p_createtrgs;
CREATE PROCEDURE `p_createtrgs`()
BEGIN
-- 定义变量
declare tmp_tabName varchar(400);
declare tmp_tabschema varchar(400) DEFAULT 'rmp_2';
declare v_sql_all longtext DEFAULT '';
declare cur_tab_done int DEFAULT 0;
-- 定义所有表的遍历游标
DECLARE cur_tab cursor for select table_name from information_schema.`TABLES` where TABLE_SCHEMA = tmp_tabschema and TABLE_NAME != 'zz_modify';
-- 将结束标志绑定到游标
declare continue handler FOR SQLSTATE '02000' SET cur_tab_done = 1;
-- 打开游标
OPEN cur_tab;
REPEAT
FETCH cur_tab into tmp_tabName;
-- call p_createtrgsbytable(tmp_tabName, tmp_tabschema);
set v_sql_all = CONCAT(v_sql_all, f_createtrgsbytable(tmp_tabName, tmp_tabschema), '\n');
UNTIL cur_tab_done
end REPEAT;
CLOSE cur_tab;
select v_sql_all;
END;
引用
JSP脚本,用来观察数据变化
<!--首先导入一些必要的packages-->
<%@page import="java.text.MessageFormat"%>
<%@ page import="java.io.*"%>
<%@ page import="java.util.*"%>
<!--告诉编译器使用SQL包-->
<%@ page import="java.sql.*" %>
<%@ page import="com.mysql.*" %>
<!--设置中文输出-->
<%@ page contentType="text/html; charset=UTF-8"%>
<html>
<head>
<title>数据变动观察</title>
<link rel="shortcut icon" href="http://a.fsdn.com/con/img/sftheme/favicon.ico">
</head>
<body>
<div style="margin:10px;width:100%;heigth:50px;">
<a href="del_modify.jsp" style="margin:0 5 0 5;">清理所有数据 </a>
<a href="comp.jsp" style="margin:0 5 0 5;">查询数据变化</a>
</div>
<%
Connection con;
Statement stmt;
ResultSet rs;
//加载驱动程序,下面的代码为加载MySQL驱动程序
Class.forName("com.mysql.jdbc.Driver");
//注册MySQL驱动程序
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
//用适当的驱动程序连接到数据库
//String dbUrl = "jdbc:mysql://172.16.34.12:3306/cec?user=root&password=abcd1001&useUnicode=true&characterEncoding=UTF-8";
//String dbUser = "cec"; //用户名
//String dbPwd = "cec"; //密码
String dbUrl = "jdbc:mysql://192.168.9.139:3306/cec_yxt?user=root&password=abcd1001&useUnicode=true&characterEncoding=UTF-8";
String dbUser = "root"; //用户名
String dbPwd = "123456"; //密码
//建立数据库连接
con = java.sql.DriverManager.getConnection(dbUrl, dbUser, dbPwd);
//创建一个JDBC声明
stmt = con.createStatement();
//查询记录
rs = stmt.executeQuery("select id,content,createtime,tablename,oprtype from zz_modify");
//输出查询结果
int idx = 0;
while (rs.next())
{
String content = rs.getString("content");
String createtime = rs.getString("createtime");
String tablename = rs.getString("tablename");
String oprtype = rs.getString("oprtype");
out.println("<table border=1 width='80%' style='margin-left:auto;margin-right:auto;margin-top:10px;margin-bottom:10px;'>");
out.println(MessageFormat.format("<caption style='margin-top:10px;margin-bottom:10px;'>第【{0}】次表【{1}】在【{2}】被修改【{3}】。</caption>", ""+(++idx), tablename, createtime, oprtype));
if (content == null || "".equals(content))
{
//打印所显示的数据
out.println("<tr width='100%'>"
+ "<td width='100%'>没有获取到修改内容。</td>"
+ "</tr>");
}
else
{
// 打印 表头
out.println("<tr width='100%' style='word-break: break-all;'>"
+ "<th width='5%'> 表字段 </td>"
+ "<th width='20%'> 旧的值 </td>"
+ "<th width='10%'> 新的值 </td>"
+ "</tr>");
StringTokenizer st = new StringTokenizer(content, "#&");
while (st.hasMoreTokens())
{
String row = st.nextToken();
String[] rowarr = row.split("~");
String oldContent = rowarr[0];
String newContent = rowarr[1];
String fieldName = oldContent.substring(oldContent.indexOf('.') + 1, oldContent.indexOf('='));
String oldValue = oldContent.substring(oldContent.indexOf('=') + 1);
String newValue = newContent.substring(newContent.indexOf('=') + 1);
if (newValue.equals(oldValue))
{
//打印所显示的数据
out.println("<tr width='100%' style='word-break: break-all;'>"
+ "<td width='5%'>" + fieldName + "</td>"
+ "<td width='20%'>" + oldValue + "</td>"
+ "<td width='10%'>" + newValue + "</td>"
+ "</tr>");
}
else
{
//打印所显示的数据
out.println("<tr width='100%' style='word-break: break-all;color:red;'>"
+ "<td width='5%'>" + fieldName + "</td>"
+ "<td width='20%'>" + oldValue + "</td>"
+ "<td width='10%'>" + newValue + "</td>"
+ "</tr>");
}
}
}
out.println("</table>");
}
//关闭数据库连结
rs.close();
stmt.close();
con.close();
%>
</body>
</html>
引用
JSP脚本,用来删除记录表zz_modify中所有的数据的。
<!--首先导入一些必要的packages-->
<%@page import="java.text.MessageFormat"%>
<%@ page import="java.io.*"%>
<%@ page import="java.util.*"%>
<!--告诉编译器使用SQL包-->
<%@ page import="java.sql.*" %>
<%@ page import="com.mysql.*" %>
<!--设置中文输出-->
<%@ page contentType="text/html; charset=UTF-8"%>
<div style="margin:10px;width:100%;heigth:50px;">
<a href="del_modify.jsp" style="margin:0 5 0 5;">清理所有数据 </a>
<a href="comp.jsp" style="margin:0 5 0 5;">查询数据变化</a>
</div>
<%
Connection con;
Statement stmt;
ResultSet rs;
//加载驱动程序,下面的代码为加载MySQL驱动程序
Class.forName("com.mysql.jdbc.Driver");
//注册MySQL驱动程序
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
//用适当的驱动程序连接到数据库
//String dbUrl = "jdbc:mysql://172.16.34.12:3306/cec?user=root&password=abcd1001&useUnicode=true&characterEncoding=UTF-8";
//String dbUser = "cec"; //用户名
//String dbPwd = "cec"; //密码
String dbUrl = "jdbc:mysql://192.168.9.12:3306/cec_for_yxt_test?user=root&password=abcd1001&useUnicode=true&characterEncoding=UTF-8";
String dbUser = "cec"; //用户名
String dbPwd = "n2h@5B_AoP"; //密码
//建立数据库连接
con = java.sql.DriverManager.getConnection(dbUrl, dbUser, dbPwd);
//创建一个JDBC声明
stmt = con.createStatement();
//查询记录
stmt.execute("delete from zz_modify");
stmt.close();
con.close();
%>
![点击查看原始大小图片](http://dl2.iteye.com/upload/attachment/0113/4584/bc1a0a6b-faab-32d2-973d-b29d46b4186c-thumb.png)
- 大小: 27.8 KB
分享到:
相关推荐
水泥袋检测系统源码和数据集:改进yolo11-DCNV4
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
使用Plotly绘制散点图_柱状图_折线图_三维图_饼状图
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
光敏电阻接线图
MAX30102心率血样传感器原理图
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
胎儿脑部异常检测系统源码和数据集:改进yolo11-convnextv2
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
本项目为基于Kotlin语言的安卓Camera2拍照录像设计源码,总计包含48个文件,涵盖17个XML配置文件、10个WEBP图片文件、5个Kotlin源代码文件、3个Git忽略文件、3个Gradle配置文件、2个Markdown文档、2个属性文件、1个Gradle脚本文件、1个APK安装包以及1个JSON文件。该源码适用于实现安卓设备的拍照和录像功能。
【C#】设计模式大作业_pgj
本项目是一款基于ruoyi框架开发的校园后勤Vue前端设计源码,包含358个文件,涵盖122个Vue组件、93个SVG图标、87个JavaScript脚本、25个PNG图片、10个SCSS样式表、3个批处理脚本、3个JPG图片、2个HTML页面、2个JSON配置文件、2个备份文件。该代码适用于校园后勤管理系统,旨在提升校园后勤服务效率。
该项目是基于Spring Boot框架的校园外卖点餐系统设计源码,包含162个文件,包括142个Java源文件、16个XML配置文件、2个YML配置文件、1个Git忽略文件和1个XLSX文件。系统采用前后端分离架构,结合Mybatis、Spring Cache、阿里云OSS、Swagger、POI和WebSocket等技术,支持菜品、套餐、订单管理、支付、报表统计及用户催单等功能。系统分为后台管理端和用户端,用户端通过微信小程序实现。我的主要工作包括管理端员工及菜品信息的增删改查功能。
基于QT框架的OpenCV人脸识别
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
图像处理新思路:微生物菌落图像分割
该项目是一款基于Python核心的跨语言智能补全插件YouCompleteMe的设计源码,包含131个文件,涵盖57个Python文件、23个Vim配置文件、6个Markdown文件、5个C/C++源文件、3个YAML配置文件、3个文本文件以及少量其他类型的文件。该插件支持Python、C++、Shell、C等多种编程语言,旨在为开发者提供高效的代码补全功能。
英国MIDNORCO沉积物岩性数据集 内容: Fyfe, RM (2014) 发布的数据集详细记录了位于英国的MIDNORCO沉积物岩心的岩性特征。此数据集共包含12个数据点,提供了关于该地区地质结构的重要信息。通过访问以下链接可获取完整数据集:"" ()。这些数据对于研究古环境变化、地质年代测定以及了解地球历史具有重要意义。
内容: 本数据集记录了来自Filchner Trough的威德尔海豹(标记为FIL2014_wed_a_m_03)的潜水时长信息,由Bornemann H、Oosthuizen WC、Schröder M等人于2014年发布。该数据集包含了2033个数据点,提供了对单只威德尔海豹潜水行为的详细观察。通过访问以下链接可以获取完整的数据集详情:"" ()。这项研究有助于我们更好地理解威德尔海豹在南极海域中的生活习性与行为模式。
Matlab领域上传的视频是由对应的完整代码运行得来的,完整代码皆可运行,亲测可用,适合小白; 1、从视频里可见完整代码的内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作