Oracle中Nextval用法SEQUENCE與SYS_GUID()
名稱
CREATE SEQUENCE -- 建立一個新的序列發生器
語法
CREATE [ TEMPORARY | TEMP ] SEQUENCE name [ INCREMENT [ BY ] increment ]
[ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ]
[ START [ WITH ] start ] [ CACHE cache ] [ [ NO ] CYCLE ]
[ OWNED BY { table.column | NONE } ]
描述
CREATE SEQUENCE
將向當前資料庫裡增加一個新的序列號生成器。 包括建立和初始化一個新的名為 name的單行表。生成器將為使用此命令的使用者所有。
如果給出了一個模式名,那麼該序列是在指定模式中建立的。 否則它會在當前模式中建立臨時序列存在於一個特殊的模式中,因此如果建立一個臨時序列的時候, 不能給出模式名。 序列名必需和同一模式中的其他序列,表,索引,或者檢視不同。
在建立序列後,你可以使用 nextval, currval, setval
函式操作序列。。這些函式在 Section 9.12 中有詳細文件。
儘管你不能直接更新一個序列,但你可以使用象
SELECT * FROM name;
檢查一個序列的引數和當前狀態。特別是序列的 last_value
欄位顯示了任意後端程式分配的最後的數值。 (當然,這些值在被列印出來的時候可能已經過時了 — 如果其它程式正積極地使用 nextval
。)
引數
TEMPORARY
或 TEMP
如果宣告瞭這個修飾詞,那麼該序列物件只為這個會話建立, 並且在會話結束的時候自動刪除。在臨時序列存在的時候, 同名永久序列是不可見的(在同一會話裡),除非它們是用模式修飾的名字引用的。 www.2cto.com
name
將要建立的序列號名(可以用模式修飾)。
increment
可選子句 INCREMENT BY increment
要建立一個新的值,應該向當前序列值上增加什麼。一個正數將生成一個遞增的序列, 一個負數將生成一個遞減的序列。預設值是一(1)。
minvalue
NO MINVALUE
可選的子句 MINVALUE minvalue
決定一個序列可生成的最小值。 如果沒有宣告這個子句或者宣告瞭 NO MINVALUE
,那麼就使用預設。 預設分別是遞增序列為 1 遞減為 -263-1。
maxvalue
NO MAXVALUE
使用可選子句 MAXVALUE maxvalue
決定序列的最大值。 如果沒有宣告這個子句或者宣告瞭 NO MAXVALUE
,那麼就使用預設。 預設的分別是遞增為 -263-1,遞減為 -1。
start
可選的 START WITH start
子句 使序列可以從任意位置開始。預設初始值是遞增序列為 minvalue
遞減序列為 maxvalue
.
cache
CACHE cache 選項使序列號預分配並且為快速訪問儲存在記憶體裡面。 最小值(也是預設值)是1(一次只能生成一個值, 也就是說沒有快取)這也是預設。
CYCLE
NO CYCLE
可選的CYCLE關鍵字可用於使序列到達 最大值(maxvalue) 或 最小值(minvalue) 時可復位並繼續下去。如果達到極限,生成的下一個資料將分別是 最小值(minvalue) 或 最大值(maxvalue)。
如果宣告瞭可選的關鍵字 NO CYCLE
, 那麼在序列達到其最大值之後任何對 nextval
的呼叫都強返回一個錯誤。 如果既沒有宣告 CYCLE
也沒有宣告 NO CYCLE
, 那麼 NO CYCLE
是預設。
注意
使用 DROP SEQUENCE
語句來刪除序列。
序列是基於 bigint
運算的,因此其範圍不能超過八位元組的整數範圍(-9223372036854775808
到 9223372036854775807
)。 在一些老一點的平臺上可能沒有對八位元組整數的編譯器支援, 這種情況下序列使用普通的 integer
運算(範圍是 -2147483648
到 +2147483647
)。
如果 cache
設定大於一, 並且這個序列物件將被用於併發多會話的場合,那麼可能會有不可預料的結果發生。 每個會話在一次訪問序列物件的過程中將分配並快取隨後的序列值,並且相應增加序列物件的 last_value
。 這樣,同一個事務中的隨後的 cache-1
次 nextval
將只是返回預先分配的數值,而不用動序列物件。因此,任何在一個會話中分配但是沒有使用的數字都將在會話結尾丟失,導致序列裡面出現"空洞"。
另外,儘管系統保證為多個會話分配獨立的序列值,但是如果考慮所有會話, 那麼這個數值可能會丟失順序。比如,如果 cache
設定為 10
,那麼會話 A 保留了 1…10 並且返回 nextval=1
, 然後會話 B 可能會保留 11…20 然後在會話 A 生成 nextval=2
之前返回 nextval=11
。因此,對於 cache
設定為一的情況,我們可以安全地假設nextval
值是順序生成的; 而如果把 cache
設定得大於一, 那麼你只能假設 nextval
值總是唯一得,而不是完全順序地生成。 同樣,last_value
將反映任何會話保留的最後的數值,不管它是否曾被 nextval
返回。
另外一個考慮是在這樣的序列上執行的 setval
將不會被其它會話注意到,直到它們用光他們快取的數值。
例子
建立一個叫 serial 的遞增序列,從101開始:
CREATE SEQUENCE serial START 101;
從此序列中選出下一個數字:
SELECT nextval ('serial');
nextval
-------
114
在一個 INSERT 中使用此序列:
INSERT INTO distributors VALUES (nextval('serial'),'nothing');
在一個 COPY FROM
後更新序列:
BEGIN;
COPY distributors FROM 'input_file'; SELECT setval('serial', max(id)) FROM distributors;
END;
相容性
CREATE SEQUENCE
在 SQL:2003 裡宣告。
PostgreSQL 遵循標準,只有下面的例外:
- 還不支援標準的
AS <資料型別>
表示式。 - 獲取下一個數值是用
nextval()
函式不是標準的,而標準是用NEXT VALUE FOR 表示式
。 OWNED BY
子句是 PostgreSQL 的擴充套件
Oracle 中Nextval
用法
SQL Server
,Sybase
:
有個identity
屬性可以讓系統自動增1
CREATE TABLE a
(
a1 INT IDENTITY(1, 1),
a2 VARCHAR(6)
)
然後在insert時:
insert into a values( 'hello! '); --不用管a1,系統會幫你自動增1
Oracle:
使用SEQUENCE(序列)
可以達到你的要求
CREATE TABLE a
(
a1 INT,
a2 VARCHAR2(6)
);
CREATE SEQUENCE seq_a
INCREMENT BY 1;
然後在insert時:
insert into a values(seq_a.nextval, 'hello! '); --seq_a.nextval是該序列的下個值
ORACLE利用Sequence
實現欄位自增長
在oracle中sequence
就是所謂的序列號,每次取的時候它會自動增加,一般用在需要按序列號排序的地方。
1、Create Sequence
你首先要有CREATE SEQUENCE
或者CREATE ANY SEQUENCE
許可權,
CREATE SEQUENCE emp_sequence
INCREMENT BY 1 -- 每次加幾個
START WITH 1 -- 從1開始計數
NOMAXVALUE -- 不設定最大值
NOCYCLE -- 一直累加,不迴圈
CACHE 10;
一旦定義了emp_sequence
,你就可以用CURRVAL
,NEXTVAL
CURRVAL=返回 sequence的當前值
NEXTVAL=增加sequence的值,然後返回 sequence 值
比如:
emp_sequence.CURRVAL
emp_sequence.NEXTVAL
可以使用sequence
的地方:
-
不包含子查詢、snapshot、VIEW的 SELECT 語句
-
INSERT語句的子查詢中
-
NSERT語句的VALUES中
-
UPDATE 的 SET中
可以看如下例子:
INSERT INTO emp VALUES
(empseq.nextval, 'LEWIS', 'CLERK',7902, SYSDATE, 1200, NULL, 20);
SELECT empseq.currval FROM DUAL;
但是要注意的是:
-
第一次
NEXTVAL
返回的是初始值;隨後的NEXTVAL
會自動增加你定義的INCREMENT BY
值,然後返回增加後的值。CURRVAL
總是返回當前SEQUENCE
的值,但是在第一次NEXTVAL
初始化之後才能使用CURRVAL
,否則會出錯。一次NEXTVAL
會增加一次SEQUENCE
的值,所以如果你在同一個語句裡面使用多個NEXTVAL
,其值就是不一樣的。明白? -
如果指定
CACHE
值,ORACLE
就可以預先在記憶體裡面放置一些sequence
,這樣存取的快些。cache
裡面的取完後,oracle自動再取一組到cache。使用cache或許會跳號, 比如資料庫突然不正常down掉(shutdown abort),cache中的sequence就會丟失. 所以可以在create sequence
的時候用nocache
防止這種情況。
2、Alter Sequence
你或者是該sequence的owner,或者有ALTER ANY SEQUENCE 許可權才能改動sequence. 可以alter除start至以外的所有sequence引數.如果想要改變start值,必須 drop sequence
再 re-create
.
Alter sequence 的例子
ALTER SEQUENCE emp_sequence
INCREMENT BY 10
MAXVALUE 10000
CYCLE -- 到10000後從頭開始
NOCACHE ;
影響Sequence
的初始化引數:
SEQUENCE_CACHE_ENTRIES =設定能同時被cache的sequence數目。
可以很簡單的Drop Sequence
DROP SEQUENCE order_seq;
SYS_GUID()與sequence的比較
列生成器sequence
所生成的數字只能保證在單個例項裡是唯一的,這就不適合將它用作並行或者遠端環境裡的主關鍵字,因為各自環境裡的序列可能會生成相同的數字,從而導致衝突的發生。
SYS_GUID
會保證它建立的識別符號在每個資料庫裡都是唯一的。
此外,序列必須是DML陳述式的一部分,因此它需要一個到資料庫的往返過程(否則它就不能保證其值是唯一的)。
SYS_GUID
源自不需要對資料庫進行訪問的時間戳和機器識別符號,這就節省了查詢的消耗。
create table use_seq_table(id integer);
create sequence use_seq_sequence;
insert into use_seq_table values (use_seq_sequence.nextval);
create table use_guid_table(id raw(16));
insert into use_guid_table(sys_guid());
物件在不同機器的不同資料庫裡生成以及需要將資料合併到一起的情況下,SYS_GUID
很有用。
SYS_GUID()
與sequence
的作用及用法基本相同,都可以放在bi觸發器中使用。
-- Create sequence
create sequence SEQ_ADDRESS
minvalue 1
maxvalue 999999999999999999999999999
start with 1
increment by 1
nocache;
create or replace trigger tri_address_bi before insert on address for each row
begin
if :new.id<0 or :new.id is null then
select seq_address.nextval into :new.id from dual;
--select substr(sys_guid(),1,32) into :new.id from dual;
end if;
end;
/
使用限制:
SYS_GUID
生成的值的另一個顯著的不足之處是,管理這些值會變得困難得多。你必須(手動)輸入它們或者通過指令碼來填充它們,或者將它們作為Web引數來傳遞。
出於這些原因,將SYS_GUID
作為一個主關鍵字不是一個很好主意,除非是在一個並行的環境裡或者希望避免使用管理序列生成器的情況下。
不過,使用SYS_GUID
來做主鍵也不是不可以,但需要先轉為 varchar2
較好。最好在使用時顯示轉換一下,如:substr(sys_guid(),1,32)
,直接使用RAW
顯然是不合適的。
直接插 raw
進入 varchar2
欄位,發生隱式的轉換,總不是太妥。曾見過因為大量隱式轉換導致最後資料庫崩潰,當然事後看是資料庫的bug
了。
相關文章
- oracle中的CURRVAL和NEXTVAL用法Oracle
- ORACLE SEQUENCE用法Oracle
- Oracle中Sequence的使用Oracle
- oracle中sequence使用的限制Oracle
- 【Sequence】序列操作start with,nextval,currval三者之間的“複雜”關係與重要結論
- Oracle中sequence cache的測試Oracle
- Oracle中sequence的使用方法Oracle
- ORACLE SEQUENCEOracle
- Oracle - Sequence序列Oracle
- Oracle Sequence NocacheOracle
- Oracle序列sequenceOracle
- oracle中top用法Oracle
- Oracle中with的用法Oracle
- Oracle中group by用法Oracle
- Oracle之Sequence(序列)Oracle
- Oracle Sequence Audses$研究Oracle
- oracle sequence語法Oracle
- oracle sequence 試用Oracle
- 【 Oracle中rownum的用法 】Oracle
- Oracle 中 case的用法Oracle
- 在Hibernate中關於Oracle sequence的使用KHOracle
- oracle的scn及sequenceOracle
- 筆記:Oracle - sys_guid()直接select亂碼筆記OracleGUI
- js中的||與&&用法JS
- oracle中substr() instr() 用法Oracle
- oracle樹中prior的用法Oracle
- Oracle中rowid的用法Oracle
- 【oracle中rowid的用法】Oracle
- oracle中merge into用法解析Oracle
- Oracle PL/SQL中EXCEPTION用法OracleSQLException
- oracle中copy from的用法Oracle
- ORACLE 中ROWNUM用法總結!Oracle
- ORACLE 中ROWNUM用法總結Oracle
- Sequence 批量更改與建立
- 【TUNE_ORACLE】Oracle Hint之概念與用法Oracle
- 【轉】MySQL中增加sequence管理功能(模擬建立sequence)MySql
- ORACLE中ESCAPE關鍵字用法Oracle
- Oracle中select ... for update的用法Oracle