`
liss
  • 浏览: 825068 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

存储过程无法代替触发器的特殊情况

阅读更多

在这里先解释一下推崇用存储过程代替触发器的原因,当然这里先要说明一下此概念受教于ITPUB论坛的newkid版主的经验。

直接进入正题,绝大多数的由触发器提供的功能都可以用存储过程都能实现,而触发器是“隐式”执行,存储过程是“显式”执行,也就是说,当你对一个表进行操作的时候,存储过程出现于你的程序代码中,出现问题可以被发觉,而触发器是自动执行,如果它的出现了问题,你无法在代码中找到它,因而会给造成不必要的麻烦。这就是推荐用存储过程代替触发器的主要原因。

但是,也有一些存储过程无法代替触发器的特例,如果2个表双向都有外键约束,比如t1表有b_id是t2表的b_id的外键,而t2表的a_id则同时也是t1表a_id的外键,那么用触发器可以实现2个表的数据更新,用存储过程就没有办法做的,以下是对此做的一个实验:

---------------------------建表脚本------------------------------

CREATE TABLE t1
(
   a_id NUMBER PRIMARY KEY,
   b_id NUMBER
);


CREATE TABLE t2
(
   b_id NUMBER PRIMARY KEY,
   a_id NUMBER
);

-----------------------------为2个表加上外键-----------------------------------------
ALTER TABLE t1
ADD CONSTRAINT fk1
FOREIGN KEY(b_id)
REFERENCES t2(b_id);

ALTER TABLE t2
ADD CONSTRAINT fk2
FOREIGN KEY(a_id)
REFERENCES t1(a_id);

-------------------------触发器--------------------------------

CREATE OR REPLACE TRIGGER tri_row_ins_t
   after INSERT ON t1
      REFERENCING NEW AS n OLD AS o
   FOR EACH ROW
BEGIN
   INSERT INTO t2(b_id,a_id)
   VALUES(:n.b_id,:n.a_id);
END;


测试:
SQL> insert into t1 values(5,6);

1 row inserted

SQL> commit;

Commit complete


结论:触发器是在语句被编译后,约束条件被执行之前执行的,存储过程则没有办法在约束条件之前执行,所以会有这种无法使用存储过程代替触发器的特例,当然以上条件的出现情况也不常见

综上,再强调开头那一段思想,在你想到使用触发器的时候,再想一想怎样用存储过程来替代之是个比较好的习惯。

分享到:
评论

相关推荐

    数据库设计与优化.pdf

    外键作为数据库对象,很多人认为麻烦而不用,实际上,外键在大部分情况下是很有用的,理由是: 外键是最高效的一致性维护方法,数据库的一致性要求,依次可以用外键、CHECK 约束、规则约束、触发器、客 户端程序,...

    SQLServer2008查询性能优化 2/2

    9.8.3 使用sp_executesql编程以避免存储过程维护 252 9.8.4 实现准备/执行模式以避免重传查询字符串 253 9.8.5 避免即席查询 253 9.8.6 对于动态查询sp_executesql优于EXECUTE 253 9.8.7 小心地参数化查询的可变...

    SQLServer2008查询性能优化 1/2

    9.8.3 使用sp_executesql编程以避免存储过程维护 252 9.8.4 实现准备/执行模式以避免重传查询字符串 253 9.8.5 避免即席查询 253 9.8.6 对于动态查询sp_executesql优于EXECUTE 253 9.8.7 小心地参数化查询的可变...

    Delphi 5编程实例与技巧

    12.3.1 存储过程 252 12.3.2 触发器 252 12.4 本地缓存 253 第13章 Web与数据库 260 13.1 CGI的工作原理 260 13.2 Delphi对CGI的支持 260 13.3 创建Web应用程序 261 13.4 表单 262 13.5 把信息保存到数据库 264 13.6...

    mysql数据库的基本操作语法

    主键自增可以不插入,所以用null代替 指定列 insert into temp(name, age) values(‘jack’, 22); 在表面后面带括号,括号中写列名,values中写指定列名的值即可。当省略列名就表示插入全部数据, 注意插入值的...

    DELPHI 5编程实例与技巧

    12.3.1 存储过程 252 12.3.2 触发器 252 12.4 本地缓存 253 第13章 Web与数据库 260 13.1 CGI的工作原理 260 13.2 Delphi对CGI的支持 260 13.3 创建Web应用程序 261 13.4 表单 262 13.5 把信息保存到数据库 264 13.6...

    Oracle_Database_11g完全参考手册.part3/3

    第44章 JAVA存储过程 第Ⅶ部分 指南 第45章 Oracle数据字典指南 第46章 应用程序和SQL调整指南 第47章 SQL结果缓存和客户端查询缓存 第48章 关于调整的示例分析 第49章 高级体系结构选项——DB保险库、内容DB和记录...

    Oracle_Database_11g完全参考手册.part2/3

    第44章 JAVA存储过程 第Ⅶ部分 指南 第45章 Oracle数据字典指南 第46章 应用程序和SQL调整指南 第47章 SQL结果缓存和客户端查询缓存 第48章 关于调整的示例分析 第49章 高级体系结构选项——DB保险库、内容DB和记录...

    基于AT89S52 单片的频率计

    因此在仿真和程序调试时,关心的不再是某些语句执行时单片机寄存器和存储 器内容的改变,而是从工程的角度直接看程序运行和电路工作的过程和结果。 对于这样的仿真实验,从某种意义上讲,是弥补了实验和工程应用间...

    Access+2000中文版高级编程

    1.1 何时使用代码代替宏 4 1.1.1 何时用宏 4 1.1.2 何时用代码 4 1.2 宏到代码的转换 5 1.2.1 使用DoCmd对象 5 1.2.2 与宏命令等价的代码 7 1.3 将现有宏转换为代码 8 1.4 小 结 12 第2章 使用VBA...

    Access 2000中文版高级编程(part1)

    1.1 何时使用代码代替宏 4 1.1.1 何时用宏 4 1.1.2 何时用代码 4 1.2 宏到代码的转换 5 1.2.1 使用DoCmd对象 5 1.2.2 与宏命令等价的代码 7 1.3 将现有宏转换为代码 8 1.4 小 结 12 第2章 使用VBA编写代码 ...

    C#编程经验技巧宝典

    85 <br>0130 复制字符串中指定的字符 85 <br>0131 巧截字符串的数字 86 <br>0132 如何存储变长字符串 86 <br>0133 在进行字符串比较时忽略大小写 87 <br>0134 如何去除字符串尾空格 87 ...

Global site tag (gtag.js) - Google Analytics