/*遊標*/

來源:互聯網
上載者:User

/*遊標*/
  
  --遊標實際上是一種能從包括多條資料記錄的結果集中每次提取一條記錄的機制
  
  /*遊標的作用*/
  --允許定位到結果集中的特定行。
  --從結果集的當前位置檢索一行或多行資料。
  --支援對結果集中當前位置的行進行修改
  
  /*建立遊標*/
  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。
  */
  
  /*遊標操作*/
  + expand sourceview plaincopy to clipboardprint?
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 
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之隨機函數及遊標應用樣本

 view plaincopy to clipboardprint?
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,關於into子句的用法建議參看聯機叢書瞭解一下,帥的很...  
     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 
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,關於into子句的用法建議參看聯機叢書瞭解一下,帥的很...
  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 社會安全號碼碼=@社會安全號碼碼

本文來自CSDN部落格,轉載請標明出處:http://blog.csdn.net/ztj111/archive/2009/04/28/4133122.aspx

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.