目录
什么是存储过程?
存储过程是一组一个或多个数据库语句,存储在数据库的数据字典中,并从远程程序、另一个存储过程或命令行调用。存储过程通常称为SPROCS或SP。存储过程特征和命令语法特定于数据库引擎。传统上,Oracle使用PL/SQL作为其语言;而SQL Server使用T/SQL。
存储过程的主要部分
存储过程可以被认为有三个主要部分:
输入
存储过程可以接受参数值作为输入。根据参数的定义方式,可以将修改后的值传递回调用程序。
执行
存储过程可以执行SQL语句,利用条件逻辑(例如IF THEN或CASE语句)和lopping构造来执行任务。
存储过程能够调用另一个存储过程。
存储过程可以变得非常方便,因为它们可以通过游标操纵SQL查询的结果。游标允许存储过程逐行访问结果。实质上,您可以使用游标循环SQL语句的结果。这可能会降低数据库性能,因此要明智地使用游标!
输出
存储过程可以返回单个值,例如数字或文本值或结果集(行集)。此外,如上所述,根据输入的定义方式,输入的更改值可以传播回调用过程。
存储过程示例
下面是一个存储过程的示例,它接受参数,执行查询并返回结果。具体来说,存储过程接受BusinessEntityID作为参数并使用它来匹配HumanResources.Employee表的主键以返回所请求的员工。
虽然此示例返回单行,但由于我们匹配主键,因此存储过程也可用于返回多行或单个(标量)值。
可以从SQL Server中调用存储过程。要从SQL Server命令行或其他存储过程调用此存储过程,您将使用以下命令:
exec HumanResources.uspFindEmployee 3
也可以从编程语言中调用存储过程。每种语言(如PHP或C#)都有其特定的方法。
存储过程的好处
使用存储过程有几个好处。虽然封装在存储过程中编写的每个查询都没有意义,但使用它们有一些很好的理由。以下是经常提到的一些好处。
网络效率
存储过程可以包括许多命令并处理大量信息以获得期望的结果。通过将所有编程逻辑保留在服务器上,我们可以避免必须通过网络提取查询结果以由客户端程序处理。
封装业务逻辑
数据库可以处理许多客户端和调用程序。但是,数据库处理来自自定义程序(例如C#)和内置程序(例如Excel)的请求的情况并不少见。为了确保关键业务逻辑保持一致,在存储过程中在服务器上运行业务逻辑而不是依赖程序的每个版本来实现和正确执行规则是有意义的。
这有助于保持一致性,因为程序执行相同的逻辑。这也意味着数据的质量更好。
可维护性
当复杂的业务规则和编程逻辑集中到存储过程中时,它使更改变得更加容易。您只需要对存储过程进行更改,而不必在每个应用程序中搜索区域并进行更改。
一旦保存和编译,所有调用程序都将从更改中受益。同样,这可以帮助提高数据库的质量。
更强的安全性
您可以设置数据库安全性,以便应用程序只能通过存储过程调用访问和修改数据。不允许进行临时查询或直接访问表。
也可以委派安全访问权限。实际上,存储过程代码使用比调用者更高的访问凭证来执行。这意味着您不必为每个需要调用存储过程的用户提供所有访问权限。例如,在SQL Server中,您可以使用EXECUTE AS子句创建存储过程来模拟其他用户。
使用存储过程还有助于防止脚本注入攻击。任何输入参数都被视为文字值而不是可执行代码。这使得攻击者更难以尝试欺骗您的查询以执行意外操作。
缺点
使用存储过程有一些缺点,你会发现一些博客文章鼓励你不要使用它们。我认为值得一提的一些缺点包括:
可移植性
存储过程是使用供应商特定的语言编写的,这使得很难将它们从一个安装(如Oracle)转移到另一个安装(如SQL Server)。
测试
测试和调试存储过程可能很棘手。将调试工具放在一起以允许您逐步执行并跟踪存储过程可能更加困难。它肯定比早期更好,但仍然不像调试本机代码那么容易。
版本控制
跟踪存储过程所做的更改比使用本机源代码更难。与大多数本机代码IDE不同,将源代码控制集成到存储过程开发工具的方法并不多。因此,大多数版本控制活动仅限于将存储过程作为CREATE PROCEDURE脚本提取,然后手动导入版本控制系统。
我的个人经历
我觉得存储过程有它们的位置。我已经整理了一些广泛的应用程序,并使用存储过程进行所有CRUD操作。我认为使用存储过程插入和修改数据是一个非常好的主意。
我已经看到我编写的广泛使用存储过程的系统通过了安全测试,并且不太容易引发漏洞测试问题。
但是,即使在这些应用程序中,我发现您无法解决存储过程中的所有问题!我们已经组建了一些广泛的特别报告编写器,并且需要一种在客户端上生成SQL代码并将其呈现给服务器的方法。对于这些特殊情况,我不用存储过程。