﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-Junky's IT Notebook-随笔分类-Oracle</title><link>http://www.blogjava.net/junky/category/15022.html</link><description /><language>zh-cn</language><lastBuildDate>Tue, 19 Jun 2007 08:58:11 GMT</lastBuildDate><pubDate>Tue, 19 Jun 2007 08:58:11 GMT</pubDate><ttl>60</ttl><item><title>Oracle触发器</title><link>http://www.blogjava.net/junky/archive/2007/06/19/125048.html</link><dc:creator>junky</dc:creator><author>junky</author><pubDate>Tue, 19 Jun 2007 01:37:00 GMT</pubDate><guid>http://www.blogjava.net/junky/archive/2007/06/19/125048.html</guid><wfw:comment>http://www.blogjava.net/junky/comments/125048.html</wfw:comment><comments>http://www.blogjava.net/junky/archive/2007/06/19/125048.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junky/comments/commentRss/125048.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junky/services/trackbacks/125048.html</trackback:ping><description><![CDATA[<table cellSpacing=0 cellPadding=0 width="100%" border=0>
    <tbody>
        <tr>
            <td>
            <hr>
            <p>触发器的概念和类型<br>　　数据库触发器（database triggers）是响应插入、更新或删除等数据库事件而执行的过程。它定义了当一些数据库相关事件发生时应采取的动作。可用于管理复杂的完整性约束，或监控对表的修改，或通知其它程序，表已发生修改。它的类型有：语句级触发器，以及行级触发器，前者可以在语句执行前或执行后被触发。后者在每个触发语句影响的行触发一次。还有before和after触发的命令。在insert,update,和delete之前或之后执行，引用新旧值进行处理。如果需通过触发器设定插入行中的某列值，则为了访问&#8220;新(new)&#8221;值，需使用一个触发器before insert，使用after insert则不行。Instead of 触发器命令，使用它告诉oracle应执行什么操作。以上四种大类合成14种小类（略）。各种触发器的执行顺序如下： <br>　　⑴　　　如果有，最先执行语句级before触发器。 <br>　　⑵　　　每个insert，delete,update影响的行； <br>&nbsp;　　①　　如果有，最先执行行级before <br>&nbsp;　　②　　执行行的delete或update <br>&nbsp;　　③　　如果有,执行行级after触发器 <br>　　⑶　　　如果有,执行语句级after触发器 <br>　　<br>　　1、使用数据库触发器管理数据冗余性 <br>　　为了数据分析和制作报表的需要,用户在数据模型中加入了冗余数据，应使用触发器,以保证数据的完整性。 <br>　　冗余数据可以用规定的 for each row选项的before update触发器进行管理。update 命令可放在触发器中对所有需要更新的冗余数据进行更新,如客户表和订单表,订单表包括客户的订单和客户表的冗余信息,客户表(customer)的表结构:客户号(cu_no)、客户名(cu_name)、客户地址(cu_address)。订单表(order)的表结构:订单号(or_no),客户号(or_no)，客户名（cu_name），客户地址（cu_address）,当客户基表中的数据被更新时更新订单中的冗余列。语法如下： </p>
            <p>&nbsp;create or replace trigger bj_customer <br>&nbsp;before update on customer <br>&nbsp;for each row <br>&nbsp;begin <br>&nbsp;&nbsp;update order set <br>&nbsp;&nbsp;cu_no=:new.cu_no,<br>&nbsp;&nbsp;cu_name=:new.cu_name,<br>&nbsp;&nbsp;cu_address=:new.cu_addess,<br>&nbsp;&nbsp;where cu_no=:old.cu_no;<br>&nbsp;end; <br>　　<br>　　2、用触发器完成数据复制 <br>　　如果需求非常有限，可以用数据触发器从一个数据库中向另一个数据库复制数据，如果数据复制需求仅与数据的插入有关，当一条记录插入到一个数据库中的某个基表中时，用户还希望把这条记录插入到一个远程数据库中，需用create database link语句创建一条到远程数据库的连接，一旦创建了一条数据库连接后，就可以在基表上创建一个after insert触发器，以把每一条记录插入到远程数据库中。 <br>　　<br>　　（1）在脚本中创建数据库连接（database link）bj_ysd_remote基表作为数据库基表，Bj_ysd_local代表本地数据库上的源基表。 <br>　　<br>&nbsp;Creat database link remote(连接名) <br>&nbsp;Connect to bj(帐户) indentified by bj(密码) <br>&nbsp;Using ':2'; <br>　　<br>　　（2）复制记录 <br>　　<br>&nbsp;create or replace trigger trig_ysd<br>&nbsp;after insert on bj_ysd_local <br>&nbsp;for each row <br>&nbsp;begin <br>&nbsp;&nbsp;insert into <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#98;&#106;&#95;&#121;&#115;&#100;&#95;&#114;&#101;&#109;&#111;&#116;&#101;&#64;&#100;&#98;&#108;&#105;&#110;&#107;"><u><font color=#0000ff>bj_ysd_remote@dblink</font></u></a> remote <br>&nbsp;&nbsp;value(:new.x1,:new.x2,&#8230;&#8230;)/＊x1.x2代表字段名＊／ <br>&nbsp;end; <br>　　<br>　　（3）删除记录 <br>　　<br>&nbsp;create or replace trigger trig_ysd_del <br>&nbsp;after delete on bj_ysd_local <br>&nbsp;for each row <br>&nbsp;begin <br>&nbsp;&nbsp;delete from <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#98;&#106;&#95;&#121;&#115;&#100;&#95;&#114;&#101;&#109;&#111;&#116;&#101;&#64;&#100;&#98;&#108;&#105;&#110;&#107;"><u><font color=#0000ff>bj_ysd_remote@dblink</font></u></a> remote <br>&nbsp;&nbsp;where x1=:old.x1 <br>&nbsp;end; <br>　　<br>　　3、用数据库触发器完成瀑布式删除操作 <br>　　在某些情况下，当要删除一条记录时，该记录是与外键有关的另外一张基表上的记录时，这个删除操作必须在模型中进行传递，否则会出现大量的冗长数据，仍以cumstomer 和order基表为例，当从customer中删除一个客户时，order基表中所有相关记录也应当删除。 </p>
            <p>&nbsp;Create or replace trigger trig_cust <br>&nbsp;Before delete on　customer <br>&nbsp;For each row <br>&nbsp;Begin <br>&nbsp;&nbsp;Delete from order <br>&nbsp;&nbsp;Where cu_no=old.cu_no;<br>&nbsp;End; <br>　　<br>　　4、用触发器完成动态数据的操作 <br>　　在涉及如何实现动态库存的问题时，可用触发器解决。仓库有验收、出库、调拨、报废、退料、让售等这些数据必须与以前的库存相加减，才能完成动态库存操作。本文仅以验收单触发器为例，其它的结构雷同。它们涉及到两个基表：bi&shy;_ysd(验收单)，Bj_kcb(当前库存表)，前者的表结构（rq(日期)，ysdh(验收单号)， bjbm(备件编码)，yssl(验收数量)，ysdj(验收单价)），后者的表结构为（bjbm（备件编码）,dqkcl（当前库存量）,dqkcje（当前库存金额））触发器如下： <br>　　<br>&nbsp;create or replace trigger trig_ysd <br>&nbsp;after insert or update or delete on bj_ysd <br>&nbsp;for each row <br>&nbsp;&nbsp;declare rq1 varchar2(8);rq2 varchar2(8); <br>&nbsp;&nbsp;/*限于篇幅，yssl1,yssl2,ysdj1,ysdj2,bjbm1,bjbm2,ii声明略*/ <br>&nbsp;&nbsp;if inserting or updating then <br>&nbsp;&nbsp;&nbsp;rq1:=:new.rq;bjbm1:=:new.bjbm;yssl1:=:new.yssl; <br>&nbsp;&nbsp;&nbsp;ysdj1:=:new.ysdj; <br>　　<br>&nbsp;&nbsp;&nbsp;select count(*) into ii from bj_dqkcb <br>&nbsp;&nbsp;&nbsp;where bjbm=bjbm1; <br>　　<br>&nbsp;&nbsp;&nbsp;if　ii=0　then <br>&nbsp;&nbsp;&nbsp;&nbsp;insert　into　bj_dqkcb(bjbm,dqkcl,dqkcje) <br>&nbsp;&nbsp;&nbsp;&nbsp;value(bjbm1,yssl1,ysdj1); <br>&nbsp;&nbsp;&nbsp;else <br>&nbsp;&nbsp;&nbsp;&nbsp;update bj_dqkcb <br>&nbsp;&nbsp;&nbsp;&nbsp;set&nbsp;dqkcl=dqkcl+yssl1; <br>　　&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dqkcje=dqkcje+yssl1*ysdj1; <br>&nbsp;&nbsp;&nbsp;end if <br>&nbsp;&nbsp;end if <br>　　<br>&nbsp;&nbsp;if deleting or updating then <br>&nbsp;&nbsp;&nbsp;rq2:=:old.rq;<br>&nbsp;&nbsp;&nbsp;bjbm2:=:old.bjbm;<br>&nbsp;&nbsp;&nbsp;yssl2:=:old.yssl; <br>&nbsp;&nbsp;&nbsp;ysdj2:=:old.ysdj; <br>&nbsp;&nbsp;&nbsp;update&nbsp;bj_dqkcb <br>&nbsp;&nbsp;&nbsp;set&nbsp;dqkcb=dqkcl-yssl2; <br>&nbsp;&nbsp;&nbsp;&nbsp;dqkcje=dqkcje-yssl2*ysdj2 <br>&nbsp;&nbsp;end if; <br>&nbsp;end ; <br>　　<br>　　5、结束语 <br>　　数据库触发器在数据库开发有很广泛的应用，但经验表明，使用过多的触发器将降低整个数据库的性能。如果数据库触发器写得不好，它会很快破坏数据库的性能，因此，在适当的时候使用恰当的触发器显得非常重要。 </p>
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.blogjava.net/junky/aggbug/125048.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junky/" target="_blank">junky</a> 2007-06-19 09:37 <a href="http://www.blogjava.net/junky/archive/2007/06/19/125048.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Oracle数据导入导出imp/exp命令</title><link>http://www.blogjava.net/junky/archive/2006/09/09/68630.html</link><dc:creator>junky</dc:creator><author>junky</author><pubDate>Fri, 08 Sep 2006 16:43:00 GMT</pubDate><guid>http://www.blogjava.net/junky/archive/2006/09/09/68630.html</guid><wfw:comment>http://www.blogjava.net/junky/comments/68630.html</wfw:comment><comments>http://www.blogjava.net/junky/archive/2006/09/09/68630.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junky/comments/commentRss/68630.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junky/services/trackbacks/68630.html</trackback:ping><description><![CDATA[ Oracle数据导入导出imp/exp就相当于oracle数据还原与备份。exp命令可以把数据从远程数据库服务器导出到本地的dmp文件，imp命令可以把dmp文件从本地导入到远处的数据库服务器中。 利用这个功能可以构建两个相同的数据库，一个用来测试，一个用来正式使用。<br /> <br />执行环境：可以在SQLPLUS.EXE或者DOS（命令行）中执行，<br /> DOS中可以执行时由于 在oracle 8i 中  安装目录\ora81\BIN被设置为全局路径，<br /> 该目录下有EXP.EXE与IMP.EXE文件被用来执行导入导出。<br /> oracle用java编写，SQLPLUS.EXE、EXP.EXE、IMP.EXE这两个文件有可能是被包装后的类文件。<br /> SQLPLUS.EXE调用EXP.EXE、IMP.EXE所包裹的类，完成导入导出功能。<br /> <br />下面介绍的是导入导出的实例。<br />数据导出：<br /> 1 将数据库TEST完全导出,用户名system 密码manager 导出到D:\daochu.dmp中<br />   exp <a href="mailto:system/manager@TEST"><font color="#002c99">system/manager@TEST</font></a> file=d:\daochu.dmp full=y<br /> 2 将数据库中system用户与sys用户的表导出<br />   exp <a href="mailto:system/manager@TEST"><font color="#002c99">system/manager@TEST</font></a> file=d:\daochu.dmp owner=(system,sys)<br /> 3 将数据库中的表inner_notify、notify_staff_relat导出<br />    exp <a href="mailto:aichannel/aichannel@TESTDB2"><font color="#002c99">aichannel/aichannel@TESTDB2</font></a> file= d:\data\newsmgnt.dmp tables=(inner_notify,notify_staff_relat) 
<p> 4 将数据库中的表table1中的字段filed1以"00"打头的数据导出<br />   exp <a href="mailto:system/manager@TEST"><font color="#002c99">system/manager@TEST</font></a> file=d:\daochu.dmp tables=(table1) query=\" where filed1 like '00%'\"<br />  <br />  上面是常用的导出，对于压缩，既用winzip把dmp文件可以很好的压缩。<br />  也可以在上面命令后面 加上 compress=y 来实现。</p><p>数据的导入<br /> 1 将D:\daochu.dmp 中的数据导入 TEST数据库中。<br />   imp <a href="mailto:system/manager@TEST"><font color="#002c99">system/manager@TEST</font></a>  file=d:\daochu.dmp<br />   imp <a href="mailto:aichannel/aichannel@HUST"><font color="#002c99">aichannel/aichannel@HUST</font></a> full=y  file=file= d:\data\newsmgnt.dmp ignore=y <br />   上面可能有点问题，因为有的表已经存在，然后它就报错，对该表就不进行导入。<br />   在后面加上 ignore=y 就可以了。<br /> 2 将d:\daochu.dmp中的表table1 导入<br /> imp <a href="mailto:system/manager@TEST"><font color="#002c99">system/manager@TEST</font></a>  file=d:\daochu.dmp  tables=(table1) <br /> <br /> 基本上上面的导入导出够用了。不少情况要先是将表彻底删除，然后导入。<br /> <br />注意：<br /> 操作者要有足够的权限，权限不够它会提示。<br /> 数据库时可以连上的。可以用tnsping TEST 来获得数据库TEST能否连上。</p><p>附录一：<br /> 给用户增加导入数据权限的操作<br /> 第一,启动sql*puls<br /> 第二，以system/manager登陆<br /> 第三，create user 用户名 IDENTIFIED BY 密码 （如果已经创建过用户，这步可以省略）<br /> 第四，GRANT CREATE USER,DROP USER,ALTER USER ,CREATE ANY VIEW ,<br />   DROP ANY VIEW,EXP_FULL_DATABASE,IMP_FULL_DATABASE,<br />      DBA,CONNECT,RESOURCE,CREATE SESSION  TO 用户名字 <br /> 第五, 运行-cmd-进入dmp文件所在的目录, <br />      imp userid=system/manager full=y file=*.dmp<br />      或者 imp userid=system/manager full=y file=filename.dmp</p><p> 执行示例:<br /> F:\Work\Oracle_Data\backup&gt;imp userid=test/test full=y file=inner_notify.dmp</p><p>屏幕显示<br />Import: Release 8.1.7.0.0 - Production on 星期四 2月 16 16:50:05 2006<br />(c) Copyright 2000 Oracle Corporation.  All rights reserved.</p><p>连接到: Oracle8i Enterprise Edition Release 8.1.7.0.0 - Production<br />With the Partitioning option<br />JServer Release 8.1.7.0.0 - Production</p><p>经由常规路径导出由EXPORT:V08.01.07创建的文件<br />已经完成ZHS16GBK字符集和ZHS16GBK NCHAR 字符集中的导入<br />导出服务器使用UTF8 NCHAR 字符集 (可能的ncharset转换)<br />. 正在将AICHANNEL的对象导入到 AICHANNEL<br />. . 正在导入表                  "INNER_NOTIFY"          4行被导入<br />准备启用约束条件...<br />成功终止导入，但出现警告。</p><p><br />附录二：<br /> Oracle 不允许直接改变表的拥有者, 利用Export/Import可以达到这一目的.<br />  先建立import9.par,<br />  然后，使用时命令如下：imp parfile=/filepath/import9.par<br />  例 import9.par 内容如下：<br />        FROMUSER=TGPMS        <br />        TOUSER=TGPMS2     （注：把表的拥有者由FROMUSER改为TOUSER，FROMUSER和TOUSER的用户可以不同）           <br />        ROWS=Y<br />        INDEXES=Y<br />        GRANTS=Y<br />        CONSTRAINTS=Y<br />        BUFFER=409600<br />        file==/backup/ctgpc_20030623.dmp<br />        log==/backup/import_20030623.log</p><img src ="http://www.blogjava.net/junky/aggbug/68630.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junky/" target="_blank">junky</a> 2006-09-09 00:43 <a href="http://www.blogjava.net/junky/archive/2006/09/09/68630.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>