定义

存储过程(Stored Procedure)是一种在数据库中存储复杂程序,以便外部程序调用的一种数据库对象。

存储过程是为了完成特定功能的SQL语句集,经编译创建并保存在数据库中,用户可通过指定存储过程的名字并给定参数(需要时)来调用执行。

你可以理解为其他编程语言中的函数或者子程序

优点

  1. 将重复性很高的一些操作,封装到一个存储过程中,简化了对这些SQL的调用
  2. 批量处理:可以直接批量运行存储过程中的多个SQL语句
  3. 提高速度:由于存储过程是先编译再执行的,同时可以批量执行语句,因此存储过程能够实现较快的执行速度并减少网络时间消耗
  4. 统一接口,同时将业务逻辑隐藏,确保数据的安全

缺点

  1. 存储过程,往往定制化于特定的数据库上,因为支持的编程语言不同。当切换到其他厂商的数据库系统时,需要重写原有的存储过程。
  2. 存储过程的性能调校与撰写,受限于各种数据库系统。

创建存储过程

创建存储过程的语法为:

-- 适用于SQL Server 与 Azure SQL Database

CREATE [ OR ALTER ] { PROC | PROCEDURE }
    [schema_name.] procedure_name [ ; number ]
    [ { @parameter [ type_schema_name. ] data_type }
        [ VARYING ] [ = default ] [ OUT | OUTPUT | [READONLY]
    ] [ ,...n ]
[ WITH <procedure_option> [ ,...n ] ]
[ FOR REPLICATION ]
AS { [ BEGIN ] sql_statement [;] [ ...n ] [ END ] }
[;]

<procedure_option> ::=
    [ ENCRYPTION ]
    [ RECOMPILE ]
    [ EXECUTE AS Clause ]

注意不同的数据库的语法可能会有些许不同。

看到这个语法是不是很复杂,但是不用担心,常用的参数其实很少。在这篇文章中我们不会介绍所有参数,所以想要了解所有参数可以查看官网文档:https://docs.microsoft.com/zh-cn/sql/t-sql/statements/create-procedure-transact-sql?view=sql-server-ver15

创建不带参数的存储过程

语法为:

create proc | procedure pro_name
as
    SQL_statements

其中pro_name为自定义的存储过程名称,SQL_statements为SQL语句。proc和procedure选择其中一个均可使用(proc是procedure的缩写)

例如创建一个存储过程,实现从student表中选取所有的数据

create proc proc_get_student
as
    select * from student; 

之后使用exec+存储过程名即可调用存储过程

exec proc_get_student

创建带参数的存储过程

创建带参数的存储过程首先要在存储过程中声明该参数,每个存储过程参数都必须用唯一的名称进行定义。与T-SQL变量相同,参数名必须以@为前缀,并且遵从标识符规则。当用户不提供该参数的值时可以使用一个默认值来代替。
创建带参数的存储过程的基本语句为:

create proc | procedure pro_name
    [{@参数数据类型} [=默认值] [output],
     {@参数数据类型} [=默认值] [output],
     ....
    ]
as
    SQL_statements

1.不带默认值的参数

创建一个参数不带默认值的存储过程,在调用该存储过程时,必须对存储过程中的所有参数进行赋值,如果有一个参数没有赋值,则无法调用该存储过程。例如:

use db_student
--创建存储过程
create procedure proc_group
@课程类别 varchar(20),  --定义参数
@学分 int 
as 
select * from course
where 课程类别=@课程类别 and 学分>@学分

执行不带参数的存储过程就是:

use db_student
exec proc_group '歌曲',8

如果不按顺序赋值可以写成:

use db_student
exec proc_group @学分=8,@课程类别=‘篮球课’

2.带默认值的参数

在SQL中我们可以对字段进行默认值的约束,在存储过程中也可以建立使用默认值的参数。只要在参数的定义之后加上等号,并在等号后面写出默认值即可。

--创建存储过程
use db_student
create procedure proc_group
@课程类别 varchar(20)='体育课',
@学分 int=6
as 
select * from course where 课程类别=@课程类别 and 学分>@学分

执行参数带默认值的存储过程

use db_student
exec proc_group @学分=8

带返回参数的存储过程

创建存储过程时,可以用output/out参数来创建一个带返回值的存储过程,例如:@a int output
如果创建带返回参数的存储过程proc_group,那么SQL语句如下:

--创建带返回值的存储过程
create procedure proc_group
@课程类别 varchar(20),
@平均学分 int output         --设置带返回值的参数
as 
select @平均学分=avg(学分) from course where 课程类别=@课程类别

执行带返回值的存储过程与普通的执行过程会有区别:

DECLARE @平均学分 int;
exec proc_group 'D', @平均学分 output
print (@平均学分)

创建存储过程的优化

存储过程是不允许重名的,所以有时我们会在创建存储过程的语句中加一个判断,如果已存在同名的存储过程则删除

if (exists (select * from sys.objects where name = 'proc_get_student'))
    drop proc proc_get_student
go
create proc proc_get_student
as
    select * from student;

修改存储过程

使用alter修改存储过程

alter proc proc_get_student
as
select * from student;

删除存储过程

drop proc proc_get_student

系统存储过程

系统存储过程是系统创建的存储过程,目的在于能够方便的从系统表中查询信息或完成与更新数据库表相关的管理任务或其他的系统管理任务。系统存储过程主要存储在master数据库中,以“sp”下划线开头的存储过程。尽管这些系统存储过程在master数据库中,但我们在其他数据库还是可以调用系统存储过程。有一些系统存储过程会在创建新的数据库的时候被自动创建在当前数据库中

exec sp_databases; --查看数据库
exec sp_tables;        --查看表
exec sp_columns student;--查看列
exec sp_helpIndex student;--查看索引
exec sp_helpConstraint student;--约束
exec sp_stored_procedures;--查看所有存储过程信息
exec sp_helptext 'sp_stored_procedures';--查看存储过程创建、定义语句
exec sp_rename student, stuInfo;--修改表、索引、列的名称
exec sp_renamedb myTempDB, myDB;--更改数据库名称
exec sp_defaultdb 'master', 'myDB';--更改登录名的默认数据库
exec sp_helpdb;--数据库帮助,查询数据库信息