存储过程(学习笔记)

一、存储过程的概念。

解决上面的问题,我们可以使用一种叫做“存储过程”的数据库对象。 
存储过程(Stored Procedure)把我们经常用到的一串复杂sql语句保存成一个数据库对象,并给它起一个名字。每次使用存储过程只需要使用如下的形式即可:


 存储过程并不神秘,它就是批处理。之前提到视图是保存在服务器上的命名select语句,
   与之类似,存储过程是保存在服务器上的命名批处理,系统将预先对它进行编译。

 存储过程可以包含几乎所有的T-SQL语句,如数据存取语句、流程控制语句、错误处理
   语句等,使用起来弹性很大。 
 数据库中也存在着系统函数和用户定义函数这两种对象,用户定义函数的功能和存储过
   程很像,但是有一定的区别,我们将在后面的课程中介绍。

【存储过程的分类】

 系统存储过程 system stored procedure 前缀sp_ 例如sp_help sp、helpdb;

 扩展存储过程 extended stored procedure 前缀xp_ 例如xp_cmdshell 
 用户自定义存储过程 user-defined stored procedure 也就是我们自己创建的 


二、用户自定义存储过程的创建、修改、删除 

【创建存储过程】

【修改存储过程】



可以看到,修改存储过程的语法和创建的语法只差一个单词,把create换成alt即可。 

【删除存储过程】

drop proc 存储过程名 

我们还可使用management studio来管理存储过程,展开菜单树中的“可编程性”,在“存储过程”的子节点中可以进行各种操作。这里要说一下创建:当点击“新建存储过程”之后,会出现一个基于模板的创建语句。这时点击菜单中的“查询→指定模板参数的值”,即可弹出对话框来对模板进行设置,从而建立我们想要的存储过程。另外,点击菜单中的“视图→模板资源管理器”,可以看到SQL SERVER 2005为我们提供的各种SQL语句模板。模板的功能比较高级,有兴趣的同学务必自学一下。

【一个简单的例子】 
--插入一个以时间为用户名的用户 

create proc insUser 
as 
begin tran 
declare @username varchar(20) 
set @username=convert(varchar(8),getdate(),112) 
+replace(convert(varchar(10),getdate(),8),':','') 
if not exists(select * from yonghu where yonghuming=@username)     
  insert into yonghu values 
(@username,'111111','@163.com','新用户') 
commit tran --也可以写commit,但是建议不要去掉tran
 go 
然后使用exec执行这个存储过程: 
exec insUser

选中exec这一行,然后按F5快速地反复执行,你会发现在同一秒内只能插入一个用户。 这个存储过程一旦建立就不能再次执行这段代码了,可以把create改成alter来修改。 注意存储过程的代码中不能go语句,因为go是用来提交批的,一旦遇到go系统会认为这个存储过程的代码已经书写完毕,会提交create或者alter的批处理。如果希望在存储过程中执行另一个批处理,请把该批处理写成另一个存储过程并调用。

三、用户自定义存储过程的参数传递和返回值

【传递参数】




还记得我们前面做过的一个案例吗:


现在我们把它写成存储过程。这样我们每次都可以从一个指定表中提取我们想要的记录了



调用的方法: 




存储过程不使用exec也可以调用,但是不推荐这么做。存储过程参数的名字可以在调用时写出来,但是这是完全没必要的,所以@idvalue=10直接写成10就可以了。 

exec加不加括号效果不一样。加括号是执行sql语句,不加括号是执行存储过程。 

【返回值】 

1.以retrun返回,始终是整数值 

return只能返回整数,即使不显式写出“return 整数值”这样的语句,存储过程也会自动返回一个数值0表示成功。我们可以在发生错误时返回非0值,表示有错误发生。不要试图使用return返回一个在存储过程中处理的结果,比如姓名、生日之类的内容,因为它是整数,功能极为有限。我们只用它返回存储过程执行的状态就足够了。请看例子:



调用的方法:



2.以output参数返回数据 

output可以用来返回任何类型的数据,严格来说,它并不是一个“返回值”,而是一个能够被存储过程调用代码处看到的“外部变量”。这样说的原因看下面的例子就明白了: --通过id查询艺人的姓名和年龄 



在调用处,我们先定义了两个变量,然后我们以output的方式把两个变量传递给了存储过程。于是存储过程就可以看到这两个来自外部的变量了。那么存储过程中对这两个变量的一切修改都可以立刻体现到调用处的代码中,因为它修改的实际上就是调用处的两个变量。 

3.select语句的结果集 


如果在存储过程中执行了select语句并显示结果集(并不是使用select语句给变量赋值),那么这个结果集也可以看做是一种返回值(不能被批处理语句用,但是作为结果集可以被C#等编程语言使用)。


这种存储过程可以用来实现“带有参数的视图”,在上面【传递参数】中举出的例子就是。 

【存储过程的常用功能】 

从存储过程参数和返回值的用法我们可以看出,存储过程通常用来处理一些对数据库的更新操作、或者是按照特定的需要从数据库中查询信息,并以变量的形式(而不是结果集的形式)返回给调用处、或者是以结果集的形式返回,但并不能被调用处的语句所使用。我们可以使用return的数值来监控存储过程执行得是否顺利。 


【在Java中使用“带有参数的视图”】 

我们没法像使用视图那样从一个返回select结果集的存储过程中进行二度查询,那么它究竟应该如何使用,我们现在来举一个例子:



上面演示的是最基本的访问实例。可以看到,当这类存储过程没有参数的时候,调用的方法和一条普通select语句没有什么区别。但是当带有参数的时候就不一样了。不要着急,让我们回到存储过程的使用话题上面来。以后我们再学习Java如何调用带参数的存储过程。 

五、存储过程的嵌套调用 

在一个存储过程中还可以执行另一个存储过程,即嵌套调用。可以多次嵌套,但最多32层。可以用@@NESTLEVEL来查看嵌套当前层数:









六、系统存储过程 

系统存储过程是SQL SERVER 2005系统创建的存储过程,其作用是方便查询系统信息或完成系统管理任务。常用系统sp如下(更多内容查阅联机丛书):



七、存储过程的注意事项 

【存储过程的优点】

 只在创建时编译,执行速度快效率高  减少网络传输流量  提高安全性 
 模块式编程,可以重复使用 
 统一每次的操作流程 

【偷偷说一句】 

前面不管学什么都要提一下缺点,但是存储过程这里却没提。这并不意味着存储过程没有任何缺点,毕竟任何东西都不能滥用,但是可以看出来,存储过程的确是T-SQL编程的核心内容,是最重要的部分。而它本身又是如此地容易掌握,相信你现在的心情不错吧?

【在存储过程中使用事务】

存储过程中是可以使用事务的,这毫无疑问。在存储过程中使用事务不必用goto语句,在rollback或者commit语句之后直接return即可终止存储过程的执行。前面我们也提到过:在普通批处理中实际上也是可以使用return语句的。

 八、使用存储过程实现分页查询




 sp_executesql这个系统存储过程是另一种执行sql语句的方法。它比exec(@sql)的功
    能高级一些。在这里我们为它传入3个参数,分别是等待处理的@sql(必须是nvarchar类型的)、使用字符串为         @sql语句定义新的变量名、为字符串中定义的新变量赋值(@rc是字符串中定义的新变量,把它赋为@rowcount,     又因为希望通过@rc为@rowcount返回值,所以指定为output)。 
 ceiling函数得到大于某小数的最小整数,如ceiling(3.5)会得到4。这里把@rowcount
   和@pagesize相除,得到的数字是个小数。小数部分无法组成一个完整的分页但是不代表没有记录,所以使用             ceiling  函数,让@totalpages的值能够正确赋值。 
 当传入的currentpage并不在正确的分页编号范围内时,我们的代码做出了处理,给
    @currentpage赋了一个正确范围内的数值。


调用上面的存储过程:





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值