游標的高階技巧(供初學者參考)

2022-02-23 09:07:34 字數 3752 閱讀 2517

提到游標這個詞,人們想到的是在螢幕上乙個閃動的方框,用以指示使用者將要輸入字元的位置。而在關係型資料庫的sql語言中,游標卻有另外的含義,它是存放結果集的資料物件。

為什麼要用到游標

在某些powerbuilder應用程式的開發中,您可能根本用不到游標這樣乙個物件。因為在其它工具開發中很多需用游標實現的工作,在 powerbuilder中卻已有datawin-dow來代勞了。事實上,datawindow不僅可以替代游標進行從後台資料庫查詢多條記錄的複雜操作,而且還遠不止這些。但是同datawindow和datastore相比,游標也有其自身的優點,比如系統資源占用少,操作靈活,可根據需要定義變數型別如全域性、例項或區域性型別和訪問型別如私有或公共等。

游標的操作

使用游標有四種基本的步驟:宣告游標、開啟游標、提取資料、關閉游標。

宣告游標

象使用其它型別的變數一樣,使用乙個游標之前,首先應當宣告它。游標的宣告包括兩個部分:游標的名稱;這個游標所用到的sql語句。如要宣告乙個叫作cus-tomercursor的游標用以查詢位址在北京的客戶的姓名、帳號及其餘額,您可以編寫如下**:

declare customercursor cursor for

select acct_no,name,balance

from customer

where province="北京";

在游標的宣告中有一點值得注意的是,如同其它變數的宣告一樣,宣告游標的這一段**行是不執行的,您不能將debug時的斷點設在這一**行上,也不能用if...end if語句來宣告兩個同名的游標,如下列的**就是錯誤的。

if is_prov="北京"then

declare customercursor cursor for

select acct_no,name,balance

from customer

where province="北京";

else

declare customercursor cursor for

select acct_no,name,balance

from customer

where province〈〉"北京";

end if

開啟游標

宣告了游標後在作其它操作之前,必須開啟它。開啟游標是執行與其相關的一段sql語句,例如開啟上例宣告的乙個游標,我們只需鍵入:

open customercursor;

由於開啟游標是對資料庫進行一些sql select的操作,它將耗費一段時間,主要取決於您使用的系統效能和這條語句的複雜程度。如果執行的時間較長,可以考慮將螢幕上顯示的滑鼠改為hourglass。

提取資料

當用open語句開啟了游標並在資料庫中執行了查詢後,您不能立即利用在查詢結果集中的資料。您必須用fetch語句來取得資料。一條fetch語句一次可以將一條記錄放入程式設計師指定的變數中。事實上,fetch語句是游標使用的核心。在datawindow和datastore中,執行了retrieve ()函式以後,查詢的所有結果全部可以得到;而使用游標,我們只能逐條記錄地得到查詢結果。

已經宣告並開啟乙個游標後,我們就可以將資料放入任意的變數中。在fetch語句中您可以指定游標的名稱和目標變數的名稱。如下例:

fetch custmercur-sor

into:ls_acct_no,

:ls_name,

:ll_balance;

從語法上講,上面所述的就是一條合法的取資料的語句,但是一般我們使用游標卻還應當包括其它的部分。正如我們前面所談到的,游標只能一次從後台資料庫中取一條記錄,而在多數情況下,我們所想要作的是在資料庫中從第一條記錄開始提取,一直到結束。所以我們一般要將游標提取資料的語句放在乙個迴圈體內,直至將結果集中的全部資料提取後,跳出迴圈圈。通過檢測sqlca.sql-code的值,可以得知最後一條fetch語句是否成功。一般,當sqlcode值為 0時表明一切正常,100表示已經取到了結果集的末尾,而其它值均表明操作出了問題,這樣我們可以編寫以下的**:

lb_continue=true

ll_total=0

do while lb_continue

fetch customercur-sor

into:ls_acct_no,

:ls_name,

:ll_balance;

if sqlca.sqlcode=0 then

ll_total+=ll_balance

else

lb_continue=false

end if

loop

迴圈體的結構有多種,這裡提到的是最常見的一種。也有的程式設計師喜愛將一條fetch語句放在迴圈體的前面,迴圈體內再放置另外一條fetch語句,並檢測sqlca.sqlcode是否為100。但是這樣做,維護時需同時修改兩條fetch語句,稍麻煩了些。

關閉游標

在游標操作的最後請不要忘記關閉游標,這是乙個好的程式設計習慣,以使系統釋放游標占用的資源。關閉游標的語句很簡單:

close customercursor;

使用where子句子

我們可以動態地定義游標中的where子句的引數,例如在本例中我們是直接定義了查詢省份是北京的記錄,但也許在應用中我們要使用乙個下拉式列表框,由使用者來選擇要查詢的省份,我們該怎樣做呢?

我們在前面曾經提到過,declare語句的作用只是定義乙個游標,在open語句中這個游標才會真正地被執行。了解了這些,我們就可以很方便地實現這樣的功能,在declare的where子句中加入變數作引數,如下所示:

declare customercursor cursor for

selcect acct_no,name,balance

from customer

where province=:ls_province;

∥定義ls_province的值

open customercursor;

游標的型別

同其它變數一樣,我們也可以定義游標的訪問型別:全域性、共享、例項或區域性,游標變數的命名規範建議也同其它變數一樣。

游標的高階技巧

儘管目前基於sql語句的後台資料庫所支援的語言都大致相當,但對游標的支援卻有著一些差異,例如對滾動游標支援。所謂滾動游標,就是程式設計師可以指定游標向前後任意乙個方向滾動。如在informix中,您甚至還可以將游標滾向結果集開頭或末尾,使用的語句分別是fetch first,fetch last、fetch prior和fetch next。當程式設計師用fetch語句,其預設是指fetch next。由於滾動是在資料庫後台實現的,所以滾動游標為使用者程式設計提供了極大的方便。

對游標支援的另乙個不同是可修改游標。上述游標的使用都是指唯讀游標,而象oracle、sybase等資料庫卻另外支援可作修改的游標。使用這樣的資料庫,您可以修改或刪除當前游標所在的行。例如修改當前游標所在行的使用者的餘額,我們可以如下操作:

update customer

set balance=1000

where current of customercursor;

刪除當前行的操作如下:

delete from customer

where current of customercursor;

但是如果您當前使用的資料庫是sybase,您需要修改資料庫的引數,將游標可修改的值定為1,才能執行上述操作。這一賦值在連線資料庫的前後進行均可。

sqlca.dbparm="cursor update=1"

另外乙個內容是動態游標,也就是說您可以執行過程中動態地形成游標的select語句。這同在powerbuilder中動態地使用嵌入式sql一樣,需要用到dynamicstagin-garea等資料型別,這已超出了本節的範圍。

Schema初學者高階 2

簡化schema的設計 在我們上次的練習中,設計schema所使用的方法是極其簡單的。由於使用層層巢狀的的定義方法,當文件非常複雜時,由於巢狀層次過深,文件將不易閱讀並且難以維護。同時這種方法和過去dtd的設計結構有非常大的差異,這使得人或者機器想把dtd轉換成xml schema時會有困難。因此,...

初學者建模和佈線技巧

最近通過很多師弟的交流,我發現遊戲建模初學者大多存在三個大問題,一是工具的使用不夠熟練,甚至有些功能還不知道,二是對佈線的規範沒有太大的要求和了解,三是對遊戲製作流程不清晰和板繪下的功力不夠,對貼圖製作用工少,甚至有些人還處於一直做白膜的階段,那麼對大多說想要要學遊戲建模的學習者想要學什麼 低模,高...

初學者高階的python經典例項

題目 對10個數進行排序。程式分析 可以利用選擇法,即從後9個比較過程中,選擇乙個最小的與第乙個元素交換,下次類推,即用第二個元素與後8個進行比較,並進行交換。程式源 usr bin python coding utf 8 if name main n 10 input data print ple...