关于oracle触发器操作的疑问

问题描述

首先说明我要实现的功能:假设A表和B表,我想实现,在增加A表的同时,利用刚刚插入的数据和A表中已有的数据(包括刚刚插入的数据)进行如数据编码(code)组合,生成一个新的字符串插入到B表中的编码列;我使用的Oracle客户端是PL/SQL devloper 8,我现在想到的方案:方案1:使用行触发器,在插入的时候使用new获取刚刚插入的数据,这样跟之前已经有的数据组合,但是这样当插入两条或多条的时候,会出现下一条总是无法和刚刚插入的数据组合,也就是不能发现同一批插入的数据;(按道理,两个SQL语句应该是两个事务,应该能使用刚刚插入的数据,这是第一个疑问,是不是客户端造成的,我的客户端设置是自动提交SQL,不应该有问题)方案2:在第一种方案不能满足需求,我寻求了第二种方案,就是建立一个全局临时表,然后使用行触发器把新插入的数据放到临时表中,再最后做一次语句触发器,在语句级触发器中使用游标遍历临时表记录,跟已经存在的数据进行组合,插入到B表中;(疑问2:在插入多条数据的时候,比如两个insert语句,行触发器在临时表新增一条数据,然后触发了一次语句级触发器,然后行触发器在临时表又新增一条数据,然后又触发了一次语句级触发器,跟我预想的应该是两次行触发器,一次最终语句级触发不一样,不知道是不是我理解的不对;按照我的理解,两个insert语句应该是两个事务,这样临时表只会保留一条记录,但是目前确实是多条;如果两条insert在一个事务内,为什么又多次触发语句级触发器?);目前解决方法就是在语句触发器最后增加一条删除临时表数据,这样保证临时表始终是最新插入的数据。代码如下: CREATE TABLE A  ( id number, name varchar2(30),birthdate date  ) ; -- B表 CREATE TABLE B  ( id number, name varchar2(30),birthdate date  ) ; -- 创建临时表 a_tt,存储刚刚插入的数据CREATE global temporary TABLE a_tt  (id number, name varchar2(30),birthdate date  ) ON COMMIT DELETE ROWS; --A表的行触发器记录新插入的数据create or replace trigger a_insert_row AFTER insert on A for each row declare begin insert into a_tt(id,name,birthdate) values(:new.id,:new.name,:new.birthdate); end;   create or replace trigger aaaa_insert_tt AFTER insert on A declare v_name aaaa_log.name%type; cursor n_cur is select name from a_tt; begin dbms_output.put_line('语句触发器执行'); for cur in n_cur loop dbms_output.put_line( cur.name); insert into B(name) select cur.name ||'_' ||name from A;end loop; -- delete from a_tt; --删除临时表过时数据 end; 测试语句: insert  into A  values(2,'a',sysdate);         insert  into A values(3,'b',sysdate); 预期结果:B表中name 列 2_2,3_2,3_3 希望各位大神,帮我理理思路,不知道我说清没有触发器执行的时候是不是在行触发器(after)之后提交数据,在语句级触发器就可以使用提交后的数据

解决方案

好像这样就能实现了吧,不用中间表吧create or replace trigger a_for_test before insert on a for each row declare cursor cur is select id as nm from a t;begin FOR i in cur LOOP insert into b (name, birthdate) values (i.nm || '_' || :new.id, sysdate); END LOOP; insert into b (name, birthdate) values (:new.id || '_' || :new.id, sysdate);end a_for_test;

时间: 2024-07-29 14:35:02

关于oracle触发器操作的疑问的相关文章

Oracle触发器简单实现

[oracle]触发器简单实现   目标:实现实时备份uertest表数据至usertest_temp中,两表结构一致 解决:用oracle触发器实现同步   结果:   1.建表   ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 [sql] -- 简单的用户表  create table USERTEST  (    NAME     VARCHAR2(20) not null,    AGE      NUMBER,    ISDELETE VARCHAR2(4

Oracle触发器用法实例详解_oracle

本文实例讲述了Oracle触发器用法.分享给大家供大家参考,具体如下: 一.触发器简介 触发器的定义就是说某个条件成立的时候,触发器里面所定义的语句就会被自动的执行.因此触发器不需要人为的去调用,也不能调用.然后,触发器的触发条件其实在你定义的时候就已经设定好了.这里面需要说明一下,触发器可以分为语句级触发器和行级触发器.详细的介绍可以参考网上的资料,简单的说就是语句级的触发器可以在某些语句执行前或执行后被触发.而行级触发器则是在定义的了触发的表中的行数据改变时就会被触发一次. 具体举例: 1.

Oracle数据操作和控制语言详解_oracle

正在看的ORACLE教程是:Oracle数据操作和控制语言详解.SQL语言共分为四大类:数据查询语言DQL,数据操纵语言DML, 数据定义语言DDL,数据控制语言DCL.其中用于定义数据的结构,比如 创建.修改或者删除数据库:DCL用于定义数据库用户的权限:在这篇文章中我将详细讲述这两种语言在Oracle中的使用方法.  DML语言 DML是SQL的一个子集,主要用于修改数据,下表列出了ORACLE支持的DML语句. 插入数据 INSERT语句常常用于向表中插入行,行中可以有特殊数据字段,或者可

oracle 触发器 实现出入库_oracle

用语言实现 好处: 1.可以减少对数据库的访问. 2.可移植性好. 坏处: 1.操作起来考虑的东西较多,修改一处就要修改别一处.也就是说是相互关联的.如果少改了某一处,很可能使数据不一致. 用触发器实现 好处: 1.可以使程序员从复杂的相互关联中解放出来,把精力放在复杂的业务上. 坏处: 1.可移植性差. 下面我就用一个例子实现一个简单的出入库.因为是例子表中所用到的字段很少.这里的例子只做为抛砖引玉. 数据表为入库金额表(以下简称入库表)income,出库金额表(以下简称出库表)outlay,

sql 触发器操作详解

触发器对表进行插入.更新.删除的时候会自动执行的特殊存储过程.触发器一般用在check约束更加复杂的约束上面.触发器和普通的存储过程的区别是:触发器是当对某一个表进行操作.诸如:update.insert.delete这些操作的时候,系统会自动调用执行该表上对应的触发器.SQL Server 2005中触发器可以分为两类:DML触发器和DDL触发器,其中DDL触发器它们会影响多种数据定义语言语句而激发,这些语句有create.alter.drop语句.   常见的触发器有三种:分别应用于Inse

Oracle触发器trigger详解_oracle

触发器相关概念及语法 概述 本篇博文中主要探讨以下内容: 什么是触发器 触发器的应用场景 触发器的语法 触发器的类型 案例 数据: 触发器的概念和第一个触发器 数据库触发器是一个与表相关联的,存储的PL/SQL 语句. 每当一个特定的数据操作语句(insert update delete)在指定的表上发出时,Oracle自动执行触发器中定义的语句序列. 举个简单的例子: 当员工表中新增一条记录后,自动打印"成功插入新员工" create or replace trigger inser

Oracle触发器6(建立系统事件触发器)

Oracle触发器6(建立系统事件触发器) (2012-02-14 09:23:36) 转载▼ <SCRIPT. $tag="触发器,建立,用于,事件,例程" $tag_code="64e2a8d9ae7359def02feebdbe14d783" $r_quote_bligid="71806002010108pu" $worldcup="0" var $worldcupball="0" ; <

Oracle如何操作XML

最近在研究Oracle PLSQL中对于XML的系列操作.结合工作中使用的知识和参考资料整理出以下相关内容: 一 如何生成XML文件: 1.使用dbms_xmlquery和utl_file内置包(scott用户执行) CREATE OR REPLACE DIRECTORY xml_dir AS 'd:\app\xml'; DROP SEQUENCE seq_filename; CREATE SEQUENCE seq_filename MINVALUE 10000 MAXVALUE 99999 I

使用Oracle触发器实现IP限制用户登录

在Oracle里,不像MySQL那样方便,可以直接在用户上进行IP限制,Oracle要实现用户级别的IP限制 ,可以使用触发器来迂回实现,下面是一个触发器的例子: create or replace trigger logon_ip_control after logon on database declare ip STRING(30); user STRING(30); begin SELECT SYS_CONTEXT('USERENV','SESSION_USER') into user