分享

SQL SERVER游标详解

 cqxujun 2015-03-12
--游标实际上是一种能从包括多条数据记录的结果集中每次提取一条记录的机制 
  /*游标的作用*/
  --允许定位到结果集中的特定行。
  --从结果集的当前位置检索一行或多行数据。
  --支持对结果集中当前位置的行进行修改
  /*创建游标*/
  DECLARE cursor_name [ INSENSITIVE ] [ SCROLL ] CURSOR FOR select_statement [ FOR { READ ONLY | UPDATE [ OF column_name [ ,...n ] ] } ]
  /*cursor_name
  是所定义的 Transact-SQL 游标名称。
   INSENSITIVE
  定义一个游标,以创建将由该游标使用的数据的临时复本。对游标的所有请求都从 tempdb 中的该临时表中得到应答;
  因此,在对该游标进行提取操作时返回的数据中不反映对基表所做的修改,并且该游标不允许修改。使用 SQL-92 语法时,
  如果省略 INSENSITIVE,(任何用户)对基表提交的删除和更新都反映在后面的提取中。
   SCROLL
  指定所有的提取选项(FIRST、LAST、PRIOR、NEXT、RELATIVE、ABSOLUTE)均可用。
  如果在 SQL-92 DECLARE CURSOR 中未指定 SCROLL,则 NEXT 是唯一支持的提取选项。
  如果指定 SCROLL,则不能也指定 FAST_FORWARD。
   select_statement
  是定义游标结果集的标准 SELECT 语句。在游标声明的 select_statement 内不允许使用关键字 COMPUTE、COMPUTE BY、和 INTO。
  */
  
  /*游标操作*/
[cpp] view plaincopy
declare cr cursor  
  for  
  select * from authors  
  --定义游标  
  --该游标未指定scroll,只可用next  
    
  open cr  
  --打开游标  
    
  fetch next from cr  
  --推进游标  
    
  close cr  
  --关闭游标  
    
  deallocate cr  
  --删除游标  
    
  create table emp  
  (  
  eid int primary key,  
  ename varchar(10),  
  sal money  
  )  
    
  insert into emp select 1001,'rose',1234  
  union select 1002,'jack',2564  
  union select 1003,'will',245  
  union select 1004,'lecky',456  
    
    
  --首次推进的结果为第一条  
    
  /*@@fetch_status*/  
    
  --返回被 FETCH 语句执行的最后游标的状态,而不是任何当前被连接打开的游标的状态。  
  -- 0 FETCH 语句成功。  
  -- -1 FETCH 语句失败或此行不在结果集中。(无法fetch的时候)  
  -- -2 被提取的行不存在  
  fetch next from cr  
  while @@fetch_status=0  
  begin  
   fetch next from cr  
  end  
  --如不推进,则全局变量的值对于循环是否能够启动没有参考价值  
  --最后一行fetch_status值为0  
  --下一条为-1  
    
  /*滚动游标*/  
  declare cr cursor scroll for select * from emp  
  --需用scroll关键字  
  open cr  
  fetch next from cr  
  close cr  
  deallocate cr  

    
  
  --FETCH FIRST:提取游标的第一行。
  --FETCH NEXT:提取上次提取的行的下一行。
  --FETCH PRIOR:提取上次提取的行的前一行。
  --FETCH LAST:提取游标中的最后一行。
  --FETCH ABSOLUTE n:
  -- 如果n 为正整数,则提取 游标中的第n行
  -- 如果n为负整数,则提取游标最后一行之前的第n行
  -- 如果n 为0,则不提取任何行
  --FETCH RELATIVE n :
  -- 如果n为正,则提取上次提取的行之后的第n行。
  -- 如果n为负,则提取上提取的行之前的第n行。
  -- 如果n为0,则再次提取同一行
  
  /*@@cursor_rows*/
  --返回当前打开的游标中符合条件的行的数目
  
  /*游标实例(更新)*/
  begin tran tr
  declare cr cursor for select * from emp for update of ename
  --通过该游标只能更新ename列
  --多个列逗号分隔
  open cr
  
  fetch next from cr 
  update emp set ename='log' where current of cr
  --current of cr通过游标
  --只更新一行
  close cr
  deallocate cr 
  rollback tran tr
  
  /*删除游标指向的行*/
  delete from emp where current of cr
  /*存储过程*/
  
  /*取记录*/
  create proc p1 @no int
  as select * from emp where eid=@no
  --as必须
  
  exec p1 2004
  --执行存储过程
  
  /*加法*/
  create proc p1 @a int,@b int
  as return @a+@b
  declare @res int
  set @res=exec p1 20,30
  print @res
  --drop proc p1
  --带有返回值的存储过程的执行
  
  /*按地址传递输出*/
  create proc p1 @a int output,@b int output
  as
  begin
  declare @temp int
  set @temp=@a
  set @a=@b
  set @b=@temp
  end
  
  declare @a int,@b int
  set @a=90
  set @b=890
  exec p1 @a output,@b output
  print @a
  print @b  

SQL之随机函数及游标应用示例

[c-sharp] view plaincopy
create table emp  
(  
    eid varchar(10)  
)  
GO  --注意这里一定要加go  
--drop table emp  
create proc prand   
    as   
    begin  
     declare @i int  
     set @i=0  
     while @i<100  
     begin  
     insert into emp select floor(rand()*100000)  
     --rand()*100000的取值范围为1--99999  
     set @i=@i+1  
     --循环插入100条随机数  
     end  
       
     declare crl scroll cursor for select * from emp  
     --定义游标  
     open crl  
     --打开游标  
     --fetch first from crl   
     declare @max int,@min int,@temp int  
     --@max最大值,@min最小值,@temp 临时变量  
     fetch next from crl into @max  
     --首次推进游标,'into @max'是把其推进结果赋值给@max
     set @min=@max  
     --将此初值也赋给最小值  
     while @@fetch_status=0  
     begin  
  
     fetch next from crl into @temp  
     if @temp>@max  
     begin  
        set @max=@temp  
     end  
  
     if @temp<@min  
     begin  
     set @min=@temp  
     end  
  
     end  
     print '最大值为'+convert(varchar,@max)  
     print '最小值为'+convert(varchar,@min)  
     --输出结果,需要强制转换  
     close crl  
     --关闭游标  
     deallocate crl  
     --删除游标  
    end  
    --drop proc prand  
  
    exec prand  


GO表示一批T-SQL语句结束,GO之后的T-SQL语句属于另一个批处理范围,在T-SQL所有语句的最后都要默认有一个GO。但是,GO不是T-SQL语句,而只是一个能被SQL Server实用工具识别的命令
USE [北风贸易]

SET ANSI_NULLS ON

SET QUOTED_IDENTIFIER ON

ALTER PROCEDURE [dbo].[testProcedure]
@身份证号码 NVARCHAR(18)
AS
SELECT*FROM dbo.成绩 WHERE 身份证号码=@身份证号码
上面示例将发生错误:'CREATE/ALTER PROCEDURE' 必须是查询批次中的第一个语句。
应该改成

USE [北风贸易]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[testProcedure]
@身份证号码 NVARCHAR(18)
AS
SELECT*FROM dbo.成绩 WHERE 身份证号码=@身份证号码

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多