码迷,mamicode.com
首页 > 数据库 > 详细

SQL存储过程

时间:2016-04-13 23:45:11      阅读:307      评论:0      收藏:0      [点我收藏+]

标签:

1.认识存储过程

  学完菜鸟上的SQL操作后打算好好深入下索引,然而学习过程中实际操作好多都是存储过程,所以只能先掌握存储过程再去深入索引了。使用存储过程有3个优点:存储过程是一个编译过的代码块,因此执行效率比t-sql高;使用存储过程可以不要写大量的t-sql语句,提高通信速率;通过存储过程能够使没有权限的用户在控制之下间接地存取数据库,保证数据的安全性。在SQL中存储过程分为系统存储过程和用户自定义存储过程,系统存储过程主要是以sp_为前缀的,下面是常用的系统存储过程,在我的sql里测试成功。

exec sp_databases;                      --查看数据库
exec sp_tables;                         --查看表
exec sp_helpindex myindex;              --查看索引
exec sp_stored_procedures;              --查看约束
exec sp_helptext sp_stored_procedures;--查看系统存储过程的具体代码
exec sp_rename mytable3,mytable5;       --修改表、索引、列的名称
exec sp_renamedb test,test1;            --修改数据库的名称
exec sp_helpdb test1;                   --查询数据库信息

 

 

 

当然本文的重点是我学校自定义存储过程的总结,接下来是就是很有意思的地方了。下面是创建存储过程的基本语法,我刚开始学的时候是不喜欢看这些基本语法的,但是使用上面的sp_helptext查看系统存储过程的代码你就知道基本结构很重要,再复杂的存储过程也就是在基本结构上展开的。第一行是创建存储过程,并赋予存储过程一个名字(procedure_name)。第二行是一个组标识,我们可以给多个存储过程设置为相同的一组,这样删除时就可以进行批量删除。第三行是声明变量,变量可以有一个或多个,@后加变量名,这个名字需要符合命名规范。OUTPUT说明这个参数是返回参数,这个参数可以返回给EXEC[UTE]。VARYING是指定作为输出参数支持的结果集,仅适用于游标参数,这个结果集是由存储过程动态构造,内容可以变化。第五行是一些附加选项,RECOMPILE表明SQL不会缓存该过程的计划,这个过程将在运行时重新编译,在使用非典型值或临时值而不希望覆盖缓存在内存中的执行计划时,可以使用这个选项。ENCRYPTION可加密syscomments表中包含create procedure语句文本的条目。FOR REPLICATION指定不可以在订阅服务器上执行复制创建的存储过程,使用FOR REPLICATION选项创建的存储过程可用作存储过程筛选,且只能在复制过程中执行,它不能和with recompile一起使用。AS后加上要执行的t-sql语句。

--创建存储过程,其中[]表示可选,{}表示必选
CREATE PROC [ EDURE ] procedure_name 
    [ ; number ]
    [ { @parameter data_type }[ VARYING ] [ = default ] [ OUTPUT ]]
    [ ,...n ]
    [ WITH { RECOMPILE | ENCRYPTION | RECOMPILE , ENCRYPTION }]
    [ FOR REPLICATION ]
AS sql_statement [ ...n ]

 2.存储过程的基本使用

  我新建了一个student表,下面是这个表的字段和我写的存储过程的代码。

技术分享

--查询数据表,并新增一条数据
create proc myproc
as
select * from student;
insert into student values(20131003,王五,14,,80);
go

exec myproc;
drop proc myproc;

--具有输入参数、输出参数和返回值,以及结果集的存储过程
create proc myproc
@pragender nvarchar(16),
@stuCount int output
as
if(@pragender=)
select @stuCount=SUM(stuNum) from student where gender=;
else
set @stuCount=0;
select * from student;
return @stuCount;
go

exec myproc ,null;
drop proc myproc;

--修改存储过程,输出stuCount变量,注意不能在一个存储过程中删除另一个存储过程,只能调用另一个存储过程
alter proc myproc
@stuCount int output
as
set @stuCount=9;
select @stuCount;
go

exec myproc null;
drop proc myproc;

--写完上面的例子后,可以看到都是以go结尾。go在存储过程中起结束作用,官网解释是go用信号通知SQL SERVER一批t-sql语句结束。
--简单点理解就是go标识着一组sql语句,两个go之间的sql语句作为一条批处理语句。go不是t-sql,不可和t-sql在同一行上。另外还有一个begin和end,可以将它们理解为C#中的花括号

--sql里还有一个print,它不属于函数,它可以打印出字符串或unicode字符串常量和任何有效的字符数据类型的变量。
--但是,这个变量的数据类型必须是char或varchar或者能隐私转换为char或varchar的数据类型。另外查资料时还发现了3个福利
--制表符 char(9)
--换行   char(10) 
--回车   char(13)
create proc myproc
as
print AAA+char(9)+AAA;
print AAA+char(10)+AAA;
print AAA+char(13)+AAA;
exec myproc;

--分页存储过程
if(OBJECT_ID(myproc,p) is not null)
    drop proc myproc
go
create proc myproc
(
@pageIndex int,
@pageSize int
)
as
    declare @startRow int,@endRow int;
    set @startRow=(@pageIndex-1)*@pageSize+1;
    set @endRow=@startRow+@pageSize-1;
    select * from (select *,ROW_NUMBER() over (order by stuNum asc) as number from student) t
    where t.number between @startRow and @endRow;

exec myproc 1,2;

对于分页存储过程我刚开始还有点晕,不过静下心来看就看懂了,对于select *,ROW_NUMBER() over (order by stuNum asc) as number from student;这条语句,我们可以直接执行看是什么效果,如下图。可以看到ROW_NUMBER这个函数在查到的数据表后新增了一列,并给这一列按从小到大赋值。分页时是根据这个number来进行分页的。

技术分享

3.存储过程结合事务

  当在存储过程中发生错误时可使用回滚保证数据的原子性,下面是我写得一个很简单的事务过程。

create proc myproc
(
@stuNum int
)
as
    set nocount on;  --设置nocount为on,表示不再返回统计信息,
    declare @myerror int;
    begin transaction 
        update student set stuName=张三 where stuNum=1;
        select @myerror=@@ERROR; --带2个@的是全局变量
        if @myerror !=0
            begin
                goto error_handler
            end
    commit transaction
    set nocount off
    return 0
    --处理错误,如果出现错误将进行事务回滚
    error_handler:
    rollback transaction
    set nocount off
    return @myerror
    go

 

SQL存储过程

标签:

原文地址:http://www.cnblogs.com/fangyz/p/5357520.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!