什么是存储过程?

时间:2009-01-19 22:33:25

标签: sql sql-server tsql stored-procedures

什么是存储过程?他们是如何工作的?什么是存储过程的构成(每个必须必须是存储过程的东西)?

17 个答案:

答案 0 :(得分:220)

存储过程是一批可以通过多种方式执行的SQL语句。大多数主要DBM都支持存储过程;然而,并非所有人都这么做您需要使用特定的DBMS帮助文档来验证具体细节。由于我最熟悉SQL Server,我将使用它作为我的样本。

要创建存储过程,语法非常简单:

CREATE PROCEDURE <owner>.<procedure name>

     <Param> <datatype>

AS

     <Body>

例如:

CREATE PROCEDURE Users_GetUserInfo

    @login nvarchar(30)=null

AS

    SELECT * from [Users]
    WHERE ISNULL(@login,login)=login

存储过程的一个好处是,您可以将数据访问逻辑集中到一个位置,然后DBA可以轻松优化。存储过程还具有安全性优势,因为您可以向存储过程授予执行权限,但用户不需要对基础表具有读/写权限。这是针对SQL注入的良好的第一步。

存储过程确实存在缺点,基本上是与基本CRUD操作相关的维护。假设每个表都有一个Insert,Update,Delete和至少一个基于主键的select,这意味着每个表将有4个过程。现在拿一个体面的400桌的数据库,你有1600个程序!而且假设你没有重复,你可能会。

使用ORM或其他方法自动生成基本CRUD操作的地方有很多优点。

答案 1 :(得分:139)

存储过程是一组预编译的SQL语句,用于执行特殊任务。

示例:如果我有Employee

Employee ID  Name       Age  Mobile
---------------------------------------
001          Sidheswar  25   9938885469
002          Pritish    32   9178542436

首先,我正在检索Employee表:

Create Procedure Employee details
As
Begin
    Select * from Employee
End

在SQL Server上运行该过程:

Execute   Employee details

--- (Employee details is a user defined name, give a name as you want)

然后,我将值插入员工表

Create Procedure employee_insert
    (@EmployeeID int, @Name Varchar(30), @Age int, @Mobile int)
As
Begin
    Insert Into Employee
    Values (@EmployeeID, @Name, @Age, @Mobile)
End

在SQL Server上运行参数化过程:

Execute employee_insert 003,’xyz’,27,1234567890

  --(Parameter size must be same as declared column size)

示例:@Name Varchar(30)

Employee表中,Name列的大小必须为varchar(30)

答案 2 :(得分:71)

存储过程是一组已创建并存储在数据库中的SQL语句。存储过程将接受输入参数,以便可以使用不同的输入数据通过网络在网络上使用单个过程。存储过程将减少网络流量并提高性能。如果我们修改存储过程,则所有客户端都将获得更新的存储过程。

创建存储过程的示例

CREATE PROCEDURE test_display
AS
    SELECT FirstName, LastName
    FROM tb_test;

EXEC test_display;

使用存储过程的优点

  • 存储过程允许模块化编程。

    您可以创建一次程序,将其存储在数据库中,并在程序中多次调用它。

  • 存储过程可以更快地执行。

    如果操作需要重复执行大量SQL代码,则存储过程可以更快。它们在首次执行时被解析和优化,并且存储过程的编译版本保留在内存高速缓存中供以后使用。这意味着每次使用都不需要重新分析和重新优化存储过程,从而大大加快了执行时间。

  • 存储过程可以减少网络流量。

    需要数百行Transact-SQL代码的操作可以通过执行过程中代码的单个语句来执行,而不是通过网络发送数百行代码。

  • 存储过程为您的数据提供更好的安全性

    即使用户没有直接执行过程语句的权限,也可以被授予执行存储过程的权限。

    在SQL Server中,我们有不同类型的存储过程:

    • 系统存储过程
    • 用户定义的存储过程
    • 扩展存储过程
  • 系统存储过程存储在master数据库中,并以sp_前缀开头。这些过程可用于执行各种任务,以支持系统表中的外部应用程序调用的SQL Server函数

    示例:sp_helptext [StoredProcedure_Name]

  • 用户定义的存储过程通常存储在用户数据库中,通常用于完成用户数据库中的任务。编码这些过程时不要使用 sp_前缀,因为如果我们首先使用sp_前缀,它将检查master数据库,然后它来到用户定义的数据库

  • 扩展存储过程是从DLL文件调用函数的过程。如今,不推荐使用扩展存储过程,因为最好避免使用扩展存储过程。

答案 3 :(得分:34)

通常,存储过程是“SQL函数”。他们有:

-- a name
CREATE PROCEDURE spGetPerson
-- parameters
CREATE PROCEDURE spGetPerson(@PersonID int)
-- a body
CREATE PROCEDURE spGetPerson(@PersonID int)
AS
SELECT FirstName, LastName ....
FROM People
WHERE PersonID = @PersonID

这是一个以T-SQL为重点的例子。存储过程可以执行大多数SQL语句,返回标量和基于表的值,并且被认为更安全,因为它们可以防止SQL注入攻击。

答案 4 :(得分:14)

想想这样的情况,

  • 您有一个包含数据的数据库。
  • 访问该中央数据库需要许多不同的应用程序,以及将来的一些新应用程序。
  • 如果要插入内联数据库查询以访问中央数据库,在每个应用程序的代码中单独进行,那么可能您必须在不同的应用程序代码中反复复制相同的查询。
  • 在这种情况下,您可以使用存储过程(SP)。使用存储过程,您将编写许多常见查询(过程)并将其与中央数据库一起存储。
  • 现在重复工作将永远不会像以前那样发生,数据访问和维护将集中完成。

注:

  • 在上述情况下,您可能想知道“为什么我们不能引入中央数据访问服务器与所有应用程序进行交互?是的。这将是一种可能的替代方案。但是,
  • SP与该方法的主要优点是,与具有内联查询的数据访问代码不同,SP是预编译语句,因此它们的执行速度更快。通信成本(通过网络)将是最小的。
  • 与此相反,SP会为数据库服务器增加一些负载。如果根据情况需要考虑,那么带有内联查询的集中式数据访问服务器将是更好的选择。

答案 5 :(得分:7)

存储过程主要用于在数据库上执行某些任务。例如

  • 从数据的某些业务逻辑中获取数据库结果集。
  • 在一次通话中执行多个数据库操作。
  • 用于将数据从一个表迁移到另一个表。
  • 可以调用其他编程语言,如Java。

答案 6 :(得分:5)

存储过程用于检索数据,修改数据和删除数据库表中的数据。每次要在SQL数据库中插入,更新或删除数据时,都不需要编写完整的SQL命令。

答案 7 :(得分:5)

存储过程只不过是一组编译成单个执行计划的SQL语句。

  1. 创建一次并多次调用
  2. 减少网络流量
  3. 示例:创建存储过程

    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    CREATE PROCEDURE GetEmployee
          @EmployeeID int = 0
    AS
    BEGIN
          SET NOCOUNT ON;
    
          SELECT FirstName, LastName, BirthDate, City, Country
          FROM Employees 
          WHERE EmployeeID = @EmployeeID
    END
    GO
    

    更改或修改存储过程:

    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    
    ALTER PROCEDURE GetEmployee
          @EmployeeID int = 0
    AS
    BEGIN
        SET NOCOUNT ON;
    
        SELECT FirstName, LastName, BirthDate, City, Country
        FROM Employees 
        WHERE EmployeeID = @EmployeeID
    END
    GO
    

    删除或删除存储过程:

    DROP PROCEDURE GetEmployee
    

答案 8 :(得分:3)

  • 存储过程是一个执行某些特定任务的一个或多个SQL语句的预编译集。

  • 应使用EXEC

  • 独立执行存储过程
  • 存储过程可以返回多个参数

  • 存储过程可用于实现transact

答案 9 :(得分:2)

&#34;什么是存储过程&#34;这里的其他帖子已经回答了。我将发布的是一种鲜为人知的使用存储过程的方法。它是grouping stored proceduresnumbering stored procedures

语法参考

enter image description here

根据{{​​3}}

; number

  

一个可选的整数,用于对同名的过程进行分组。可以使用一个DROP PROCEDURE语句将这些分组过程一起删除

示例

CREATE Procedure FirstTest 
(
    @InputA INT
)
AS 
BEGIN
    SELECT 'A' + CONVERT(VARCHAR(10),@InputA)
END
GO

CREATE Procedure FirstTest;2
(
    @InputA INT,
    @InputB INT
)
AS 
BEGIN
    SELECT 'A' + CONVERT(VARCHAR(10),@InputA)+ CONVERT(VARCHAR(10),@InputB)
END
GO

使用

exec FirstTest 10
exec FirstTest;2 20,30

<强>结果

this

另一种尝试

CREATE Procedure SecondTest;2
(
     @InputA INT,
    @InputB INT
)
AS 
BEGIN
    SELECT 'A' + CONVERT(VARCHAR(10),@InputA)+ CONVERT(VARCHAR(10),@InputB)
END
GO

<强>结果

  

Msg 2730,Level 11,State 1,Procedure SecondTest,Line 1 [Batch Start line 3]   无法创建程序&#39; SecondTest&#39;组号为2,因为数据库中当前不存在具有相同名称和组号1的过程。   必须首先执行CREATE PROCEDURE&#39; SecondTest&#39 ;; 1。

<强>参考

  1. enter image description here
  2. CREATE PROCEDURE with the syntax for number
  3. Numbered Stored Procedures in SQL Server - techie-friendly.blogspot.com
  4. <强>注意

    1. 对程序进行分组后,您无法单独删除它们。
    2. 此功能可能会在Microsoft SQL Server的未来版本中删除。

答案 10 :(得分:0)

存储过程是SQL语句和过程逻辑的命名集合,即编译,验证并存储在服务器数据库中。存储过程通常像其他数据库对象一样对待,并通过服务器安全机制进行控制。

答案 11 :(得分:0)

在DBMS中,存储过程是一组具有指定名称的SQL语句,这些名称以编译形式存储在数据库中,以便可以由多个程序共享。

使用存储过程可能会有所帮助

  1. 提供对数据的受控访问(最终用户只能输入或更改数据,但无法编写程序)

  2. 确保数据完整性(数据将以一致的方式输入)和

  3. 提高工作效率(存储过程的语句只需编写一次)

答案 12 :(得分:0)

简单,

存储过程存储程序,存储在数据库中的程序/函数。

每个存储的程序都包含一个由SQL语句组成的主体。该语句可以是由分号(;)字符分隔的多个语句组成的复合语句。

CREATE PROCEDURE dorepeat(p1 INT)
BEGIN
  SET @x = 0;
  REPEAT SET @x = @x + 1; UNTIL @x > p1 END REPEAT;
END;

答案 13 :(得分:0)

SQL Server中的存储过程可以接受输入参数并返回多个输出参数值;在SQL Server中,存储过程程序语句用于在数据库中执行操作并将状态值返回给调用过程或批处理。

在SQL Server中使用存储过程的好处

它们允许模块化编程。 它们允许更快的执行。 他们可以减少网络流量。 它们可以用作安全机制。

这是一个存储过程的示例,它接受参数,执行查询并返回结果。具体来说,存储过程接受BusinessEntityID作为参数,并使用它来匹配HumanResources.Employee表的主键以返回请求的员工。

> create procedure HumanResources.uspFindEmployee    `*<<<---Store procedure name`*
@businessEntityID                                     `<<<----parameter`
as
begin
SET NOCOUNT ON;
Select businessEntityId,              <<<----select statement to return one employee row
NationalIdNumber,
LoginID,
JobTitle,
HireData,
From HumanResources.Employee
where businessEntityId =@businessEntityId     <<<---parameter used as criteria
end

我从essential.com了解到这一点......它非常有用。

答案 14 :(得分:0)

存储过程将帮助您在服务器中创建代码。您可以传递参数并查找输出。

create procedure_name (para1 int,para2 decimal)
as
select * from TableName

答案 15 :(得分:0)

在“存储过程”中,语句仅写入一次,从而减少了客户端和服务器之间的网络流量。 我们还可以避免Sql注入攻击。

  • 如果您在应用程序中使用第三方程序 处理付款,此处数据库应仅公开 该第三方需要的信息和活动 授权,这样我们就可以通过设置 权限使用存储过程。
  • 表的更新仅应针对它所针对的表 但它不应该更新任何其他表,通过它我们可以实现 使用事务处理和错误处理实现数据完整性。
  • 如果要返回一个或多个数据类型的项目,则返回 最好使用输出参数。
  • 在存储过程中,我们将输出参数用于任何 需要退回。如果您只想退还一件物品 整数数据类型,则最好使用返回值。其实 返回值仅用于通知已存储的成功或失败 程序。

答案 16 :(得分:0)

前言:1992年,SQL92标准被创建并被Firebase DB普及。该标准引入了“存储过程”。

** 直通查询:一个字符串(通常以编程方式连接),其结果为语法正确的SQL语句,通常在服务器层上生成(使用PHP,Python,PERL等语言)。然后将这些语句传递到数据库中。 **

** 触发器:旨在响应通常用于强制数据完整性的数据库事件(通常是DML事件)而触发的一段代码。 **

解释什么是存储过程的最好方法是解释执行数据库逻辑的旧方法(即不使用存储过程)。

创建系统的传统方法是使用“传递查询”,并且可能在数据库中具有触发器。 几乎任何不使用存储过程的人都使用一种叫做“通过查询”的东西

根据现代的存储过程约定,触发器和“传递查询”一起成为了传统。

存储过程的优点是:

  1. 可以将它们作为存储过程的物理文本进行缓存 永不改变。
  2. 它们内置了针对恶意SQL的机制 注射。
  3. 仅需要检查参数中是否存在恶意SQL 注入可节省大量处理器开销。
  4. 最现代的数据库 引擎实际上会编译存储过程。
  5. 他们增加了 层之间的抽象度。
  6. 它们出现在同一位置 作为数据库进行处理,以实现更大的优化和 吞吐量。
  7. 可以测试后端的整个工作流程 没有客户端代码。 (例如, Transact SQL或MySQL中的CALL命令。
  8. 它们可以用来 增强安全性,因为可以利用它们来禁止 访问数据库的方式与 系统旨在工作。这是通过数据库用户完成的 许可机制。例如,您只能授予用户特权 执行存储过程,而不是SELECT,UPDATE等 特权。
  9. 不需要与触发器关联的DML层。 ** 使用一个触发器就可以打开一个DML层 处理器密集型**

总而言之,在创建新的SQL数据库系统时,没有很好的借口来使用直通查询。

值得一提的是,在已经使用触发器或传递查询的旧系统中使用存储过程是绝对安全的;这意味着从遗留程序到存储过程的迁移非常容易,并且这种迁移不需要长时间关闭系统。