精华内容
下载资源
问答
  • Oracle触发器的概念以及写法讲解

    千次阅读 2019-11-08 17:01:22
    1.触发器的概念: 触发器是存储在服务器中的程序单元,当数据库中某些事件发生时(比如insert\update\delete),数据库自动启动触发器,执行触发器中的相应操作。 (1) 触发器是一种特殊的存储过程,具备事务的功能...

    1. 触发器的概念:

    触发器是存储在服务器中的程序单元,当数据库中某些事件发生时(比如insert\update\delete),数据库自动启动触发器,执行触发器中的相应操作。

    (1) 触发器是一种特殊的存储过程,具备事务的功能;

    (2) 触发器不能被直接调用,而是由事件来触发;--例如:增删改

    (3) 触发器常用于加强数据的完整性约束和业务规则等。

    简单点说:触发器就是个开关,灯就是开关触发后的操作,触动了开关灯就亮了。

    2. 触发事件:

    Insert,update,delete,create(创建对象时),alter,drop

    logon/logoff(用户的登录或注销时执行触发器)

    startup/shutdown(数据库打开或关闭时执行触发器)

    3. 触发时间

    before 在指定的事件发生之前执行触发器

    after 在指定的事件发生之后执行触发器

    4. 触发级别

    4.1行级触发

    行触发:对触发事件影响的每一行执行触发器,即触发机制是基于行的。改一行数据,触发一次。

    该类型触发器将在insert\update\delete操作完成以后触发,即after。(也就是增删改都用after

    关键语句:for each row

    --案例2

    create or replace tirgger t_mydel

    after delete

    on stuinfo

    for each row

    begin

    dbms_output.put_line('删的好!');

    end;

    --执行(删除了一条记录,结果显示一条'删的好'

    delete from stuinfo where stuname='李文才';

    --执行(删除了整个表中的记录,显示N'删的好'

    delete from stuinfo

    --说明:这就是讲解行级触发器。

    --行级触发器:一条条的删,删一条就触发一个行级触发器。

    --语句级触发器:执行一条触发一次。

    4.2语句触发

    语句触发:对触发事件只能触发一次,而且不能该问受触发器影响的每一行的值。既无论这条SQL语句影响多少条记录,触发器都只触发一次。

    5. 创建触发器

    create [or replace] trigger trigger_name

    after|before|instead of --instead反向

    [insert][[or] update [of 列列表]][[or] delete]

    on table表或view

    [for each row] --行级模式

    Begin

    --pl/sql语句(begin...end)

    End;

    案例1

    --创建一个触发器tig_1,当用户删除scott.emp表中的数据时提示。

    SQL>create or replace trigger tig_1

    after delete

    on scott.emp //注意:这里没有用for each row,即不管删除多少条,只触发一次该触发器

    begin

    if deleting then

    dbms_output.put_line('有用户删除了emp表中的数据!');

    end if;

    end;

    案例2

    --创建一个触发器tig_2,当表scott.dept中的deptno列的值发生变化时,自动更新表scott.emp中的deptno列的值,从而保证数据的完整性。

    SQL>create or replace trigger tig_2

    after update

    on scott.emp

    for each row

    begin

    update scott.emp set deptno = :new.deptno

    where deptno = :old.deptno;

    end;

    注意:

    这段程序中有两个概念:new:old :new代表执行更新操作之后的新表,:old代表执行更新操作之前的旧表。

    通过这两张表的使用,可以访问到触发器执行前后表数据的变化。

    insert操作只有:newdelete操作只有:oldupdate操作二者皆有。

    :new :old只用于行级触发器。

    --:new表,将插入的数据先放入到:new表中,确认后放到要更新的表。

    --:old表,将不要的数据先放入到:old表中,确认不要了再清除:old表。

    --注意::new表和:old表中至始至终就只有一条数据,那请问有多少个列?触发器的表有多少个列,:new表和:old表就有多少个列。

    --案例:

    SQL>insert into emp values(…,张三,…,0,……);

    SQL>create or replace trigger trig_name

    after insert --插入操作之后

    on emp --emp表中

    for each row --行级模式

    begin

    if(:new.sal<=0) then --新表:new中的sal等于0

    dbms_output.put_line('警告:干活不能不给薪水');

    rollback;(可以用异常:抛异常后回滚数据)

    else

    dbms_output.put_line('已插入记录');

    commit;

    end if;

    end;

    6.触发器组成三部分:

    a. 触发器语句(事件)--定义激活触发器的DML事件和DDL事件;

    b. 触发器限制 --执行触发器的条件,该条件为真才能激活触发器;

    c. 触发器操作(主体)--包含SQL语句和代码,它们在发出了触发语句且触发限制的值为真是才运行。

    注示:序列通过前触发保存到数据库中。

    案例:在级联表中创建触发器案例

    --李斯文不能删

    (什么时候触发?a.delete; b.when 条件满足时; c.代码中写明)

    SQL>create or replace trigger t_studel

    after delete --删除操作之后

    on stuinfo

    for each row

    begin

    if :old.stuname='李斯文' then --如果:old表中存在李斯文,就提示不能删

    --抛出异常

    raise_application_error(-20010,'该学生不能删!!!');

    end if;

    end;

    SQL>delete from emp;

    --李斯文不能删也不能改

    只需修改上例代码中的:

    ……

    after delete or update

    ……

    --怎么知道是(insert\delete\update)哪个操作?不知道没关系,用case when语句

    ……

    begin

    case

    when deleting then

    --删除时

    if :old.stuname='李斯文' then

    raise_application_error(-20010,'该学生不能删!!!');

    end if;

    when updating then

    --修改时

    if :old.stuname='李斯文' then

    raise_application_error(-20011,'该学生不能修改!!!');

    end if;

    when inserting then

    --插入时

    if :new.stuname='张杨' then

    raise_application_error(-20012,'该学生你也敢招!!!');

    end if;

    end case;

    end;

    7.多表连接触发器

    stuinfo表中写个delete触发器,指定删除的人名,

    直接删除stumarks表中该人的成绩。

    create or replace tirgger t_mydel

    after delete

    on stuinfo

    for each row

    declare

    stu varchar2(22);

    begin

    stu:=:old.stuno; --将删除的学生的学号赋值给该变量

    delete from stumarks where stuno=stu;

    end;

    --运行下

    delete from stuinfo where stuname='李斯文';

    8. 触发器的应用(标识列)

    标识列:序列+触发器

    --解决:

    (1)建表

    create table tb_715(

    sid number,

    sname varchar2(22)

    )

    (2)创建序列

    create sequence seq715;

    (3)创建个触发器,用前触发,用new

    create or replace trigger t_insert

    before insert

    on tb_715

    for each row

    begin

    --新表中的id=序列的下一个值

    :new.sid:=seq715.nextval;

    end;

    *****************************************

    oracle 11g的语法:

    :new.sid:=seq715.nextval;

    oracle 10g的语法:

    select seq715.nextval into :new.sid from dual;

    别用变量,用变量的方法就是11g的写法。

    Oracle触发器分:前触发、后触发

     

    展开全文
  • sqlplus 中查看oracle触发器: 只能在命令窗口中查看,查看前,先使用set serveroutput on; 改变环境变量,以显示输出值;在命令窗口中输入相关的sql指令,测试; 如:  1 建测试表aa,create table AA( ...

    sqlplus 中查看oracle触发器:


    1. 只能在命令窗口中查看,查看前,先使用set serveroutput on; 改变环境变量,以显示输出值;
    2. 在命令窗口中输入相关的sql指令,测试;

    如:

        1  建测试表aa,create table AA(  A NUMBER);

        2 创建测试触发器

    create or replace trigger testa before insert on aa
     for each row
     declare
      aa number;
     begin

        dbms_output.put_line( :new.a);
        :new.a:=5;
        select t.port into aa from t_car t where t.id='aaa'; --肯定查不到值,报错
        :new.a := aa;
        exception
        WHEN OTHERS THEN return;
    end;

       3 在命令窗口中输入测试指令



    展开全文
  • 背景 项目遇到这样一个需求: 由于数据库是第三方系统的Oracle数据库,我们需要时刻同步该数据库中的告警记录表,并在我...2、在Oracle中编写触发器,实现告警表的行变化触发存储过程。 3、我们项目提供一个htt...

     背景

    项目遇到这样一个需求:  由于数据库是第三方系统的Oracle数据库,我们需要时刻同步该数据库中的告警记录表,并在我平台中存储或通知。鉴于这样的需求,考虑通过oracle 的 触发器加存储过程实现发送http请求的方案实现。

    方案

    1、在Oracle中编写存储过程,实现调用http接口。

    2、在Oracle中编写触发器,实现告警表的行变化触发存储过程。

    3、我们项目提供一个http接口供存储过程调用,并实现进一步定制操作。

    实现

    1、创建存储过程

    直接上代码

    在oracle 的sql执行窗口中执行  存储过程创建命令 

    create or replace PROCEDURE            "PRO_POSTREQ" ( guid in varchar2,res out  varchar2) as
    	begin
    		DECLARE
    		  req   UTL_HTTP.REQ;
    		  resp  UTL_HTTP.RESP;
    		  value VARCHAR2(1024);  -- URL to post to
    		  v_url VARCHAR2(4000) := 'http://127.0.0.1:8902/api/service/getservicestatus?uid='||guid;
    		  v_param VARCHAR2(4000) := '1';
    		  v_param_length NUMBER := LENGTHB(v_param);
    		BEGIN
    			DBMS_OUTPUT.ENABLE (buffer_size=>null);
    			req := UTL_HTTP.BEGIN_REQUEST (url=> v_url, method => 'POST');
    			UTL_HTTP.SET_BODY_CHARSET('UTF-8');
    			UTL_HTTP.SET_HEADER (r      =>  req,
    						   name   =>  'Content-Type',
    						   value  =>  'application/x-www-form-urlencoded');
    			UTL_HTTP.SET_HEADER(req, 'Keep-Alive', '  timeout=1');
    			UTL_HTTP.SET_HEADER (r      =>   req,
    							name   =>   'Content-Length',
    							value  =>   v_param_length);
    	 
    			UTL_HTTP.WRITE_RAW (r    => req,
    							data => UTL_RAW.CAST_TO_RAW(v_param)); 
    	 
    			resp := UTL_HTTP.GET_RESPONSE(req);
         
    		LOOP
    			UTL_HTTP.READ_LINE(resp, value, TRUE);
    			DBMS_OUTPUT.PUT_LINE(value);
    		END LOOP;
    			UTL_HTTP.END_RESPONSE(resp);
    		EXCEPTION
    		WHEN UTL_HTTP.END_OF_BODY THEN
    			UTL_HTTP.END_RESPONSE(resp);
    		END;
    	end PRO_POSTREQ;

    2. 创建触发器

    执行 存储过程创建命令

    create or replace TRIGGER "TR_AFTER_INSERT_EMPLOYEE" after insert or update  on TEST for each row
      declare res varchar2(2000);
    		begin
    			--PRO_POSTREQ(RTRIM(:new.SRVTRANSDATETIME),RTRIM(:new.CARDNO),RTRIM(:new.MID),RTRIM(:new.TRANAMT),RTRIM(:new.CARDKIND),RTRIM(:new.SRVSTAN));
          PRO_POSTREQ(:new.Name,res);
    		END TR_BEFORE_INSERT_EMPLOYEE;

    解释:

    1. => 是 Oracle 中调用 存储过程的时候,  指定 参数名进行调用。:= 是赋值语句。 = 是if的判断语句。

    2.触发器中的【:new】是 oracle PL/ sql的关键字。

    NEW关键字在什么情况下使用?
    ------最佳解决方案--------------------
    oracle默认的 用old代表老数据 new代表新数据 不过二者在使用时是有限制的
    insert时 只有new 没有old 
    delete时 只有old 没有new
    update时 二者都可用
    ————————————————

    3. 定义存储过程时,参数中 in/out 代表输出/输出参数。 varchar/varchar2不用指定参数长度。

    4. 触发器中res 的类型是varchar,此时就需要定义长度。

    5. 触发器和存储过程可以调试,F5 插入断点,点击 运行即可进行步进调试。

    调试与断点

    6.触发器中少了 for each row会抛出  NEW 或 OLD 引用不允许在表级触发器中错误

    3. 增加访问控制权限

    在调试和调用存储过程的访问http接口时 提示 HTTP 请求失败,网络访问被访问控制列表 (ACL) 拒绝。可执行如下代码:YONGHU是我当前的用户,一定要大写,不然会提示  ACL 无效:无法解析的主用户。

    --添加acl和权限控制(sql语句执行的方式来执行)
    	begin
    	  dbms_network_acl_admin.create_acl (       -- 创建访问控制文件(ACL)
    		acl         => 'utl_http.xml',          -- 文件名称
    		description => 'HTTP Access',           -- 描述
    		principal   => 'YONGHU',             -- 授权或者取消授权账号,大小写敏感
    		is_grant    => TRUE,                    -- 授权还是取消授权
    		privilege   => 'connect',               -- 授权或者取消授权的权限列表
    		start_date  => null,                    -- 起始日期
    		end_date    => null                     -- 结束日期
    	  );
    	 
    	  dbms_network_acl_admin.add_privilege (    -- 添加访问权限列表项
    		acl        => 'utl_http.xml',           -- 刚才创建的acl名称 
    		principal  => 'YONGHU',                    -- 授权或取消授权用户
    		is_grant   => TRUE,                     -- 与上同 
    		privilege  => 'resolve',                -- 权限列表
    		start_date => null,                     
    		end_date   => null
    	  );
    	 
    	  dbms_network_acl_admin.assign_acl (       -- 该段命令意思是允许访问acl名为utl_http.xml下授权的用户,使用oracle网络访问包,所允许访问的目的主机,及其端口范围。
    		acl        => 'utl_http.xml',
    		host       => '127.0.0.1',           -- ip地址或者域名,填写https://localhost:9000/hello与https://localhost:9000/是会报host无效的
    												-- 且建议使用ip地址或者使用域名,若用localhost,当oracle不是安装在本机上的情况下,会出现问题
    		lower_port => 8902,                     -- 允许访问的起始端口号
    		upper_port => Null                      -- 允许访问的截止端口号
    	  );
    	  commit;
    	end;

    4. 插入数据测试

    insert into test (id,name,value) values(1,'张三','zhangsan');
    insert into test (id,name,value) values(1,'李四','lisi');
    insert into test (id,name,value) values(1,'王五','wangwu');

    这样就成功收到 存储过程的http接口调用啦

    参考链接:

    通过oracle触发器调用存储过程发送http请求

    Oracle触发器中的NEW和Old关键字说明

     

     

    展开全文
  • Oracle触发器报错

    2018-09-27 15:16:00
    Oracle编写触发器时,执行时候报错,错误提示信息如上图所示,类似这种一般都是触发器语句有语法错误。重新审核语句,并再次执行。 如果用的是pl/sql developer的话,可以查看当前用户下的对象栏中的triggers,找到...

    Oracle编写触发器时,执行时候报错,错误提示信息如上图所示,类似这种一般都是触发器语句有语法错误。重新审核语句,并再次执行。

    如果用的是pl/sql developer的话,可以查看当前用户下的对象栏中的triggers,找到新编写的触发器。如果有错误,相应的触发器名称前面图标中有小红色X号。

     

    转载于:https://www.cnblogs.com/ray-bk/p/9713237.html

    展开全文
  • 5.4 在 PL/SQL 中使用 SQLCODE, SQLERRM异常处理函数 由于ORACLE 的错信息最大长度是512字节,为了得到完整的错误提示信息,我们可用 SQLERRM和 SUBSTR 函数一起得到错误提示信息,方便进行错误,特别是...
  • Oracle 触发器

    2020-05-31 15:34:47
    (Insert,update,delete)在指定的表上发出时, Oracle 自动地执行触发器中定义的语句序列。 触发器可用于: 数据确认,实施复杂的安全性检查,做审计,跟踪表上所做的数据操作等,数据的备份和同步 触发器,就是制定...
  • Oracle 触发器详解(trigger)

    千次阅读 2019-01-06 21:50:55
    文章目录1 概述2 触发器管理2.1 创建触发器2.1.1 for each row2.1.2 follows2.1.3 when2.2 查询触发器2.3 删除触发器2.4 常用属性2.4.1 inserting、updating、deleting2.4.2 now、old3 触发器分类3.1 DML 触发器...
  • Oracle触发器

    千次阅读 2018-08-18 13:52:35
    Oracle触发器 触发器是一个能够自动执行的PLSQL块。 当表的状态发生改变的时候,那么该表中对应的触发器就会自动触发,然后执行触发器中PLSQL块。 触发器监控表的记录是否 修改【insert、update、delete】 ...
  • 触发器和错误提示信息设置

    千次阅读 2020-04-13 06:41:06
    触发器:就是制定一个规则,在我们做增删改操作的时候,只要满足条件,自动触发,无需调用。 二.分类 语句级触发器:不包含for each row的就是语句级触发器。 行级触发器:包含for each row的就是行级触发器。 三.增...
  • 一、什么是触发器 前面已经介绍过存储过程,触发器和存储过程比较类似,它由PL/SQL编写并存储在数据库中,它可以调用存储过程,但触发器本身的调用和存储过程调用却是不一样的。存储过程由用户、应用程序、触发器或...
  • 每当一个特定的数据操作语句(insert、update、delete)在指定的表上发出时,Oracle自动地执行触发器中定义的语句序列。 二、如何创建触发器 create trigger saynewemp after insert on emp declare begin dbms_...
  • Oracle触发器用法详解

    2018-10-17 16:09:46
    Oracle触发器用法详解一、触发器简介二、触发器语法三、举例:1)、下面的触发器在更新表tb_emp之前触发,目的是不允许在周末修改表:2)、使用触发器实现序号自增3)、当用户对test表执行DML语句时,将相关信息记录到...
  • 对于编写的trigger,有dbms_output.put_line等输出语句存在时,执行相应代码触发trigger之后,没有信息输出,可能是系统的打印功能被lock了,需要解开,代码如下: set serveroutput on;
  • 从数据库(Oracle)触发器调用Java代码

    千次阅读 2017-11-29 15:39:14
    官方教程:https://docs.oracle.com/database/122/JJDEV/calling-Java-from-database-triggers.htm#JJDEV13286https://docs.oracle.com/cd/B19306_01/java.102/b14187/chthree.htm参考: ...
  • 触发器可以看做是一种“特殊”的存储过程,它定义了一些在数据库相关事件(如INSERT、UPDATE、CREATE等事件)发生时应执行的“功能代码块”,通常用于管理复杂的完整性约束,或监控对表的修改,或通知其他程序,甚至...
  • 什么是存储过程和函数?... 触发器是在触发一定事件的时候隐式执行的一段PL/SQL块,编译后作为一种数据库对象存储在数据字典中,只能被事件触发。  存储过程语法:  创建存储 过程 ,需 要有CREATE P...
  •  oracle通过var变量的方式存储新旧值  :new  :old 只能使用在行级触发器上  **/  syso('我删除了一行记录 班级名称是:'||:old.cname );    end;  delete from tb_grade where cid=3;  ...
  • oracle存储过程、函数、触发器和包

    千次阅读 2018-05-22 07:52:46
    要点:存储过程的创建带参数的存储过程的使用存储过程的管理函数的创建和使用触发器的类型和作用程序包的创建和使用存储过程1、存储过程的创建2、调用存储过程3、带参数的存储过程4、修改与删除存储过程5、查询存储...
  • 2)掌握存储过程,函数和触发器 3)了解一些oralceSQL语句优化方案 准备,再每次启动PLSQL,执行下面的sql col empno for 9999; col ename for a10; col job for a10; col mgr for 9999; col hiredate for a12...
  • oracle触发器

    2019-09-24 21:43:13
    1. 什么是触发器?  当用户满足某一条件(如:登陆数据库, insert, update, delete,create等等)时, 会引起某个存储过程的  自动执行, 我们把这个隐含被调用的存储过程就称为触发器. 2.触发器的分类  dml触发器 #...
  • 触发器,就是制定一个规则,在我们做增删改操作的时候, ----只要满足该规则,自动触发,无需调用。...----插入一条记录,输出一个新员工入职 create or replace trigger t1 after insert on person declare BEGIN
  • Oracle入门到实战

    万次阅读 多人点赞 2019-11-09 11:12:07
    Oracle学习:Oracle基础语句、Oracle表查询关键字、Oracle常用函数、Oracle常用结构
  • oracle 触发器

    2012-08-01 11:24:14
    Oracle 触发器 : 触发器是特定事件出现的时候,自动执行的代码块。类似于存储过程,但是用户不能直接调用他们。 功能: 1 、 允许 / 限制对表的修改 2 、 自动生成派生列,比如自增字段 3 、 强制...
  • 触发器 触发器组成 1、触发事件 DML或DDL语句。2、触发时间 是在触发事件发生之前(before) 还是之后(after) 触发3、触发操作 使用PL/SQL块进行相应的数据库操作4、触发对象 表、视图、模式、数据库5、触发...
  • 触发器,就是制定一个规则,在我们做增删改操作的时候, ----只要满足该规则,自动触发,无需调用。...----插入一条记录,输出一个新员工入职 create or replace trigger t1 after insert on person decl.

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 7,531
精华内容 3,012
关键字:

oracle触发器输出提示