什么是存储过程
存储过程就是能完成一定操作的一组SQL语句。这里说的SQL语句是指ANSI SQL的扩展集T-SQL。
为什么要用存储过程
- 存储过程只在创造时进行编译,以后每次执行存储过程都不需再重新编译,而一般SQL语句每执行一次就编译一次,所以使用存储过程可提高数据库执行速度。
- 当对数据库进行复杂操作时,可将此复杂操作用存储过程封装起来与数据库提供的事务处理结合一起使用。
- 存储过程可以重复使用,可减少数据库开发人员的工作量。
- 安全性高,可设定只有某些用户才具有对指定存储过程的使用权。
存储过程的编写格式
use database_name
go
if exists (select * from sysobjects where id=OBJECT_ID(N'proc_name')
and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure proc_name
go
create procedure proc_name
as --这个as不能省略
begin --begin和end成对出现,可以省略
--balabala
end
return 0 --当然你可以在begin和end中间任何位置return
go
存储过程的局部变量和全局变量
全局变量的生存周期为变量定义处到程序末尾。
如果把整个存储过程看作一个函数,那么在存储过程里定义的全局变量就相当于函数的形参,接收从外部传入的实参。
全局变量的值一般是在调用存储过程的时候从外部传入,也可以在存储过程内部定义全局变量时赋值。相当于函数的默认参数。
输出参数,相当于C++的引用,在调用存储过程的时候需要在实参后面跟上一个output,类似于C++&符号的作用。
存储过程也可以有返回值,就跟调用函数返回一个值是类似的。
局部变量的生存周期为定义处到函数尾。
--带全局变量的
use database_name
go
create procedure proc_name
@global_variable_userid int, --多个全局变量之间用逗号分开,不能省略
@global_variable_nickname varchar(30) --最后一个全局变量跟as之间是不用加逗号的
as
begin
select * from table_name where userid=@global_variable_userid
end
go
--带全局变量且有默认值
use database_name
go
create procedure proc_name
@global_variable_userid int=666
as
begin
select * from table_name where userid=@global_variable_userid
end
go
--带全局变量且全局变量为输出参数
use database_name
go
create procedure proc_name
@a int output
as
begin
set @a = 666
end
go
--调用方式
declare @x int
exec proc_name @x output
print @x
--带局部变量的
use database_name
go
create procedure proc_name
as
declare @local_varible_id int
begin
declare @local_varible_name varchar(128)
--个人测试后发现,变量写在as和begin中间,或者写在begin和end中间都是局部变量
end
go
--带局部变量且想把局部变量输出出去
use database_name
go
create procedure proc_name
as
declare @local_varible_id int
begin
declare @local_varible_name varchar(128)
set @local_variable_name=(select name from table_person where id=@local_variable_id)
select @local_variable_name
end
go
存储过程的循环、分支、条件
--循环
declare @i int = 1
declare @sum int = 0
while @i <= 100
begin
set @sum += @i;
set @i += 1;
end
print @sum
--分支
if(1+1=2)
begin
print '对'
end
else
begin
print '错'
end
--条件
declare @today int
declare @week nvarchar(3)
set @today=3
set @week=case
when @today=1 then '星期一'
when @today=2 then '星期二'
when @today=3 then '星期三'
when @today=4 then '星期四'
when @today=5 then '星期五'
when @today=6 then '星期六'
when @today=7 then '星期日'
else '值错误'
end
print @week
存储过程的属性
use database_name
go
if exists (select * from sysobjects where id=OBJECT_ID(N'proc_name')
and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure proc_name
go
set QUOTED_IDENTIFIER on --这个不重要,反正你给存储过程取名字的时候不要跟关键字一样
go
set ansi_nulls on --只需知道会影响“跟空值做等或不等比较返回值真假”
create procedure proc_name
with encryption as --加密
set nocount on --不统计几行受影响
begin
select * from person(nolock) where id=1 --可以读那些修改后还没提交的数据(脏读)
end
return 0
go