ms sql server中存储过程入门教程详解

作者:袖梨 2022-06-29

一、存储过程的概念

T-SQl和C语言一样 ,是一门结构化的语言。

什么是存储过程?

  存储过程是SQL查询语句与控制流程语句的预编译集合,并以特定的名称保存在数据库中。存储过程也是数据库对象

分类:

  系统存储过程: 以sp_或xp_打头

   用户自定义  :以proc_打头

存储过程的优点:

  执行速度快 效率高

  模块式编程 

  减少网络流量

    提高安全性

二、系统存储过程

SQl server 的系统存储过程保存在master数据库中,且所有命名的系统存储过程命名以“Sp_”开头。在master数据库中,

系统存储过程数量如下:

 代码如下 复制代码

select  count([name])as '系统存储数量' from  sysobjects

  where [name] like 'sp_%'


EXECUTE 用来表示调用存储过程,也可以缩写为EXEC,

调用存储的语法如下:

EXECUTE ‘存储过程名’   ‘参数’      ---如果没有参数则省略参数

常用的系统存储过程

EXEC sp_databases 列出当前系统中的数据库
EXEC  sp_renamedb 'Northwind','Northwind1'  修改数据库的名称(单用户访问)
USE stuDB GO EXEC sp_tables  返回某个表列的信息
EXEC sp_columns 查看指定列的信息
EXEC sp_help  查看某个表的所有信息
EXEC sp_helpconstraint '表名'  查看某个表的约束
EXEC sp_helpdb '数据库名' 或 EXEC sp_helpdb  查看指定数据库或所有数据库信息
EXEC sp_helptext '对象名称'   显示数据库对象(存储过程、触发器、试图)的定义文本
EXEC sp_helpindex '表名' 查看指定表的索引信息
EXEC sp_renamedb '原名称','新名称'  更改数据库名称
EXEC sp_stored_procedures  列出当前环境可用的所有存储过程  


除了系统存储过程,SQL Server 还提供以Xp_开头的扩展存储过程,如可以调用DOS命名的,XP_cmdshell  存储过程

用法如下:

 

 代码如下 复制代码


EXEC   Xp_cmdshell   DOS 命名 [NO_OUTPUT]

 


NO_OUTPUT   为可选参数,表示是否输入存储过程返回的信息

 三、用户自定义存储过程

1、语法

 代码如下 复制代码

create procedure 存储过程名 

  @参数1名 数据类型 [=默认值] [参数类型(输入/输出)] 

  ...  ... 

  @参数n名 数据类型 [=默认值] [参数类型(输入/输出)]

as 

begin

   sql语句 

end;

go

 
参数类型分为输入参数和输出参数,默认为输入参数,使用OUTPUT表示输出参数。创建存储过程最好以proc开头
 

2、创建不带参数的存储过程
 

 代码如下 复制代码

--判断存储过程是否存在
if object_id('proc_student','procedure') is not null

  drop procedure proc_student

 go

create procedure proc_student

as

begin

   select pcid as '电脑编号',

   case pcuse 

     when 0 then '空闲'  

    when 1 then '忙碌' 

     end as '使用状态'  from pc 

end;

--调用存储过程

execute proc_student select * from pc

go
 

3、创建带输入参数的存储过程

语法:

 代码如下 复制代码

create procedure  存储过程名

  @参数1名   数据类型 [=默认值]

  ....

  @参数2名    数据类型[=默认值]

as

  SQl与语句

  ...

go

 

--例如

--创建带输入参数的存储过程

 代码如下 复制代码

if object_id('proc_stu','procedure') is not null 

  drop procedure proc_stu 

go

create procedure proc_stu 

  @pcuse int

as

begin 

select pcid as '电脑编号',  

  case pcuse  

    when 0 then '空闲'  

    when 1 then '忙碌'  

    end as '使用状态'  from pc where pcuse=@pcuse end;

--调用存储过程

execute proc_stu @pcuse=1
 

4、创建带输出参数的存储过程

 代码如下 复制代码

--创建带输出参数的存储过程

if OBJECT_ID('proc_s','procedure') is not null 

  drop procedure proc_s 

go

create procedure proc_s 

  @pcid int, 

  @pcus int output

as

begin

      select @pcus=pcuse from pc where pcid=@pcid end;

--调用存储过程

declare @pcus int execute proc_s 5,@pcus output
 


四、处理错误信息

当存储过程的语句十分复杂时,可以在存储过程中加入错误语言。SQL Server中可以使用RAISERROR  返回用户自定义的错误信息。

RAISERROR  语法如下:

 
RAISERROR  (自定义的错误信息,错误的严重级别,错误状态)

 
自定义错误信息:表示输出信息:表示输出的错误提示文本

错误的严重级别:表示用户自定义错误的严重性级别。(0-18极)

错误的状态:表示自定义错误的状态,值的范围在1-127

例子

写出了自己的分页存储过程,经过整理之后,给一个完整的例子。
首先创建一个分页存储过程,下面的分页存储过程是在pbsql大侠提供的分页存储过程的基础上修改而成的。

 代码如下 复制代码

 CREATE   PROCEDURE   sp_page  
    @strTable       varchar(50),   --表名  
    @strColumn      varchar(50),   --按该列来进行分页  
    @intColType     int,           --@strColumn列的类型,0-数字类型,1-字符类型,2-日期时间类型  
    @intOrder       bit,           --排序,0-顺序,1-倒序  
    @strColumnlist varchar(800), --要查询出的字段列表,*表示全部字段  
    @intPageSize    int,           --每页记录数  
    @intPageNum     int,           --指定页  
    @strWhere       varchar(800), --查询条件  
    @intPageCount   int   OUTPUT   --总页数  
 AS  
  DECLARE   @sql    nvarchar(4000) --用于构造SQL语句
 DECLARE   @where1 varchar(800)   --构造条件语句
 DECLARE   @where2 varchar(800)   --构造条件语句
 IF   @strWhere   is   null   or   rtrim(@strWhere)=''  
 -- 为了避免SQL关键字与字段、表名等连在一起,首先为传入的变量添加空格
 BEGIN  --没有查询条件  
      SET   @where1=' WHERE '  
      SET   @where2=' '  
 END  
 ELSE  
 BEGIN  --有查询条件  
      SET   @where1=' WHERE ('+@strWhere+') AND '
      SET   @where2=' WHERE ('+@strWhere+') '  
 END  
  set @strColumn = ' ' + @strColumn + ' '
 set @strColumnlist = ' ' + @strColumnlist + ' '
 --构造SQL语句,计算总页数。计算公式为 总页数 = Ceiling ( 记录个数 / 页大小 ) http://www.111com.net
 SET   @sql='SELECT   @intPageCount=CEILING((COUNT(*)+0.0)/'
        + CAST(@intPageSize   AS   varchar)
        + ')   FROM   ' + @strTable + @where2  
 --执行SQL语句,计算总页数,并将其放入@intPageCount变量中
 EXEC sp_executesql @sql,N'@intPageCount   int   OUTPUT',@intPageCount   OUTPUT
 --将总页数放到查询返回记录集的第一个字段前,此语句可省略
 SET  @strColumnlist= Cast(@intPageCount as varchar(30)) + ' as PageCount,' + @strColumnlist  
 IF   @intOrder=0   --构造升序的SQL
      SET @sql='SELECT TOP '+ CAST(@intPageSize   AS   varchar) +
               @strColumnlist +  
               ' FROM ' + @strTable + @where1 +
               @strColumn + '>(SELECT MAX('+@strColumn+') '+  
               ' FROM (SELECT TOP '+ CAST(@intPageSize*(@intPageNum - 1) AS  varchar) +  
               @strColumn + ' FROM '+ @strTable+@where2+'ORDER BY '+@strColumn+') t) ORDER BY '+ @strColumn  
 ELSE              --构造降序的SQL  
      SET @sql='SELECT TOP '+ CAST(@intPageSize   AS   varchar) +
               @strColumnlist+  
               ' FROM '+ @strTable + @where1 +
               @strColumn + '<(SELECT   MIN('+@strColumn+')   '+  
               ' FROM (SELECT TOP '+ CAST(@intPageSize*(@intPageNum - 1) AS  varchar) +  
               @strColumn + ' FROM '+ @strTable+@where2+'ORDER   BY '+@strColumn+'   DESC)   t)   ORDER   BY   '+  
               @strColumn + ' DESC'       
 IF   @intPageNum=1--第一页  
      SET   @sql='SELECT   TOP   '+CAST(@intPageSize   AS   varchar) + @strColumnlist + ' FROM '+@strTable+  
                 @where2+'ORDER   BY   '+@strColumn+CASE   @intOrder WHEN  0 THEN  '' ELSE  ' DESC'
 END  
 --PRINT   @sql  
 EXEC(@sql)  
 GO  
 


下面创建一个数据表,进行测试,并向表中添加123个测试数据。

 代码如下 复制代码
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[myUser]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[myUser]
GO
CREATE TABLE [dbo].[myUser] (
     [UserId] [int] IDENTITY (1, 1) NOT NULL ,
     [UserName] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL
) ON [PRIMARY]
GO
declare @i int
set @i=1
while ( @i <= 123 )
 begin
    insert into myUser (UserName) values ( 'test' + cast(@i as varchar(6)))
    set @i = @i + 1
 end
 调用存储过程
declare   @o   int  
exec   sp_page   'myUser','UserId',0,0,'*',15,1,'',@o   output  
exec   sp_page   'myUser','UserId',0,0,'*',15,9,'',@o   output  
如果在.Net中,可以使用输出参数。下面给出C#的从存储过程中输出参数的例子
    ......
    int ipage=1;
    SqlCommand cmd = new SqlCommand("sp_page", conn );
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.Parameters.Add("@strTable", "myUser");
    cmd.Parameters.Add("@strColumn", "UserId");
    cmd.Parameters.Add("@intColType", 0);
    cmd.Parameters.Add("@intOrder", 0);
    cmd.Parameters.Add("@strColumnlist", "*");
    cmd.Parameters.Add("@intPageSize", 15);
    cmd.Parameters.Add("@intPageNum", iPage);
    cmd.Parameters.Add("@strWhere", "");
    SqlParameter paramPageCount = cmd.Parameters.Add("@intPageCount", SqlDbType.Int);
    paramPageCount.Direction = ParameterDirection.Output;
    //可以改为ExecuteReader()
    cmd.ExecuteNonQuery();
    Response.Write(paramPageCount.Value.ToString());

相关文章

精彩推荐