【Sequence】序列操作start with,nextval,currval三者之間的“複雜”關係與重要結論

secooler發表於2009-10-22
透過這篇文章談一下在使用Sequence時候需要注意的事項。細節重於一切。

1.建立測試用序列S
sec@ora10g> drop sequence s;
sec@ora10g> create sequence s start with 99;

Sequence created.

2.使用seq簡單檢視一下s的基本資訊
sec@ora10g> select * from seq where SEQUENCE_NAME = 'S';

SEQUENCE_NAME MIN_VALUE  MAX_VALUE INCREMENT_BY C O CACHE_SIZE LAST_NUMBER
------------- --------- ---------- ------------ - - ---------- -----------
S                     1 1.0000E+27            1 N N         20          99

3.使用dbms_metadata得到序列的詳細的建立語句
sec@ora10g> set linesize 150
sec@ora10g> set longchunksize 1000
sec@ora10g> select dbms_metadata.get_ddl('SEQUENCE','S') as "Create Sequence Statements" from dual;

Create Sequence Statements
------------------------------------------------------------------------------------------------------------------------------------------------------

   CREATE SEQUENCE  "SEC"."S"  MINVALUE 1 MAXVALUE 999999999999999999999999999 INCREMENT BY 1 START WITH 99 CACHE 20 NOORDER  NOCYCLE

透過上面的建立,我們得到的序列s是從99開始的。

4.在對s取nextval時,推測一下,得到的值是多少??
重要結論一:在初建立的Sequence上第一次使用nextval的時候,得到是初始值,不是初始值加一!
請看下面的演示,得到的是初始化的99值,不是100!!
sec@ora10g> select s.nextval from dual;

   NEXTVAL
----------
        99

如果此時再繼續取nextval的話,一切恢復正常
sec@ora10g> select s.nextval from dual;

   NEXTVAL
----------
       100

sec@ora10g> select s.nextval from dual;

   NEXTVAL
----------
       101

5.新開啟的session中允許直接使用currval取Sequence的當前值麼?
重要結論二:第一次NEXTVAL初始化之後才能使用CURRVAL取值。
sec@ora10g> conn sec/sec
Connected.
sec@ora10g> select s.currval from dual;
select s.currval from dual
       *
ERROR at line 1:
ORA-08002: sequence S.CURRVAL is not yet defined in this session

sec@ora10g> select s.nextval from dual;

   NEXTVAL
----------
       102

sec@ora10g> select s.currval from dual;

   CURRVAL
----------
       102

6.雖然上面看到currval必須在nextval之後使用,不過,可以在一條SQL語句中同時得到nextval和currval值,而且它們在SQL中不分先後順序,請看下面的演示。
sec@ora10g> conn sec/sec
Connected.
sec@ora10g> select s.currval from dual;
select s.currval from dual
*
ERROR at line 1:
ORA-08002: sequence S.CURRVAL is not yet defined in this session


sec@ora10g> select s.currval, s.nextval from dual;

   CURRVAL    NEXTVAL
---------- ----------
       103        103

sec@ora10g> conn sec/sec
Connected.
sec@ora10g> select s.currval from dual;
select s.currval from dual
*
ERROR at line 1:
ORA-08002: sequence S.CURRVAL is not yet defined in this session


sec@ora10g> select s.nextval, s.currval from dual;

   NEXTVAL    CURRVAL
---------- ----------
       104        104

7.將Oracle 10gR2官方文件關於序列的create和alter的命令語法copy一份在此,便於參考
CREATE SEQUENCE [ schema. ]sequence
   [ { INCREMENT BY | START WITH } integer
   | { MAXVALUE integer | NOMAXVALUE }
   | { MINVALUE integer | NOMINVALUE }
   | { CYCLE | NOCYCLE }
   | { CACHE integer | NOCACHE }
   | { ORDER | NOORDER }
   ]
     [ { INCREMENT BY | START WITH } integer
     | { MAXVALUE integer | NOMAXVALUE }
     | { MINVALUE integer | NOMINVALUE }
     | { CYCLE | NOCYCLE }
     | { CACHE integer | NOCACHE }
     | { ORDER | NOORDER }
     ]... ;


ALTER SEQUENCE [ schema. ]sequence
  { INCREMENT BY integer
  | { MAXVALUE integer | NOMAXVALUE }
  | { MINVALUE integer | NOMINVALUE }
  | { CYCLE | NOCYCLE }
  | { CACHE integer | NOCACHE }
  | { ORDER | NOORDER }
  }
    [ INCREMENT BY integer
    | { MAXVALUE integer | NOMAXVALUE }
    | { MINVALUE integer | NOMINVALUE }
    | { CYCLE | NOCYCLE }
    | { CACHE integer | NOCACHE }
    | { ORDER | NOORDER }
    ]... ;


8.小結
透過這個小實驗,得到的結論有:
1)結論一:在初建立的Sequence上第一次使用nextval的時候,得到是初始值,不是初始值加一!
2)結論二:第一次NEXTVAL初始化之後才能使用CURRVAL取值;
3)結論三:可以在一條SQL語句中同時得到nextval和currval值;
4)結論四:從上面的alter sequence的語法看,可以得到這樣一個結論,無法使用alter語句修改序列的當前值。

很有必要重點關注以上這些結論,尤其是第一條。

-- The End --

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/519536/viewspace-617172/,如需轉載,請註明出處,否則將追究法律責任。

相關文章