posts - 188,comments - 176,trackbacks - 0

          Sequence是數據庫系統按照一定規則自動增加的數字序列。這個序列一般作為代理主鍵(因為不會重復),沒有其他任何意義。

          Sequence是數據庫系統的特性,有的數據庫有Sequence,有的沒有。比如Oracle、DB2、PostgreSQL數據庫有Sequence,MySQL、SQL Server、Sybase等數據庫沒有Sequence。

          根據我個人理解,Sequence是數據中一個特殊存放等差數列的表,該表受數據庫系統控制,任何時候數據庫系統都可以根據當前記錄數大小加上步長來獲取到該表下一條記錄應該是多少,這個表沒有實際意義,常常用來做主鍵用,非常不錯,呵呵,不過很郁悶的各個數據庫廠商尿不到一個壺里--各有各的一套對Sequence的定義和操作。在此我對常見三種數據庫的Sequence的定義和操作做一個對比和總結,以便日后查看。


          一、定義Sequence

          定義一個seq_test,最小值為1,最大值為99999999999999999,從1開始,增量的步長為1,緩存為20的循環排序Sequence。

          Oracle的定義方法:
          create sequence seq_test
          minvalue 1
          maxvalue 99999999999999999
          start with 1
          increment by 1
          cache 20
          cycle
          order;

          DB2的寫法:
          create sequence seq_test
                 as bigint
                 start with 20000
                 increment by 1
                 minvalue 10000
                 maxvalue 99999999999999999
                 cycle
                 cache 20
                 order;

          PostgreSQL的寫法:
          create sequence seq_test
                 increment by 1
                 minvalue 10000
                 maxvalue 99999999999999999
                 start 20000
                 cache 20
                 cycle;


          二、Oracle、DB2、PostgreSQL數據庫Sequence值的引用參數為:currval、nextval,分別表示當前值和下一個值。

          下面分別從三個數據庫的Sequence中獲取nextval的值。

          Oracle中:seq_test.nextval
          例如:select seq_test.nextval from dual;
          DB2中:nextval for SEQ_TOPICMS
          例如:values nextval for seq_test;
          PostgreSQL中:nextval(seq_test)
          例如:select nextval(seq_test);


          三、Sequence與indentity的區別與聯系

          Sequence與indentity的基本作用都差不多。都可以生成自增數字序列。
          Sequence是數據庫系統中的一個對象,可以在整個數據庫中使用,和表沒有任何關系;indentity僅僅是指定在表中某一列上,作用范圍就是這個表。

           

          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的值,所以如果你在不同的SQl語句里面使用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; 

           

          下面詳細介紹NEXTVAL和CURRVAL用法以及sequence用法的限制


          使用 NEXTVAL

          第一次訪問一個序列,在引用 sequence.CURRVAL 之前必須先引用 sequence.NEXTVAL。第一次引用 NEXTVAL,返回序列的初始值。后面每次引用 NEXTVAL,用已定義的 step 增加序列值并返回序列新的增加以后的值。

          在一個 SQL 語句中只能對給定的序列增加一次。即使在一個語句中多次指定 sequence.NEXTVAL,序列也只增加一次,所以每次 sequence.NEXTVAL 出現在同一 SQL 語句中返回相同的值。除了在同一語句中多次出現這種情況以外,每個sequence.NEXTVAL表達式都會增加序列,無論后來是否提交或回滾當前事務。如果在最終回滾的事務中指定sequence.NEXTVAL,某些序列數可能被跳過。

          如在PL/SQL中:
          查詢nextval的值等于151
          select cheng.nextval from test1234 
          執行insert語句
          insert into test1234 values(cheng.nextval,'bb',22);
          commit或rollback后再查詢nextval的值會增加到153


          使用 CURRVAL

          任何對CURRVAL的引用返回指定序列的當前值,該值是最后一次對NEXTVAL的引用所返回的值。用NEXTVAL生成一個新值以后,可以繼續使用 CURRVAL訪問這個值,不管另一個用戶是否增加這個序列。如果sequence.CURRVAL和 sequence.NEXTVAL都出現在一個 SQL語句中,則序列只增加一次。在這種情況下,每個sequence.CURRVAL和 sequence.NEXTVAL表達式都返回相同的值,不管在語句中sequence.CURRVAL和sequence.NEXTVAL的順序。

          如在PL/SQL中:
          select cheng.nextval,cheng.currval from test1234
          nextval和currval的值都是160


          序列的并發訪問

          序列總是在數據庫中生成唯一值,即使當多個用戶并發地引用同一序列時也沒有可察覺的等待或鎖定。當多個用戶使用 NEXTVAL 來增長序列時,每個用戶生成一個其他用戶不可見的唯一值。當多個用戶并發地增加同一序列時,每個用戶看到的值是有差異的。例如,一個用戶可能從一個序列生成一組值,如 11、14、16 和 18,而另一個用戶并發地從同一序列生成值 12、13、15 和 17。


          sequence使用的限制

          NEXTVAL 和 CURRVAL 只在 SQL 語句中有效,并不在 SPL 語句中直接有效。(但是使用NEXTVAL 和CURRVAL的SQL語句可用于SPL例程)以下限制應用于 SQL 語句中的這些運算符:


          [1]在 CREATE TABLE 或 ALTER TABLE 語句中,在下列上下文中不能指定 NEXTVAL 或 CURRVAL:
             在 DEFAULT 子句中。
             在檢查約束中。

          [2]在 SELECT 語句中,下列上下文中不能指定 NEXTVAL 或 CURRVAL:
             使用 DISTINCT 關鍵字時在投影列表中。
             在 WHERE、GROUP BY 或 ORDER BY 子句中。
             在子查詢中。
             在 UNION 運算符結合 SELECT 語句時。

          [3]在下列這些上下文中也不能指定 NEXTVAL 或 CURRVAL:
             在分段存儲表達式中
             在對另一個數據庫中的遠程序列對象的引用中。


          Oracle中實現類似自動增加 ID 的功能

          我們經常在設計數據庫的時候用一個系統自動分配的ID來作為我們的主鍵,但是在ORACLE 中沒有這樣的 功能,我們可以通過采取以下的功能實現自動增加ID的功能.

          1.首先創建 sequence
          create sequence seqmax increment by 1
          2.使用方法
          select seqmax.nextval id from dual
          就得到了一個和ms sql的自動增加ID相同的功能id值

           

          轉:http://baike.baidu.com/view/71967.htm    
                  http://blog.csdn.net/liuya1985liuya/archive/2006/11/13/1381204.aspx
           

          posted on 2008-04-17 19:39 cheng 閱讀(1827) 評論(0)  編輯  收藏 所屬分類: Oracle
          主站蜘蛛池模板: 托克逊县| 富宁县| 凤阳县| 柘城县| 达州市| 无锡市| 通化县| 潜山县| 昆明市| 莱西市| 泸溪县| 茂名市| 同心县| 西华县| 巴林左旗| 福贡县| 合山市| 安义县| 焦作市| 分宜县| 山西省| 安远县| 邻水| 阜康市| 临朐县| 遂平县| 南部县| 万源市| 旬阳县| 黔西| 民和| 隆尧县| 英山县| 镇巴县| 勐海县| 洞口县| 龙泉市| 姜堰市| 辽源市| 杂多县| 客服|