触发器的概念和类?br> 数据库触发器Qdatabase triggersQ是响应插入、更新或删除{数据库事g而执行的q程。它定义了当一些数据库相关事g发生时应采取的动作。可用于理复杂的完整性约束,或监控对表的修改Q或通知其它E序Q表已发生修攏V它的类型有Q语句触发器,以及行触发器,前者可以在语句执行前或执行后被触发。后者在每个触发语句影响的行触发一ơ。还有before和after触发的命令。在insert,update,和delete之前或之后执行,引用新旧D行处理。如果需通过触发器设定插入行中的某列|则ؓ了访?#8220;?new)”|需使用一个触发器before insertQ用after insert则不行。Instead of 触发器命令,使用它告诉oracle应执行什么操作。以上四U大cd?4U小c(略)。各U触发器的执行顺序如下:
⑴ 如果有,最先执行语句before触发器?
c 每个insertQdelete,update影响的行Q?
① 如果有,最先执行行Ubefore
② 执行行的delete或update
③ 如果?执行行after触发?
⑶ 如果?执行语句Uafter触发?
1、用数据库触发器管理数据冗余?
Z数据分析和制作报表的需?用户在数据模型中加入了冗余数据,应用触发器,以保证数据的完整性?
冗余数据可以用规定的 for each row选项的before update触发器进行管理。update 命o可放在触发器中对所有需要更新的冗余数据q行更新,如客戯和订单表,订单表包括客L订单和客戯的冗余信?客户?customer)的表l构:客户?cu_no)、客户名(cu_name)、客户地址(cu_address)。订单表(order)的表l构:订单?or_no),客户?or_no)Q客户名Qcu_nameQ,客户地址Qcu_addressQ?当客户基表中的数据被更新时更新订单中的冗余列。语法如下:
create or replace trigger bj_customer
before update on customer
for each row
begin
update order set
cu_no=:new.cu_no,
cu_name=:new.cu_name,
cu_address=:new.cu_addess,
where cu_no=:old.cu_no;
end;
2、用触发器完成数据复?
如果需求非常有限,可以用数据触发器从一个数据库中向另一个数据库复制数据Q如果数据复刉求仅与数据的插入有关Q当一条记录插入到一个数据库中的某个中时Q用戯希望把这条记录插入到一个远E数据库中,需用create database link语句创徏一条到q程数据库的q接Q一旦创Z一条数据库q接后,可以在上创Z个after insert触发器,以把每一条记录插入到q程数据库中?
Q?Q在脚本中创建数据库q接Qdatabase linkQbj_ysd_remote作ؓ数据库基表,Bj_ysd_local代表本地数据库上的源?
Creat database link remote(q接?
Connect to bj(帐户) indentified by bj(密码)
Using ':2';
Q?Q复制记?
create or replace trigger trig_ysd
after insert on bj_ysd_local
for each row
begin
insert into bj_ysd_remote@dblink remote
value(:new.x1,:new.x2,……)/Qx1.x2代表字段名*Q?
end;
Q?Q删除记?
create or replace trigger trig_ysd_del
after delete on bj_ysd_local
for each row
begin
delete from bj_ysd_remote@dblink remote
where x1=:old.x1
end;
3、用数据库触发器完成瀑布式删除操?
在某些情况下Q当要删除一条记录时Q该记录是与外键有关的另外一张基表上的记录时Q这个删除操作必d模型中进行传递,否则会出现大量的冗长数据Q仍以cumstomer 和orderZQ当从customer中删除一个客hQorder中所有相兌录也应当删除?
Create or replace trigger trig_cust
Before delete on customer
For each row
Begin
Delete from order
Where cu_no=old.cu_no;
End;
4、用触发器完成动态数据的操作
在涉及如何实现动态库存的问题Ӟ可用触发器解冟뀂仓库有验收、出库、调拨、报废、退料、让售等q些数据必须与以前的库存相加减,才能完成动态库存操作。本文仅以验收单触发器ؓ例,其它的结构雷同。它们涉及到两个Qbi_ysd(验收?QBj_kcb(当前库存?Q前者的表结构(rq(日期)Qysdh(验收单号)Q?bjbm(备g~码)Qyssl(验收数量)Qysdj(验收单h)Q,后者的表结构ؓQbjbmQ备件编码),dqkclQ当前库存量Q?dqkcjeQ当前库存金额)Q触发器如下Q?
create or replace trigger trig_ysd
after insert or update or delete on bj_ysd
for each row
declare rq1 varchar2(8);rq2 varchar2(8);
/*限于幅Qyssl1,yssl2,ysdj1,ysdj2,bjbm1,bjbm2,ii声明?/
if inserting or updating then
rq1:=:new.rq;bjbm1:=:new.bjbm;yssl1:=:new.yssl;
ysdj1:=:new.ysdj;
select count(*) into ii from bj_dqkcb
where bjbm=bjbm1;
if ii=0 then
insert into bj_dqkcb(bjbm,dqkcl,dqkcje)
value(bjbm1,yssl1,ysdj1);
else
update bj_dqkcb
set dqkcl=dqkcl+yssl1;
dqkcje=dqkcje+yssl1*ysdj1;
end if
end if
if deleting or updating then
rq2:=:old.rq;
bjbm2:=:old.bjbm;
yssl2:=:old.yssl;
ysdj2:=:old.ysdj;
update bj_dqkcb
set dqkcb=dqkcl-yssl2;
dqkcje=dqkcje-yssl2*ysdj2
end if;
end ;
5、结束语
数据库触发器在数据库开发有很广泛的应用Q但l验表明Q用过多的触发器将降低整个数据库的性能。如果数据库触发器写得不好,它会很快破坏数据库的性能Q因此,在适当的时候用恰当的触发器显得非帔R要?
4 数据库中的表table1中的字段filed1?00"打头的数据导?br /> exp system/manager@TEST file=d:\daochu.dmp tables=(table1) query=\" where filed1 like '00%'\"
上面是常用的导出Q对于压~,既用winzip把dmp文g可以很好的压~?br /> 也可以在上面命o后面 加上 compress=y 来实现?/p>
数据的导?br /> 1 D:\daochu.dmp 中的数据导入 TEST数据库中?br /> imp system/manager@TEST file=d:\daochu.dmp
imp aichannel/aichannel@HUST full=y file=file= d:\data\newsmgnt.dmp ignore=y
上面可能有点问题Q因为有的表已经存在Q然后它报错,对该表就不进行导入?br /> 在后面加?ignore=y 可以了?br /> 2 d:\daochu.dmp中的表table1 导入
imp system/manager@TEST file=d:\daochu.dmp tables=(table1)
基本上上面的导入导出够用了。不情况要先是表d删除Q然后导入?br />
注意Q?br /> 操作者要有够的权限Q权限不够它会提C?br /> 数据库时可以q上的。可以用tnsping TEST 来获得数据库TEST能否q上?/p>
附录一Q?br /> l用户增加导入数据权限的操作
W一,启动sql*puls
W二Q以system/manager登陆
W三Qcreate user 用户?IDENTIFIED BY 密码 Q如果已l创用户Q这步可以省略)
W四QGRANT CREATE USER,DROP USER,ALTER USER ,CREATE ANY VIEW ,
DROP ANY VIEW,EXP_FULL_DATABASE,IMP_FULL_DATABASE,
DBA,CONNECT,RESOURCE,CREATE SESSION TO 用户名字
W五, q行-cmd-q入dmp文g所在的目录,
imp userid=system/manager full=y file=*.dmp
或?imp userid=system/manager full=y file=filename.dmp
执行CZ:
F:\Work\Oracle_Data\backup>imp userid=test/test full=y file=inner_notify.dmp
屏幕昄
Import: Release 8.1.7.0.0 - Production on 星期?2?16 16:50:05 2006
(c) Copyright 2000 Oracle Corporation. All rights reserved.
q接? Oracle8i Enterprise Edition Release 8.1.7.0.0 - Production
With the Partitioning option
JServer Release 8.1.7.0.0 - Production
l由常规路径导出由EXPORT:V08.01.07创徏的文?br />已经完成ZHS16GBK字符集和ZHS16GBK NCHAR 字符集中的导?br />导出服务器用UTF8 NCHAR 字符?(可能的ncharset转换)
. 正在AICHANNEL的对象导入到 AICHANNEL
. . 正在导入表 ?"INNER_NOTIFY" 4行被导入
准备启用U束条g...
成功l止导入Q但出现警告?/p>
附录二:
Oracle 不允许直接改变表的拥有? 利用Export/Import可以辑ֈq一目的.
先徏立import9.par,
然后Q用时命o如下Qimp parfile=/filepath/import9.par
?import9.par 内容如下Q?br /> FROMUSER=TGPMS
TOUSER=TGPMS2 Q注Q把表的拥有者由FROMUSER改ؓTOUSERQFROMUSER和TOUSER的用户可以不同)
ROWS=Y
INDEXES=Y
GRANTS=Y
CONSTRAINTS=Y
BUFFER=409600
file==/backup/ctgpc_20030623.dmp
log==/backup/import_20030623.log