`

SqlServer中的存储过程和游标操作

阅读更多
--------------开篇讲述-----------------------------
首先介绍一下什么是存储过程:
      存储过程就是将常用的或很复杂的工作,预先用SQL语句写好并用一个指定的名称存储起来,并且这样的语句是放在数据库中的,
      还可以根据条件执行不同SQL语句, 那么以后要叫数据库提供与已定义好的存储过程的功能相同的服务时,只需调用execute,即可自动完成命令。
---------------注意事项----------SQL2008 R2------
*修改存储过程和重新创建存储过程的区别:
          如果需要更改存储过程中的语句或参数,可以删除并重新创建该存储过程,也可以通过一个步骤更改该存储过程。
          删除并重新创建存储过程时,与该存储过程关联的所有权限都将丢失。更改存储过程时,将更改过程或参数定义,
          但为该存储过程定义的权限将保留,并且不会影响任何相关的存储过程或触发器。还可以修改存储过程以加密其定
          义或使该过程在每次执行时都得到重新编译。
*修改存储过程出错:
    更改存储过程的名称或定义可能会导致所有相关对象在执行时失败,如果这些相关对象未进行更新以反映对该存储过程所做的更改。
   
1、----------------------------------SQLserver存储过程的语法------------------------------

Create PROC [ EDURE ] procedure_name     [  number ]     [ { @parameter data_type }
            [ VARYING ] [ = default ] [ OUTPUT ]     ] [ ,...n ] 
   [ WITH
        { RECOMPILE | ENCRYPTION | RECOMPILE , ENCRYPTION } ] 
   [ FOR REPLICATION ] 
  AS sql_statement [ ...n ]

简单一点就是:Create PROCEDURE    procedure_name  [参数个数]   [有参数/没有参数  ]         AS             过程体           GO
存储过程的调用:execute procedure    [参数]

2、---------------------------------------查看存储过程-------------------------
-- 若要查看存储过程的定义
sys.sql_modules (Transact-SQL)
OBJECT_DEFINITION (Transact-SQL)
sp_helptext (Transact-SQL)
-- 查看有关存储过程的信息
sys.objects (Transact-SQL)
sys.procedures (Transact-SQL)
sys.parameters (Transact-SQL)
sys.numbered_procedures (Transact-SQL)
sys.numbered_procedure_parameters (Transact-SQL)
sp_help (Transact-SQL)
-- 查看存储过程的依赖关系
sys.sql_expression_dependencies (Transact-SQL)
sys.dm_sql_referenced_entities (Transact-SQL)
sys.dm_sql_referencing_entities (Transact-SQL)
-- 查看有关扩展存储过程的信息
sp_helpextendedproc (Transact-SQL)             

3、------------------------存储过程示例:--------------------------
----------示例1:--------------简单数据查询------------------
create proc query_book
  as
    select * from book
go
--调用存储过程
exec query_book
----------示例2:--------------存储过程参数传递------------------
create procedure dbo.Get_operator
    @Czy_code varchar(10),

    @Czy_password varchar(10)
as
declare Czy_name varchar(10)
declare Czy_in_station varchar(10)
  
    begin transaction
        select @Czy_name = name,@Czy_in_station = in_station
              from dbo.User where code = @Czy_code and password =@Czy_password
    commit
    select @Czy_code,@Czy_name,@Czy_in_station

GO
----------示例3:--------------分页存储过程------------------
create proc commonPagination
  @columns varchar(500),   --要显示的列名,用逗号隔开
  @tableName varchar(100), --要查询的表名
  @orderColumnName varchar(100), --排序的列名
  @order varchar(50),  --排序的方式,升序为asc,降序为 desc
  @where varchar(100), --where 条件,如果不带查询条件,请用 1=1
  @pageIndex int, --当前页索引
  @pageSize int,  --页大小(每页显示的记录条数)
  @pageCount int output --总页数,输出参数
as
  begin
    declare @sqlRecordCount nvarchar(1000) --得到总记录条数的语句
    declare @sqlSelect nvarchar(1000) --查询语句
    set @sqlRecordCount=N'select @recordCount=count(*) from '
           +@tableName + ' where '+ @where
    declare @recordCount int --保存总记录条数的变量
    exec sp_executesql @sqlRecordCount,N'@recordCount int output',@recordCount output
   
    --动态 sql 传参
    if( @recordCount % @pageSize = 0) --如果总记录条数可以被页大小整除
        set @pageCount = @recordCount / @pageSize --总页数就等于总记录条数除以页大小
    else --如果总记录条数不能被页大小整除
      set @pageCount = @recordCount / @pageSize + 1 --总页数就等于总记录条数除以页大小加1
    set @sqlSelect =
     N'select '+@columns+' from (
         select row_number() over (order by '
               +@orderColumnName+' '+@order
               +') as tempid,* from '
               +@tableName+' where '+ @where
               +') as tempTableName where tempid between '
               +str((@pageIndex - 1)*@pageSize + 1 )
               +' and '+str( @pageIndex * @pageSize)
     exec (@sqlSelect) --执行动态Sql
  end
go
--以下是调用示例
use pubs
   go
declare @pageCount int
exec commonPagination  'job_id,job_desc','jobs','job_id', 'asc','1=1',2,2,@pageCount output
select '总页数为:' + str(@pageCount)

4、 ----------------------------------存储过程输入输出演示------------------------------------------------
   存储过程的3种传回值(方便正在看这个例子的朋友不用再去查看语法内容):  
      1.以Return传回整数   
      2.以output格式传回参数   
      3.Recordset 
  传回值的区别:     output和return都可在批次程式中用变量接收,而recordset则传回到执行批次的客户端中。

   实例1:只返回单一记录集的存储过程。

    要求:查询表bankMoney的内容的存储过程
   create procedure sp_query_bankMoney   as
          select * from bankMoney
   go
   exec sp_query_bankMoney
  注*  在使用过程中只需要把中的SQL语句替换为存储过程名,就可以了很方便吧!

  实例2(向存储过程中传递参数):

  加入一笔记录到表bankMoney,并查询此表中userID= Zhangsan的所有存款的总金额。  
  Create proc insert_bank @param1 char(10),@param2 varchar(20),@param3 varchar(20),@param4 int,@param5 int output   with encryption ---------加密   as  
  insert bankMoney (id,userID,sex,Money) Values(@param1,@param2,@param3, @param4)
  select @param5=sum(Money) from bankMoney where userID='Zhangsan'   go
  在SQL Server查询分析器中执行该存储过程的方法是:   declare @total_price int
  exec insert_bank '004','Zhangsan','男',100,@total_price output   print '总余额为'+convert(varchar,@total_price)   go

  实例3:使用带有复杂 Select 语句的简单过程

  下面的存储过程从四个表的联接中返回所有作者(提供了姓名)、出版的书籍以及出版社。该存储过程不使用任何参数。   USE pubs
  IF EXISTS (Select name FROM sysobjects          Where name = 'au_info_all' AND type = 'P')   Drop PROCEDURE au_info_all   GO
  Create PROCEDURE au_info_all   AS
  Select au_lname, au_fname, title, pub_name   FROM authors a INNER JOIN titleauthor ta       ON a.au_id = ta.au_id INNER JOIN titles t       ON t.title_id = ta.title_id INNER JOIN publishers p       ON t.pub_id = p.pub_id   GO
  au_info_all 存储过程可以通过以下方法执行:   EXECUTE au_info_all   -- or
  EXEC au_info_all
  如果该过程是批处理中的第一条语句,则可使用:   au_info_all  

  实例4:使用带有参数的简单过程

  Create PROCEDURE au_info       @lastname varchar(40),       @firstname varchar(20)   AS
  Select au_lname, au_fname, title, pub_name       FROM authors a INNER JOIN titleauthor ta       ON a.au_id = ta.au_id INNER JOIN titles t       ON t.title_id = ta.title_id INNER JOIN publishers p       ON t.pub_id = p.pub_id       Where  au_fname = @firstname       AND au_lname = @lastname   GO
  au_info 存储过程可以通过以下方法执行:   EXECUTE au_info 'Dull', 'Ann'   -- or
  EXECUTE au_info @lastname = 'Dull', @firstname = 'Ann'   -- or
  EXECUTE au_info @firstname = 'Ann', @lastname = 'Dull'   -- or
  EXEC au_info 'Dull', 'Ann'   -- or
  EXEC au_info @lastname = 'Dull', @firstname = 'Ann'   -- or
  EXEC au_info @firstname = 'Ann', @lastname = 'Dull'   如果该过程是批处理中的第一条语句,则可使用:   au_info 'Dull', 'Ann'   -- or
  au_info @lastname = 'Dull', @firstname = 'Ann'   -- or
  au_info @firstname = 'Ann', @lastname = 'Dull'

  实例5:使用带有通配符参数的简单过程

  Create PROCEDURE au_info2   @lastname varchar(30) = 'D%',   @firstname varchar(18) = '%'   AS
  Select au_lname, au_fname, title, pub_name   FROM authors a INNER JOIN titleauthor ta      ON a.au_id = ta.au_id INNER JOIN titles t      ON t.title_id = ta.title_id INNER JOIN publishers p      ON t.pub_id = p.pub_id   Where au_fname LIKE @firstname      AND au_lname LIKE @lastname   GO
  au_info2 存储过程可以用多种组合执行。下面只列出了部分组合:   EXECUTE au_info2   -- or
  EXECUTE au_info2 'Wh%'   -- or
  EXECUTE au_info2 @firstname = 'A%'   -- or
  EXECUTE au_info2 '[CK]ars[OE]n'   -- or
  EXECUTE au_info2 'Hunter', 'Sheryl'   -- or
  EXECUTE au_info2 'H%', 'S%'
5、--------------------------------存储过程中游标的使用--------------------------------------------------
(1)、需要游标的数据操作

    当select语句的结果中包含多个元组时,使用游标可以逐个存取这些元组 
    活动集:select语句返回的元组的集合 
    当前行:活动集中当前处理的那一行。游标即是指向当前行的指针。 
(2)、游标分类

    滚动游标:游标的位置可以来回移动,可在活动集中取任意元组。 
    非滚动游标:只能在活动集中顺序地取下一个元组。 
    更新游标:数据库对游标指向的当前行加锁,当程序读下一行数据时,本行数据解锁,下一行数据加锁。 
(3)、定义与使用游标的语句

    declare : 
        declare  游标名[scroll]  cursor  for select语句[for update [of列表名]] 定义一个游标,使之对应一个select语句 
       for update任选项,表示该游标可用于对当前行的修改与删除 
    open 
       打开一个游标,执行游标对应的查询,结果集合为该游标的活动集 
       open  游标名 
    fetch 
       在活动集中将游标移到特定的行,并取出该行数据放到相应的变量中 
       fetch [next | prior | first | last | current | relative n | absolute m] 游标名into  [变量表]
    close 
       关闭游标,释放活动集及其所占资源。需要再使用该游标时,执行open语句 
       close  游标名 
    deallocate 
       删除游标,以后不能再对该游标执行open语句 
       deallocate 游标名 
    @@FETCH_STATUS 
        返回被FETCH 语句执行的最后游标的状态. 
       0 fetch语句成功 
        -1 fetch语句失败 
        -2 被提取的行不存在
(4)、游标实例
     例:查询电子商务系学生信息,性别为女输出为female,否则输出为male? 
       declare c1 cursor for select sno,sname,ssex from student where sdept='ec' 
       declare @sno char(10),@sname char(10),@ssex char(2) 
       Open c1 
       Fetch c1 into @sno,@sname,@ssex 
       While @@fetch_status==0 
       Begin 
       if @ssex='女' 
           begin  set @ssex='female' end 
       else
        begin set @ssex='male' end 
            Select @sno,@sname ,@ssex 
           Fetch c1 into @sno,@sname,@ssex 
       end

(5)修改存储过程
例: ALTER PROC [dbo].[dnt_UserRecoveryByUserName]     @username    NVARCHAR(50) AS 
BEGIN 
    DECLARE    @uid INT;     DECLARE    @tid INT;     DECLARE    @replies INT;
    DECLARE    @temp varchar(50); 
    SET @uid        = (SELECT TOP(1) uid FROM dnt_users WHERE username = '@username');
    SET @tid        = 0;     SET @replies    = 0; 
    UPDATE dnt_users SET accessmasks = 0 WHERE uid = @uid;
    UPDATE dnt_userforum SET groupid = 5 WHERE groupid = 4 AND uid = @uid;     UPDATE dnt_posts SET invisible = 0 WHERE invisible = -1 AND posterid = @uid; 
    -- 定义一游标
    DECLARE Ctemp CURSOR FOR SELECT tid FROM dnt_topics WHERE posterid = @uid FOR READ only -- FOR UPDATE 
    OPEN Ctemp  
        FETCH next FROM Ctemp INTO @tid;         WHILE (@@fetch_status = 0)         BEGIN
            SET @replies = (SELECT COUNT(1) FROM dnt_posts WHERE tid = @tid AND layer > 0);
            UPDATE dnt_topics SET replies = @replies WHERE posterid = @uid AND tid = @tid;
            FETCH next FROM Ctemp INTO @tid;         END
    CLOSE Ctemp;
    DEALLOCATE Ctemp;
分享到:
评论

相关推荐

    SQL SERVER中的存储过程和游标的使用大综合

    在SQL Server中,存储过程和游标是两个重要的数据库编程元素,它们对于数据操作和管理起着关键作用。本文将深入探讨这两个概念,以及如何在实际应用中有效地使用它们。 **存储过程(Stored Procedures)** 存储...

    MS SQL Server2005存储过程、游标、游标嵌套综合例子

    在提供的示例文件`sqlserver2005_procedure_cursor_sample_20101015.sql`中,很可能是包含了存储过程的定义,这些存储过程可能涉及到游标的使用,甚至游标嵌套,以解决特定的业务问题。通常,这样的示例会展示如何在...

    SqlServer存储过程、游标讲解

    在SqlServer中,使用游标一般包含以下几个步骤:声明游标、打开游标、读取数据、关闭游标以及删除游标。声明游标时可以使用简单的查询,也可以是复杂的连接查询或者嵌套查询。游标被声明后,必须先打开才能从中读取...

    SqlServer存储过程游标

    ### SqlServer 存储过程与...存储过程和游标都是SQL Server中非常重要的工具,它们能够帮助开发者更高效地管理和操作数据库中的数据。在实际应用中,合理地使用存储过程和游标可以显著提升应用程序的性能和可维护性。

    sql server 2008 存储过程示例带游标

    在SQL Server 2008中,存储过程与游标是数据库编程中常见的技术,用于实现复杂的业务逻辑和数据操作。下面将详细解析标题“sql server 2008 存储过程示例带游标”所涉及的知识点,包括存储过程的创建、游标的使用...

    sqlserver游标存储过程的使用

    接下来,我们将学习如何在SQL Server存储过程中使用游标: 1. **声明游标**:首先需要声明一个游标,指定其类型、源数据集(通常是查询语句)以及其属性。例如: ```sql DECLARE @MyCursor CURSOR FOR SELECT * FROM...

    sql server和oracle的存储过程、游标示例

    在数据库管理领域,SQL Server和Oracle都是广泛应用的关系型数据库管理系统,它们都支持存储过程和游标的使用,这两种特性极大地增强了数据库的功能性和效率。存储过程是预编译的SQL语句集合,而游标则用于逐行处理...

    存储过程和游标

    在提供的标签"源码"和"工具"中,我们可以理解为这可能是关于如何在代码中调用存储过程和操作游标的方法。在实际开发中,开发者通常会使用编程语言如Java、C#等来与数据库交互,通过特定的数据库连接库(如JDBC、ADO...

    SqlServer存储过程及调试指南

    6. 存储过程修改与变更:在对SQLServer存储过程进行修改和变更时,可能会遇到与现有数据库函数冲突的问题,需要掌握正确的方法来进行升级和批量修改,避免造成错误。 7. 异常处理的详细机制:在TRY块中包含潜在失败...

    SQL Server存储过程之嵌套游标

    下面是一个订单取消的含2个游标的存储过程 set ANSI_NULLS ON set QUOTED_IDENTIFIER ON go ALTER PROCEDURE [dbo].[CancelOrderBySystem] AS BEGIN declare /*声明变量*/ @Status varchar(100), –状态 ...

    SQLServer数据库游标和函数的使用(经典)

    3. 获取数据:通过`FETCH NEXT`从游标中获取下一行数据,可以使用` INTO`关键字将数据存储到变量中。 4. 处理数据:根据业务需求,对获取的数据执行操作。 5. 关闭和释放游标:完成数据处理后,使用`CLOSE`关闭游标...

    SQL Server遍历表中记录的2种方法(使用表变量和游标)

    表变量在SQL Server中是一种临时存储数据的结构,它与临时表相似但作用范围更小,仅限于当前批处理或存储过程。以下是一个使用表变量的例子: ```sql DECLARE @temp TABLE (id INT IDENTITY(1, 1), Name VARCHAR(10...

    SQL学习教程-存储过程,游标,触发器

    在SQL Server 2008中,理解如何有效地利用存储过程、游标和触发器,能帮助开发者编写出更加高效和维护友好的数据库应用程序。通过实践和深入理解这三个概念,你将能够更好地管理数据库,实现更高效的数据操作和更...

    自己做的存储过程含游标例子

    自己做的存储过程含游标例子,对于初学存储过程和游标的人有帮助

    SQL Server 游标用法

    4. **提取(FETCH)**:`FETCH NEXT`用于获取游标中的下一行数据,并将其赋值给之前声明的变量: ```sql FETCH NEXT FROM my_cursor1 INTO @rowid, @title ``` 5. **循环处理**:在提取数据后,我们可以进行一...

    sql server 游标实例

    3. **获取数据**:使用`FETCH`语句从游标中获取数据,并将其存储到事先定义好的变量中。 4. **处理数据**:在循环中处理每一行数据。 5. **关闭游标**:使用`CLOSE`语句关闭游标。 6. **释放游标**:使用`DEALLOCATE...

    TSQL 存储过程 和 游标

    在TSQL中,游标允许程序逻辑逐条遍历和操作查询结果,而不是一次性处理所有数据。这在需要循环遍历数据或根据当前行数据做出决策时非常有用。 创建游标的基本步骤: 1. 定义游标:`DECLARE 游标名 CURSOR FOR 查询...

Global site tag (gtag.js) - Google Analytics