没有找到合适的产品?
联系客服协助选型:023-68661681
提供3000多款全球软件/控件产品
针对软件研发的各个阶段提供专业培训与技术咨询
根据客户需求提供定制化的软件开发服务
全球知名设计软件,显著提升设计质量
打造以经营为中心,实现生产过程透明化管理
帮助企业合理产能分配,提高资源利用率
快速打造数字化生产线,实现全流程追溯
生产过程精准追溯,满足企业合规要求
以六西格玛为理论基础,实现产品质量全数字化管理
通过大屏电子看板,实现车间透明化管理
对设备进行全生命周期管理,提高设备综合利用率
实现设备数据的实时采集与监控
利用数字化技术提升油气勘探的效率和成功率
钻井计划优化、实时监控和风险评估
提供业务洞察与决策支持实现数据驱动决策
转帖|其它|编辑:郝浩|2008-07-16 10:41:32.000|阅读 528 次
概述:DBA:在生产环境中创建监控表DML的触发器
# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>
在生产环境中,总是可能出现这样的情况:某张或者某些表的数据被莫名其妙的修改了,但是很难定位出是哪个用户、哪个过程修改的。这是一个很让DBA头痛的事情(往往DBA对于整个代码逻辑并不是非常了解)。要定位出“问题”语句,有几种方法可以选择:log miner;细节粒度审计;触发器。Log miner要求要有归档日志(这个并非所有系统都可以做),而且需要有相当的磁盘空间,好处就是可以离线做;细节粒度升级能够根据条件记录下表的DML操作(9i及之前只能记录SELECT语句),比较复杂的FGA需要较高权限的用户来实现;触发器比较灵活,能够按照比较复杂的条件来记录需要的信息。下面介绍触发器如何实现。
要建立这样的触发器,需要利用到几张系统视图:v$session, v$sql, v$cursor,(10g, 9.2.0.1中可以,9.2.0.5, 9.2.0.之前存在bug)
SQL> connect "/ as sysdba"
grant select on SYS.V_$SQL to demo;
grant select on SYS.V_$SQL_BIND_DATA to demo;
grant select on SYS.V_$SQL_CURSOR to demo;
grant select on SYS.V_$SESSION to demo;
grant create trigger to demo;
CREATE TABLE trig_sql(lt DATE, sid NUMBER, SERIAL# NUMBER,
USERNAME VARCHAR2(30), OSUSER VARCHAR2(64),
MACHINE VARCHAR2(32), TERMINAL VARCHAR2(16),
PROGRAM VARCHAR2(64), sqlText VARCHAR2(2000),
status VARCHAR2(30));
方法1:
create or replace trigger ttt_trig
after insert or update on pga_ttt
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
begin
INSERT INTO trig_sql
select sysdate,s.SID, s.SERIAL#, s.USERNAME, s.OSUSER,
s.MACHINE, s.TERMINAL, s.PROGRAM, q.sql_text line,
'NONE'
from v$sql q, v$session s
where s.audsid=(select userenv('SESSIONID') from dual)
and s.prev_sql_addr=q.address
AND s.PREV_HASH_VALUE = q.hash_value;
COMMIT;
end;
方法2:
create or replace trigger ttt_trig
after insert or update on pga_ttt
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
begin
for cr in (select s.SID, s.SERIAL#, s.USERNAME, s.OSUSER,
s.MACHINE, s.TERMINAL, s.PROGRAM,
q.sql_text line, c.status stat
from v$sql q, v$sql_cursor c, v$session s
where s.audsid=(select userenv('SESSIONID') from dual)
and s.prev_sql_addr=q.address
AND c.STATUS = 'CURFETCH')
loop
INSERT INTO trig_sql VALUES(SYSDATE, cr.sid, cr.SERIAL#,
cr.USERNAME, cr.OSUSER, cr.MACHINE,
cr.TERMINAL, cr.PROGRAM, cr.line,
cr.stat);
end loop;
COMMIT;
end;
第一种方法是通过前一SQL的地址(pre_sql_addr)和HASH(prev_hash_value)值来定位出发trigger的语句的,不能用sql_address和hash_value来定位,否则获取到是触发器里面向日志表插入记录数据的语句本身了。
第二个方法是通过通过地址加游标的方法,按照视图各个字段的解释,应该是可以通过v$sql_cursor.parent_handle来定位的。但是通过测试发现,只有当前一条语句和查找前一条语句的语句在一个PLSQL块中的时候才有效,
SQL> set serveroutput on
SQL> declare
2 v_date date;
3 v_sql varchar2(2000);
4 begin
5 select sysdate into v_date from dual;
6
7 select q.sql_text into v_sql
8 from v$sql q, v$sql_cursor c, v$session s
9 where s.audsid=(select userenv('SESSIONID') from dual)
10 and s.prev_sql_addr=q.address and q.address=c.parent_handle;
11
12 dbms_output.put_line(v_sql);
13 end;
14 /
SELECT SYSDATE FROM DUAL
PL/SQL procedure successfully completed.
因为触发器本身是一个PLSQL块,所以总是无法获得正确语句,最后只有通过cursor的状态来获取。下面简单了解一下CURSOR各个状态的含义:
·CURNULL:游标已经存在,但没有任何SQL语句在使用它(即cache在每个session内存中的游标)
·CURSYNTAX:解析SQL语句过程的一个游标状态,说明调用游标的SQL语句语法正确,但是没有解析完成。
·CURPARSE:调用游标的语句解析完毕
·CURBOUND:游标使用了帮定变量,并定义好了帮定变量
·CURFETCH:游标执行完毕,并fetch了数据
·CURROW:游标正指向某一行
·ERROR:游标错误,一般是有BUG了。
当一条INSERT或者UPDATE语句执行以后才会触发触发器,所以这时候的游标状态是CURFETCH,我们这就通过状态为CURFETCH来定位。
本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@evget.com
文章转载自:赛迪网面对“数字中国”建设和中国制造2025战略实施的机遇期,中车信息公司紧跟时代的步伐,以“集约化、专业化、标准化、精益化、一体化、平台化”为工作目标,大力推进信息服务、工业软件等核心产品及业务的发展。在慧都3D解决方案的实施下,清软英泰建成了多模型来源的综合轻量化显示平台、实现文件不失真的百倍压缩比、针对模型中的大模型文件,在展示平台上进行流畅展示,提升工作效率,优化了使用体验。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
服务电话
重庆/ 023-68661681
华东/ 13452821722
华南/ 18100878085
华北/ 17347785263
客户支持
技术支持咨询服务
服务热线:400-700-1020
邮箱:sales@evget.com
关注我们
地址 : 重庆市九龙坡区火炬大道69号6幢
慧都科技 版权所有 Copyright 2003-
2025 渝ICP备12000582号-13 渝公网安备
50010702500608号