通常由触发器解决的常见问题时:在DEFFAULT不适用的情况下设置列的默认值。有两个典型例子:生成顺序混乱的序列的合成对象ID,以及填充基本的审计数据。在这些情况下使用触发器会有不同的功能上的优点。
1、创建测试表
--带有默认值列的表
create table test_trigger_tab2 (a varchar2(1),
create_dt date default sysdate,
create_by varchar2(30) default user);
--使用触发器的表
create table test_trigger_tab3 (a varchar2(1),
create_dt date ,
create_by varchar2(30) );
2、创建触发器
create or replace trigger test_trigger_tab3_bi
BEFORE insert on test_trigger_tab3
for each ROW
BEGIN
:NEW.create_dt:=sysdate;
:NEW.create_by:=user;
end;
3、执行测试,记录性能统计信息
select sessid; --查询的当前会话&session_id
create table mystat_start as select * from V$sesSTAT where sid = '&sessid';
BEGIN
for i in 1..10000 LOOP
insert into test_trigger_tab2(a) values ('X');
end loop;
end;
/
create table mystat_mid as select * from V$sesSTAT where sid = '&sessid';
BEGIN
for i in 1..10000 LOOP
insert into test_trigger_tab3(a) values ('X');
end loop;
end;
/
create table mystat_stop as select * from V$sesSTAT where sid = '&sessid';
4、查看性能差异
--查看比较
select ss1.id,
ss1.name,
ss1.stat_val as def_col_tab,
ss2.stat_val as tri_col_tab
from (
select * from mystat_start
minus
select * from mystat_mid
)ss1,(
select * from mystat_mid
minus
select * from mystat_stop
)ss2
where ss1.id = ss2.id;
测试结果显示,触发器造成的开销要更多。这一开销的全部都是与SQL和PLSQL之间的上下文切换相关。
由于某些安全审计的需要,涉及到数据插入需要记录用户和时间。此情况下,必须使用触发器而不是DEFAULT子句的最主要原因是默认值可以被覆盖,而触发器则永远会存入正确的数据,而不管insert语句传递的值是否正确。
5、测试插入
insert into test_trigger_tab3 values ('W',sysdate-300,'AAA');
insert into test_trigger_tab2 values ('W',sysdate-300,'AAA');
select * from test_trigger_tab3 where A ='W';--触发器表
select * from test_trigger_tab2 where A ='W';--默认值表
6、达梦数据库引入强制访问控制,在一定程度上满足个人安全的功能。SYSSSO用户下创建策略(非安全版无法使用)
将策略应用在一个表上时,就使该表处于一定的等级、范围和组内。一个表上可以应用多个策略,
但一个策略对表只能应用一次。
对表应用策略时,会在表上新建一个标记列,用于记录标记,新建的标记列名必须和表中已有列名
不同,同时还可以指定初始的标记值,以及是否将标记列设置为隐藏列。
使用下述系统过程对表应用策略:
VOID
MAC_APPLY_TABLE_POLICY(
POLICY_NAME VARCHAR(128),
SCHEMANAME VARCHAR(128),
TABLENAME VARCHAR(128),
COLNAME VARCHAR(128),
LABELVALUE VARCHAR(4000),
OPTION INT --1:开启隐藏
);
参数说明:
POLICY_NAME 应用于指定表的策略名
SCHEMANAME 表所属模式名称
TABLENAME 策略所应用的表名称
COLNAME 用于记录标记的列名称
LABELVALUE 用于说明被应用了策略的表中,已有元组的等级、范围和组
OPTION 1 代表隐藏标记列,0 代表不隐藏标记列,缺省为 0
使用说明:
该过程只能由具有 LABEL_DATABASE 的用户调用;
指定策略必须存在;
策略不能应用在系统表、临时表、HUGE 表、水平分区表、物化视图、含有聚集主键的表、含
有位图连接索引的表、含有位图索引的表上;
例如,将策略 P_04 应用于 PRODUCTION 模式中 PRODUCT 表,指定标记列为 LABEL_COL,
不隐藏标记列。
MAC_APPLY_TABLE_POLICY ('P_04', 'PRODUCTION', 'PRODUCT', 'LABEL_COL', 'L_01::',0);
过程中的 OPTION 参数用来指定该标记列是否隐藏。若对表应用策略时指定新增的这一列隐藏,
那么对表进行 INSERT 数据时,如果未指定标记列的列名,就不能对这一列插入数据,如果对
其插入数据,则会出错;如果指明具体的列来插入数据,这一列是允许插入数据的。