天天看點

Oracle解決主鍵ID自增問題觸發器序列--進階篇第一種 序列觸發器自增第二種 直接用觸發器自增ID

Oracle解決主鍵ID自增問題觸發器序列--進階篇

  • 第一種 序列觸發器自增
  • 第二種 直接用觸發器自增ID

第一種 序列觸發器自增

這個是流行的做法,廢話不多說直接上碼:

--簡單介紹一下序列參數的意思
CREATE SEQUENCE sequence  //建立序列名稱
       [INCREMENT BY n]  //遞增的序列值是n 如果n是正數就遞增,如果是負數就遞減 預設是1
       [START WITH n]    //開始的值,遞增預設是minvalue 遞減是maxvalue
       [{MAXVALUE n | NOMAXVALUE}] //最大值
       [{MINVALUE n | NOMINVALUE}] //最小值
       [{CYCLE | NOCYCLE}] //循環/不循環
       [{CACHE n | NOCACHE}];//配置設定并存入到記憶體中
   其中:

1)  INCREMENT BY用于定義序列的步長,如果省略,則預設為1,如果出現負值,則代表Oracle序列的值是按照此步長遞減的。

2)  START WITH 定義序列的初始值(即産生的第一個值),預設為1。

3)  MAXVALUE 定義序列生成器能産生的最大值。選項NOMAXVALUE是預設選項,代表沒有最大值定義,這時對于遞增Oracle序列,系統能夠産生的最大值是10的27次方;對于遞減序列,最大值是-1。

4)  MINVALUE定義序列生成器能産生的最小值。選項NOMAXVALUE是預設選項,代表沒有最小值定義,這時對于遞減序列,系統能夠産生的最小值是?10的26次方;對于遞增序列,最小值是1。

5)  CYCLE和NOCYCLE 表示當序列生成器的值達到限制值後是否循環。CYCLE代表循環,NOCYCLE代表不循環。如果循環,則當遞增序列達到最大值時,循環到最小值;對于遞減序列達到最小值時,循環到最大值。如果不循環,達到限制值後,繼續産生新值就會發生錯誤。

6)  CACHE(緩沖)定義存放序列的記憶體塊的大小,預設為20。NOCACHE表示不對序列進行記憶體緩沖。對序列進行記憶體緩沖,可以改善序列的性能。

大量語句發生請求,申請序列時,為了避免序列在運用層實作序列而引起的性能瓶頸。Oracle序列允許将序列提前生成 cache x個先存入記憶體,在發生大量申請序列語句時,可直接到運作最快的記憶體中去得到序列。但cache個數也不能設定太大,因為在資料庫重新開機時,會清空記憶體資訊,預存在記憶體中的序列會丢失,當資料庫再次啟動後,序列從上次記憶體中最大的序列号+1 開始存入cache x個。這種情況也能會在資料庫關閉時也會導緻序号不連續。

7)  NEXTVAL 傳回序列中下一個有效的值,任何使用者都可以引用。

8)  CURRVAL 中存放序列的目前值,NEXTVAL 應在 CURRVAL 之前指定 ,二者應同時有效。
-- 1.先建立一個從1開始到99999999每次增加1的遞增序列 ,名字為 TOOL_TB_SEQ
DROP SEQUENCE TOOL_TB_SEQ;    
CREATE SEQUENCE TOOL_TB_SEQ MINVALUE 1 MAXVALUE 99999999    
         INCREMENT BY 1    
         START WITH 1;
--2.再建立一個測試表
-- Create table
create table TEST_T
(
  id   number(20) not null,
  name varchar2(20)
)
;
-- Create/Recreate primary, unique and foreign key constraints 
alter table TEST_T
  add constraint TEST_ID primary key (ID); 
 --3.給建立的表添加一個插入觸發器 
 CREATE OR REPLACE TRIGGER TEST_T_TR
BEFORE INSERT ON TEST_T
FOR EACH ROW
  DECLARE
  BEGIN
    SELECT TOOL_TB_SEQ.nextval
    INTO :NEW.ID
    FROM dual;
  END;
--4.測試
INSERT INTO TEST_T
  (NAME)
VALUES
  ('2323');
--這個是基礎,我下面說的才是,入門進階,因為上面無法在我做資料庫轉換的時候起到幫助,當我表裡面已經有資料的時候,就要以自增ID的最大值+1來添加ID了。
           

第二種 直接用觸發器自增ID

上面我們已經說到當我們表裡已經有資料了,需要以表裡面ID的最大值+1來插入ID的時候,序列已經不滿足我們的需求了,這個時候觸發器它lei了。

不啰嗦,老規矩直接上碼:

--1.還是先建表TEST_T,偷個懶sql就不寫了,上面第一種方法裡有
--觸發器--
create or replace trigger TEST_T_TR
before insert on TEST_T/*觸發條件:當向表TEST_T執行插入操作時觸發此觸發器*/    
 for each row     /*對每一行都檢測是否觸發*/ 
   DECLARE   /*下面定義變量*/
 CURSOR CUR_TEST IS
  SELECT (CASE WHEN MAX(ID) is NULL THEN 0 ELSE max(ID) END)  AS ID TEST_T;    --定義遊标
begin   /*觸發器開始*/ 
  FOR V_TEST IN CUR_TEST  LOOP   --打開遊标
select  V_TEST .ID+1  into :new.ID from dual;   
END LOOP;   
end;
--3.測試一哈,打完收工。
           

竊以為第二種可能效率偏低,但也實質解決了我遇到的問題,如果各位還有更好的寫法,歡迎留言交流。

程式設計路漫漫,吾将上下而求索。