?
本文檔使用 php中文網(wǎng)手冊 發(fā)布
DECLARE name [ BINARY ] [ INSENSITIVE ] [ [ NO ] SCROLL ] CURSOR [ { WITH | WITHOUT } HOLD ] FOR query
DECLARE允許一個(gè)用戶來創(chuàng)建,這可以在較大查詢的一個(gè)時(shí)間里 用來檢索少量行。游標(biāo)創(chuàng)建以后,通過使用FETCH可以將行抓取 出來。
Note: 這個(gè)頁面在SQL命令水平描述了游標(biāo)的使用方法。如果你視圖使用PL/pgSQL 函數(shù)中的游標(biāo),規(guī)則就會不一樣—請參閱Section 39.7。
將要創(chuàng)建的游標(biāo)名
令游標(biāo)以二進(jìn)制而不是文本格式返回?cái)?shù)據(jù)
指明從游標(biāo)中恢復(fù)的數(shù)據(jù)應(yīng)該是不受影響的,在有表創(chuàng)建以后通過更新游標(biāo)下的表。 在PostgreSQL中,這是默認(rèn)的相應(yīng);所以這個(gè)關(guān)鍵字 沒有影響并且僅接受兼容SQL標(biāo)準(zhǔn)。
SCROLL聲明該游標(biāo)可以用于以倒序的方式檢索數(shù)據(jù)行 (也就是反向檢索)。根據(jù)查詢的執(zhí)行計(jì)劃的不同,聲明SCROLL 可能會對查詢的執(zhí)行時(shí)間有不良影響。NO SCROLL聲明該游標(biāo)不 能用于以倒序的方式檢索數(shù)據(jù)行。缺省僅允許在某些情況下倒序檢索,這不同于指定 SCROLL。參見 注意獲取細(xì)節(jié)。
WITH HOLD(缺省)聲明該游標(biāo)可以在創(chuàng)建它的事務(wù)成功提交后繼續(xù)使用。 WITHOUT HOLD聲明該游標(biāo)不能在創(chuàng)建它的事務(wù)提交后使用。 r若WITHOUT HOLD和WITH HOLD都未聲明, 則默認(rèn)為WITHOUT HOLD。
一個(gè)SELECT或者VALUES命令 會提供游標(biāo)返回的行。
BINARY,INSENSITIVE,SCROLL關(guān)鍵字 可以以任何順序出現(xiàn)。
正常的游標(biāo)以文本格式返回?cái)?shù)據(jù),與SELECT產(chǎn)生的一樣。BINARY選項(xiàng)聲明 BINARY選項(xiàng)聲明游標(biāo)會返回二進(jìn)制格式的數(shù)據(jù)。這減少了服務(wù)器端和客戶端的轉(zhuǎn)換工作, 但代價(jià)卻是產(chǎn)生更多的處理基于平臺的二進(jìn)制數(shù)據(jù)格式的程序工作。 例如:如果一個(gè)查詢返回一個(gè)來自整型列的一個(gè)數(shù)值,你會得到一個(gè)帶有默認(rèn)游標(biāo)的1的 字符串,而通過一個(gè)二進(jìn)制游標(biāo)您會得到一個(gè)包含值的內(nèi)部表達(dá)的4字節(jié)字段(按大端字節(jié)順序)。
二進(jìn)制游標(biāo)應(yīng)當(dāng)謹(jǐn)慎使用。包括psql在內(nèi)的許多應(yīng)用,不準(zhǔn)備處理二進(jìn)制游標(biāo) 并且希望數(shù)據(jù)以文本形式返回。
Note: 當(dāng)客戶端應(yīng)用使用"extended query"協(xié)議來發(fā)布FETCH命令, Bind協(xié)議信息聲明是以文本形式還是以二進(jìn)制形式恢復(fù)數(shù)據(jù)。該選項(xiàng)重寫游標(biāo)定義 的方式。,當(dāng)使用任何光標(biāo)可以看作是文本或二進(jìn)制擴(kuò)展查詢協(xié)議 —同樣二 進(jìn)制游標(biāo)的概念因此過時(shí)。
除非聲明WITH HOLD,否則由該命令創(chuàng)建的游標(biāo)只能在當(dāng)前事務(wù)內(nèi)使用。 因此,不帶有WITH HOLD的DECLARE在事物塊之外是無效的: 游標(biāo)只能持續(xù)到語句完成。所以,若這樣一個(gè)命令在一個(gè)事務(wù)塊之外使用時(shí),PostgreSQL 或報(bào)告一個(gè)錯(cuò)誤。使用BEGIN和COMMIT (或者ROLLBACK)來定義一個(gè)事務(wù)塊。
如果聲明了WITH HOLD并且創(chuàng)建該游標(biāo)的事務(wù)成功提交,那么游標(biāo)還可以在同一會話 隨后的事務(wù)里訪問。但如果創(chuàng)建它的事務(wù)回滾,那么游標(biāo)被刪除。帶WITH HOLD創(chuàng)建 的游標(biāo)是用一個(gè)明確的CLOSE命令或者是會話終止來關(guān)閉的。在目前的實(shí)現(xiàn)里,由一 個(gè)游標(biāo)代表的行是被拷貝到一個(gè)臨時(shí)文件或者內(nèi)存區(qū)里的,這樣他們就仍然可以在隨后的事務(wù)中被訪問。
當(dāng)查詢包括FOR UPDATE或者FOR SHARE,WITH HOLD不會被聲明。
在定義一個(gè)要用來反向抓取的游標(biāo)的時(shí)候,應(yīng)該聲明SCROLL選項(xiàng),這是 SQL 標(biāo)準(zhǔn)要求的。 不過,為了和早期的版本兼容,只要游標(biāo)的查詢計(jì)劃簡單得不需要額外的開銷, PostgreSQL在沒有聲明SCROLL的時(shí)候也允許反向抓取。不過, 建議應(yīng)用開發(fā)人員不要依賴于使用沒有使用SCROLL定義的游標(biāo)的反向查找功能。如果 聲明了NO SCROLL,那么不管怎樣都會禁止反向抓取的功能。
當(dāng)查詢包括FOR UPDATE或者FOR SHARE時(shí),向讀取也是不允許的; 所以在這種情況下可能不會聲明SCROLL。
Caution |
滾動效果和WITH HOLD游標(biāo)可能會給出意想不到的結(jié)果,如果他們 調(diào)用任何易失函數(shù)(參閱Section 35.6)。當(dāng)一個(gè)已抓取的行 再次被抓取,函數(shù)可能會被重新執(zhí)行,可能會導(dǎo)致不同于第一次的結(jié)果。針對該情況的 一個(gè)工作區(qū)是為了聲明游標(biāo)WITH HOLD并且在閱讀其任意行之前提 交事務(wù)。這回強(qiáng)制游標(biāo)的整個(gè)輸出在臨時(shí)表中實(shí)現(xiàn),因此易失函數(shù)完全是為每一行執(zhí)行一次。 |
若游標(biāo)的查詢包括FOR UPDATE或者FOR SHARE,那么返回的行會在他們首次 被抓取時(shí)鎖定,與帶有這些選項(xiàng)的定期SELECT命令以相同的方式。 另外,返回的行將是最新的版本;因此,這些選項(xiàng)提供SQL標(biāo)準(zhǔn)中稱作"sensitive cursor" 的等價(jià)物。(聲明帶有FOR UPDATE或者FOR SHARE的INSENSITIVE 是錯(cuò)誤。)
Caution |
若游標(biāo)旨在與UPDATE ... WHERE CURRENT OF或者DELETE ... WHERE CURRENT OF 一起使用,那么通常建議使用FOR UPDATE。使用FOR UPDATE阻止其他會話 在其被抓去和更新之間的時(shí)間里改變行。沒有FOR UPDATE,一個(gè)隨后的 WHERE CURRENT OF命令將會沒有效果,如果行在游標(biāo)創(chuàng)建之后被改變。 使用FOR UPDATE的另一個(gè)原因是:沒有它,一個(gè)隨后的WHERE CURRENT OF 可能會失敗,若游標(biāo)查詢不滿足SQL標(biāo)準(zhǔn)對"simply updatable" 的規(guī)則(有錢,游標(biāo)必須 僅參考一個(gè)表并且不使用分組或者ORDER BY)。不是簡單可更新的游標(biāo)可能會工作或者 不會工作,這由計(jì)劃選擇的詳細(xì)情況決定;所以在最壞的情況下,一個(gè)應(yīng)用程序可能測試工作并然后 在生產(chǎn)中失敗。 不使用帶有WHERE CURRENT OF的FOR UPDATE的主要原因是:如果您 需要可卷動的游標(biāo),或者對后續(xù)更新不敏感(即繼續(xù)顯示舊數(shù)據(jù))。若這是一個(gè)要求, 密切關(guān)注以上顯示的警告。 |
SQL 標(biāo)準(zhǔn)中的游標(biāo)只能在嵌入SQL(ESQL)的應(yīng)用中使用。 PostgreSQL服務(wù)器沒有一個(gè)明確的OPEN語句; 一個(gè)游標(biāo)被認(rèn)為在定義時(shí)就已經(jīng)打開了。不過,PostgreSQL嵌入的 SQL 預(yù)編譯器(ECPG)支持 SQL 標(biāo)準(zhǔn)的習(xí)慣,包括那些和 DECLARE和OPEN相關(guān)的語句。
可以通過查詢pg_cursors 系統(tǒng)視圖看到所有可用游標(biāo)。
定義一個(gè)游標(biāo):
DECLARE liahona CURSOR FOR SELECT * FROM films;
參閱FETCH獲取有關(guān)游標(biāo)使用的更多例子。 See FETCH for more examples of cursor usage.
SQL標(biāo)準(zhǔn)認(rèn)為游標(biāo)是否對默認(rèn)的底層數(shù)據(jù)的并發(fā)更新敏感是依賴實(shí)現(xiàn)決定的。 在PostgreSQL中,游標(biāo)是默認(rèn)不敏感的,并且 可以通過聲明FOR UPDATE來使其敏感。其他產(chǎn)品可能以不同的方式工作。
SQL 標(biāo)準(zhǔn)只允許在嵌入的SQL中和模塊中使用游標(biāo)。 PostgreSQL允許交互地使用游標(biāo)。
二進(jìn)制游標(biāo)是PostgreSQL擴(kuò)展。