【数据库系列】之存储过程与触发器

时间:2021-06-21 05:08:10

     

一、存储过程

定义:它是一组为了完成特定功能的SQL语句集,经过编译和优化后存储在数据库中,用户通过指定存储过程的名字并给出参数(如果这个存储过程带有参数的话)来执行,实现对表的增删改查

 (一)优点:

1、灵活性:

增强了SQL语言的功能和灵活性。可以用流控制语句编写,可以完成复杂的判断和较复杂的运算。

2、安全性:

  (1)保证数据的安全性。通过存储过程可以使没有权限的用户在控制之下间接地存取数据库而不必拥有直接操作基础表的权限,从而保证数据的安全。

  (2)数据库完整性。通过存储过程可以使相关的动作在一起发生,从而可以维护数据库的完整性。同时也可以避免对数据库操作出现错误,因为它是预编译的。

  (3)阻止 SQL 注入攻击。验证所有用户输入的参数化存储过程。如果使用动态 SQL,请确保将命令参数化,并绝对不能将参数值直接包括在查询字符串中。

  (4)封装数据逻辑和业务规则,用户可以仅通过开发人员和数据库管理员打算使用的方式访问数据和对象。

  (5)可禁止级联查询和数据修改。 这样将阻止用户恶意或无意中损坏数据或执行查询,以避免降低服务器或网络的性能。

  (6)过程代码中处理错误,而无需将错误直接传递给客户端应用程序。这样可防止返回错误消息,以避免其可能有助于探测攻击。 在服务器上记录错误并对其进行处理。

3、改善性能:

    运行存储过程前,数据库已对其进行了语法和句法分析,并给出了优化执行方案。这种已经编译好的过程可极大地改善SQL语句的性能。由于执行SQL语句的大部分工作已经完成,所以存储过程能以极快的速度执行。

4、降低网络的通信量:

    存储过程可以包含多条SQL语句,但只要用一条语句来执行该存储过程,从而减少了客户端应用程序对服务器的调用次数和长度。使体现企业规则的运算程序放入数据库服务器中,以便集中控制。当企业规则发生变化时在服务器中改变存储过程即可,无须修改任何应用程序。


(二)缺点:

1、调试麻烦

2、移植问题。

数据库端代码当然是与数据库相关的。

3、重新编译问题。

    因为后端代码是运行前编译的,如果带有引用关系的对象发生改变时,受影响的存储过程、包将需要重新编译(不过也可以设置成运行时刻自动编译)。

4、维护问题。

    如果在一个程序系统中大量的使用存储过程,到程序交付使用的时候随着用户需求的增加会导致数据结构的变化,接着就是系统的相关问题了,最后如果用户想维护该系统可以说是很难很难、而且代价是空前的。维护起来更加麻烦!

5、代码可复用性差。

    面向对象的思维在存储过程这毫无用武之地,两个很相似的功能在也需要两个存储过程,因为他们是互相独立的,可以互相调用,但是不能继承等面向对象的操作,这也就增加了代码量。

二、触发器

定义:通过事件进行触发而被执行,当对某一表在进行例如增删改的时候,SQL Server自动执行定义的一些SQL语句或者流程控制语句,从而确保对数据的处理符合由这些SQL语句定义的规则。 

(一)优点

1、实现由主键和外键所不能保证的复杂的参照完整性和数据的一致性

2、强化约束

触发器能够实现比CHECK 语句更为复杂的约束。

3、跟踪变化

触发器可以侦测数据库内的操作,从而不允许数据库中未经许可的指定更新和变化。

4、级联运行

    触发器可以侦测数据库内的操作,并自动地级联影响整个数据库的各项内容。例如,某个表上的触发器中包含有对另外一个表的数据操作(如删除,更新,插入)而该操作5、又导致该表上触发器被触发。

6、存储过程的调用

    为了响应数据库更新触,触发器可以调用一个或多个存储过程,甚至可以通过外部过程的调用而在DBMS( 数据库管理系统)本身之外进行操作。

7、实现高级形式的业务规则/复杂行为限制/定制记录。

触发器能够找出某一表在数据修改前后状态发生的差异,并根据这种差异执行一定的处理。

8、一个表的同一类型(Insert、Update、Delete)的多个触发器能够对同一种数据操作采取多种不同的处理。

(二)缺点

1、隐式存在,不易维护。

    无形中增加了系统的复杂性,因为它不执行根本感觉不到它的存在

2、级联关系不断追溯。

    涉及到复杂的逻辑的时候,触发器的嵌套是避免不了的,如果再涉及几个存储过程,再加上事务等等,很容易出现死锁现象,再调试的时候也会经常性的从一个触发器转到另外一个,级联关系的不断追溯,很容易使人头大。

3、性能比较低

    当运行触发器时,系统处理的大部分时间花费在参照其它表的这一处理上,因为这些表既不在内存中也不在数据库设备上,而删除表和插入表总是位于内存中。可见触发器所参照的其它表的位置决定了操作要花费的时间长短。

三、总结

触发器主要是通过事件进行触发而被执行的自动调用。而存储过程可以通过存储过程名字而被直接调用。触发器是一个隐藏的存储过程,因为它不需要参数,不需要显示调用。