postgresql----serial類型和序列


postgresql序列號(SERIAL)類型包括smallserial(smallint,short),serial(int)和bigserial(bigint,long long int),不管是smallserial,serial還是bigserial,其范圍都是(1,9223372036854775807),但是序列號類型其實不是真正的類型,當聲明一個字段為序列號類型時其實是創建了一個序列,INSERT時如果沒有給該字段賦值會默認獲取對應序列的下一個值。

測試表1:

復制代碼
test=# create table tbl_serial(a serial,b varchar(2)); CREATE TABLE test=# \d tbl_serial Table "public.tbl_serial" Column | Type | Modifiers --------+----------------------+-------------------------------------------------------- a | integer | not null default nextval('tbl_serial_a_seq'::regclass) b | character varying(2) | 
復制代碼

 

從結果中看,聲明字段a為serial類型,會自動創建一個名為tbl_serial_a_seq的序列,INSERT時缺省為該序列的下一個序列值nextval。

自動創建的序列如下定義:

復制代碼
test=# \d tbl_serial_a_seq Sequence "public.tbl_serial_a_seq" Column | Type | Value ---------------+---------+--------------------- sequence_name | name | tbl_serial_a_seq last_value | bigint | 1 start_value | bigint | 1 increment_by | bigint | 1 max_value | bigint | 9223372036854775807 min_value | bigint | 1 cache_value | bigint | 1 log_cnt | bigint | 0 is_cycled | boolean | f is_called | boolean | f Owned by: public.tbl_serial.a
復制代碼

 

其實也可以先創建一個序列,然后將表的某字段默認值設為該序列的下一個序列值。

測試表2:

復制代碼
test=# create sequence sql_tbl_serial2_a increment by 1 minvalue 1 no maxvalue start with 1; CREATE SEQUENCE test=# create table tbl_serial2(a int not null default nextval('sql_tbl_serial2_a'),b varchar(2)); CREATE TABLE test=# \d tbl_serial2 Table "public.tbl_serial2" Column | Type | Modifiers --------+----------------------+--------------------------------------------------------- a | integer | not null default nextval('sql_tbl_serial2_a'::regclass) b | character varying(2) | test=# \d sql_tbl_serial2_a Sequence "public.sql_tbl_serial2_a" Column | Type | Value ---------------+---------+--------------------- sequence_name | name | sql_tbl_serial2_a last_value | bigint | 1 start_value | bigint | 1 increment_by | bigint | 1 max_value | bigint | 9223372036854775807 min_value | bigint | 1 cache_value | bigint | 1 log_cnt | bigint | 0 is_cycled | boolean | f is_called | boolean | f
復制代碼

 

此方法和第一種直接使用serial類型效果完全相同,但是這里可以自己定義序列名稱。

創建序列的語法如下:

 

復制代碼
test=# \h create sequence Command: CREATE SEQUENCE Description: define a new sequence generator Syntax: CREATE [ TEMPORARY | TEMP ] SEQUENCE [ IF NOT EXISTS ] name [ INCREMENT [ BY ] increment ] [ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ] [ START [ WITH ] start ] [ CACHE cache ] [ [ NO ] CYCLE ] [ OWNED BY { table_name.column_name | NONE } ]
復制代碼

 

 

 

其實和上面使用\d一個序列時對應的,

INCREMENT BY : 每次序列增加(或減少)的步長

MINVALUE : 序列最小值,NO MINVALUE表示沒有最小值

MAXVALUE : 序列最大值,NO MAXVALUE表示沒有最大值

START WITH :以什么序列值開始

CYCLE : 序列是否循環使用

OWNED BY : 可以直接指定一個表的字段,也可以不指定。

 

序列涉及的函數有:

函 數 返 回 類 型 描 述
currval( regclass ) bigint 獲取指定序列最近一次使用netxval后的數值,如果沒有使用nextval而直接使用currval會出錯。
lastval() bigint 返回最近一次用 nextval 獲取的任意序列的數值
nextval( regclass ) bigint 遞增序列並返回新值
setval( regclass,bigint ) bigint 設置序列的當前數值
setval( regclass,bigint ,boolean ) bigint 設置序列的當前數值以及 is_called 標志,如果為true則立即生效,如果為false,則調用一次nextval后才會生效。

 

 

 

 

 

 

 

 

示例1:獲取序列tbl_serial_a_seq當前序列值

 

復制代碼
test=# select currval('tbl_serial_a_seq'); ERROR: currval of sequence "tbl_serial_a_seq" is not yet defined in this session test=#  test=# select nextval('tbl_serial_a_seq'); nextval --------- 1 (1 row) test=# select currval('tbl_serial_a_seq'); currval --------- 1 (1 row)
復制代碼

 

 

 

示例2:獲取最近一次使用nextval的返回值

 

復制代碼
test=# select nextval('sql_tbl_serial2_a'); nextval --------- 5 (1 row) test=# select lastval(); lastval --------- 5 (1 row) test=# select nextval('tbl_serial_a_seq'); nextval --------- 3 (1 row) test=# select lastval(); lastval --------- 3 (1 row)
復制代碼

 

 

示例3:將序列tbl_serial_a_seq當前值設為100

 

 

復制代碼
test=# select setval('tbl_serial_a_seq',100); setval -------- 100 (1 row) test=# select currval('tbl_serial_a_seq'); currval --------- 100 (1 row)
復制代碼

 

 

示例4:使用is_called標志設置序列值是馬上生效(true)還是下次生效(false)

復制代碼
test=# select setval('tbl_serial_a_seq',200,true); setval -------- 200 (1 row) test=# select currval('tbl_serial_a_seq'); currval --------- 200 (1 row) test=# select setval('tbl_serial_a_seq',300,false); setval -------- 300 (1 row) test=# select currval('tbl_serial_a_seq'); currval --------- 200 (1 row) test=# select nextval('tbl_serial_a_seq'); nextval --------- 300 (1 row) test=# select currval('tbl_serial_a_seq'); currval --------- 300 (1 row)
復制代碼

 

 

修改序列和創建序列的語法基本相同,只是用ALTER替換了CREATE,請參考

 

復制代碼
test=# \h alter sequence Command: ALTER SEQUENCE Description: change the definition of a sequence generator Syntax: ALTER SEQUENCE [ IF EXISTS ] name [ INCREMENT [ BY ] increment ] [ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ] [ START [ WITH ] start ] [ RESTART [ [ WITH ] restart ] ] [ CACHE cache ] [ [ NO ] CYCLE ] [ OWNED BY { table_name.column_name | NONE } ]
復制代碼

 

 

 

如果一個序列是NO CYCLE,當序列值全部使用完會怎樣呢?

 

復制代碼
test=# create sequence seq_test increment by 2 MINVALUE 1 MAXVALUE 5 START WITH 2 NO CYCLE; CREATE SEQUENCE test=# \d seq_test Sequence "public.seq_test" Column | Type | Value ---------------+---------+---------- sequence_name | name | seq_test last_value | bigint | 2 start_value | bigint | 2 increment_by | bigint | 2 max_value | bigint | 5 min_value | bigint | 1 cache_value | bigint | 1 log_cnt | bigint | 0 is_cycled | boolean | f is_called | boolean | f test=# select nextval('seq_test'); nextval --------- 2 (1 row) test=# select nextval('seq_test'); nextval --------- 4 (1 row) test=# select nextval('seq_test'); ERROR: nextval: reached maximum value of sequence "seq_test" (5)
復制代碼

 

如果序列值用完了當然是錯誤了!!!如果是CYCLE則會重新從START處開始再次循環。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM