PostgreSQL 序列操作函數(shù)

2021-08-27 10:20 更新

本節(jié)描述對sequence objects進(jìn)行操作的函數(shù),也稱為序列生成器或序列。 序列對象是使用CREATE SEQUENCE創(chuàng)建的特殊單行表。 序列對象通常用于為表中的行生成惟一標(biāo)識符。在表 9.50中列出的序列函數(shù),提供了簡單的、多用戶安全方法,用于從序列對象中獲取連續(xù)的序列值。

表 9.50. 序列函數(shù)

函數(shù)

描述

nextval ( regclass ) → bigint

將序列對象推進(jìn)到下一個值并返回該值。這是自動完成的:即使多個會話并發(fā)地執(zhí)行nextval,每個會話也會安全地接收到不同的序列值。 如果序列對象是用默認(rèn)形參創(chuàng)建的,則連續(xù)的nextval調(diào)用將返回以1開始的連續(xù)值。 其他行為可以通過在 CREATE SEQUENCE 命令中使用適當(dāng)?shù)膮?shù)獲得。

這個函數(shù)需要USAGEUPDATE特權(quán)在序列上。

setval ( regclass, bigint [, boolean ] ) → bigint

設(shè)置序列對象的當(dāng)前值,以及可選的它的is_called標(biāo)志。 雙參數(shù)形式將序列的last_value字段設(shè)置為指定的值,并將其is_called字段設(shè)置為true,意味著下一個nextval將在返回值之前推進(jìn)序列。 currval將報告的值也設(shè)置為指定的值。在三參數(shù)形式中,is_called可以設(shè)置為truefalsetrue與雙參數(shù)形式具有相同的效果。 如果設(shè)置為false,下一個nextval將返回指定的值,序列推進(jìn)從下面的 nextval開始。 而且,currval報告的值在這種情況下不會改變。例如,

SELECT setval('myseq', 42);           Next nextval will return 43
SELECT setval('myseq', 42, true);     Same as above
SELECT setval('myseq', 42, false);    Next nextval will return 42

setval返回的結(jié)果就是它的第二個參數(shù)的值。

這個函數(shù)在序列上需要UPDATE特權(quán)。

currval ( regclass ) → bigint

返回nextval在當(dāng)前會話中為該序列最近獲取的值。(如果在這個會話中沒有為這個序列調(diào)用nextval會報告錯誤。) 因?yàn)樗祷氐氖且粋€會話本地值,所以它給出了一個可預(yù)測的答案,即自當(dāng)前會話以來,其他會話是否執(zhí)行了nextval。

這個函數(shù)需要序列上的USAGESELECT特權(quán)。

lastval () → bigint

返回nextval在當(dāng)前會話中最近返回的值。這個函數(shù)與currval相同,不同之處在于它沒有使用序列名作為參數(shù),而是引用當(dāng)前會話中nextval最近應(yīng)用到的序列。 如果在當(dāng)前會話中還沒有調(diào)用nextval,那么調(diào)用lastval是一個錯誤。

該函數(shù)在最后使用的序列上需要USAGESELECT特權(quán)。


小心

為了避免阻塞從相同序列中獲取數(shù)字的并發(fā)事務(wù),nextval操作永遠(yuǎn)不會回滾;也就是說,一旦獲取了一個值,它就會被認(rèn)為是已使用的,并且不會再次返回。 即使周圍的事務(wù)隨后中止,或者調(diào)用查詢最終沒有使用該值,也會出現(xiàn)這種情況。 例如,帶有ON CONFLICT子句的INSERT將計算要插入的元組,包括執(zhí)行任何必需的nextval調(diào)用,在檢測到任何可能導(dǎo)致它遵循 ON CONFLICT規(guī)則的沖突之前。 這種情況會在賦值序列中留下未使用的holes。因此,PostgreSQL序列對象不能被用于獲取 gapless序列 。

同樣的,如果事務(wù)回滾,setval所做的任何序列狀態(tài)更改都不會撤消。

序列函數(shù)所要操作的序列由regclass參數(shù)指定,該參數(shù)只是pg_class系統(tǒng)目錄中序列的OID。 你不必手工查找OID,不過,因?yàn)?code class="type">regclass數(shù)據(jù)類型的輸入轉(zhuǎn)換器將為您完成這項(xiàng)工作。 只需將序列名用單引號括起來,這樣它看起來就像一個文字常量。 為了與處理普通SQL名稱兼容,字符串將被轉(zhuǎn)換為小寫,除非它在序列名稱周圍包含雙引號。因此:

nextval('foo') 序列上操作 foo
nextval('FOO') 序列上操作 foo
nextval('"Foo"')
        序列上操作 Foo
            
            

如需要,序列名稱可以是模式限定的:

nextval('myschema.foo')     操作 myschema.foo
nextval('"myschema".foo')   同上
nextval('foo')              在搜索路徑中查找 foo

關(guān)于regclass的更多信息請參見第 8.19 節(jié)。

注意

PostgreSQL 8.1 之前,序列函數(shù)的參數(shù)類型是text, 而不是 regclass,并且前文所述的從文本串到 OID 值的轉(zhuǎn)換將在每次調(diào)用的時候發(fā)生。 為了向后兼容,這個處理仍然存在,但是在內(nèi)部實(shí)際上是通過在函數(shù)調(diào)用前隱式地將text轉(zhuǎn)換成regclass實(shí)現(xiàn)的。

當(dāng)你把一個序列函數(shù)的參數(shù)寫成一個無修飾的文字串,那么它將變成類型為regclass的常量。 因?yàn)檫@只是一個 OID,它將跟蹤最初標(biāo)識的序列,而不管后面是否改名、模式變化等等。 這種早期綁定的行為通常是列默認(rèn)值和視圖中引用的序列所需要的。 但是有時候你可能想要延遲綁定,其中序列的引用是在運(yùn)行時解析的。 要得到延遲綁定的行為,我們可以強(qiáng)制常量被存儲為text常量,而不是regclass

nextval('foo'::text)      foo is looked up at runtime

請注意,延遲綁定是PostgreSQL版本 8.1 之前唯一被支持的行為, 因此你可能需要做這些來保留舊應(yīng)用的語義。

當(dāng)然,序列函數(shù)的參數(shù)也可以是表達(dá)式。如果它是一個文本表達(dá)式,那么隱式的轉(zhuǎn)換將導(dǎo)致運(yùn)行時的查找。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號