Sql server中的Cursor

來源:互聯網
上載者:User
有時候我們需要逐條地讀取資料,就像下面這樣:

this.sqlConnection1.Open();
SqlDataReader myReader = this.sqlCommand1.ExecuteReader();
do
{
while (myReader.Read())
      {
Console.WriteLine("{0}{1}", myReader.GetInt32(0), myReader.GetString(1));
} while (myReader.NextResult());
myReader.Close();
      sqlConnection1.Close();    

我們經常會這樣在自己的程式中這樣去寫,但是怎麼在SQL Server 中逐條訪問資料,當然是有辦法的,那就是遊標。
比方說:
我想從Nurthwind資料庫的Employees中尋找TitleOfCourtesy為‘Mr.'的所有人的LastName和FirstName,同時我需要逐條訪問,下面是樣本:

USE Northwind
GO
--定義遊標
DECLARE myCursor CURSOR FOR
SELECT LastName, FirstName FROM Employees
WHERE TitleOfCourtesy ='Mr.'
--開啟遊標
OPEN myCursor
--逐行讀取
FETCH NEXT FROM myCursor
--@@FETCH_STATUS,FETCH 語句成功
WHILE @@FETCH_STATUS = 0
BEGIN  
   FETCH NEXT FROM myCursor
END
--關閉遊標
CLOSE myCursor
--釋放遊標
DEALLOCATE myCursor
GO

就這樣逐條的結果讀出來了

但 是遊標佔用記憶體,還用它們那些不可思議的方式鎖定表。每執行一次FETCH就等於執行一次SELECT命令?這意味著如果你的遊標有10000條記錄,它 將執行10000次SELECT!如果你使用一組SELECT、UPDATE或者DELETE來完成相應的工作,那將有效率的多。
關於遊標與資料庫效能:
Cursor threshold選項
用於指定遊標集的行數。
如果設定為-1,則所有的遊標集將同步產生,對於小遊標集會非常有用
如果設定為0,則所有的遊標集將非同步產生,這對於數量很大的遊標集會有協助
如果設定為其它值,非同步和同步將由遊標集中所期望的行數和遊標閾值的設定值比較決定。前者大於後者,非同步;否則,同步。
可以使用sp_configure系統預存程序來修改該設定。當注意的是只有show advanced options為1時才可更改。同時該設定修改後立即生效,無須重啟資料庫。

 


2.2 隱式遊標

       所有的隱式遊標都被假設為只返回一條記錄。

       使用隱式遊標時,使用者無需進行聲明、開啟及關閉。PL/SQL隱含地開啟、處理,然後關掉遊標。

       例如:

       …….

       SELECT studentNo,studentName

       INTO curStudentNo,curStudentName

       FROM StudentRecord

       WHERE name=’gg’;

       上述遊標自動開啟,並把相關值賦給對應變數,然後關閉。執行完後,PL/SQL變數curStudentNo,curStudentName中已經有了值。

遊標四大隱式屬性

%found、%notfound、%isopen、%rowcount

其中%found、%notfound、%isopen的結果為boolean型,%rowcount結果為整數。

舉例說明:
test表資料
 A NAME
-- -----
 1 aa
 2 bb
 3 cc
 4 dd
 5 ee

程式:
set serveroutput on
declare
cursor abc(idpara number) is   --帶參數
select name from test where a=idpara;
t_name test.name%type;
e exception;     --自訂異常
nopen exception;    --自訂異常
begin
open abc('3');     --參數idpara賦值為3
fetch abc into t_name;
if abc%isopen then    --如果遊標已開啟
dbms_output.put_line('cursor is open');
else
raise nopen;     --拋出自訂異常(遊標未開啟)
end if;
if abc%notfound then    --如果資料沒有找到
raise e;     --拋出自訂異常(資料沒有找到)
elsif abc%found then    --如果資料找到
dbms_output.put_line(t_name);
dbms_output.put_line('I found '||abc%rowcount||' data!'); --輸出找到多少個資料
end if;
exception    
when nopen then       --遊標未開啟異常執行
dbms_output.put_line('The cursor is not found!');  
when e then       --資料未找到異常執行
dbms_output.put_line('The eid is not found!');
end;
/

完成。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.