ORACLE中的序列和觸發器
序列:
序列(SEQUENCE)是序號產生器,可以為表中的行自動產生序號,產生一組等間隔的數值(類型為數字)。其主要的用途是產生表的主索引值,可以在插入語句中引用,也可以通過查詢檢查當前值,或使序列增至下一個值。
建立序列需要CREATE SEQUENCE系統許可權。序列的建立文法如下:
CREATE SEQUENCE 序列名 [INCREMENT BY n] [START WITH n] [{MAXVALUE/ MINVALUE n|NOMAXVALUE}] [{CYCLE|NOCYCLE}] [{CACHE n|NOCACHE}]; |
INCREMENT BY 用於定義序列的步長,如果省略,則預設為1,如果出現負值,則代表序列的值是按照此步長遞減的。
START WITH 定義序列的初始值(即產生的第一個值),預設為1。
MAXVALUE 定義序列產生器能產生的最大值。選項NOMAXVALUE是預設選項,代表沒有最大值定義,這時對於遞增序列,系統能夠產生的最大值是10的27次方;對於遞減序列,最大值是-1。
MINVALUE定義序列產生器能產生的最小值。選項NOMAXVALUE是預設選項,代表沒有最小值定義,這時對於遞減序列,系統能夠產生的最小值是?10的26次方;對於遞增序列,最小值是1。
CYCLE和NOCYCLE 表示當序列產生器的值達到限制值後是否迴圈。CYCLE代表迴圈,NOCYCLE代表不迴圈。如果迴圈,則當遞增序列達到最大值時,迴圈到最小值;對於遞減序列達到最小值時,迴圈到最大值。如果不迴圈,達到限制值後,繼續產生新值就會發生錯誤。
CACHE(緩衝)定義存放序列的記憶體塊的大小,預設為20。NOCACHE表示不對序列進行記憶體緩衝。對序列進行記憶體緩衝,可以改善序列的效能。
刪除序列的文法是:
其中:
刪除序列的人應該是序列的建立者或擁有DROP ANY SEQUENCE系統許可權的使用者。序列一旦刪除就不能被引用了。
序列的某些部分也可以在使用中進行修改,但不能修改SATRT WITH選項。對序列的修改隻影響隨後產生的序號,已經產生的序號不變。修改序列的文法如下:
建立和刪除序列
例1:建立序列:
CREATE SEQUENCE ABC INCREMENT BY 1 START WITH 10 MAXVALUE 9999999 NOCYCLE NOCACHE;
執行結果
序列已建立。
步驟2:刪除序列:
DROP SEQUENCE ABC;
執行結果:
序列已丟棄。
說明:以上建立的序列名為ABC,是遞增序列,增量為1,初始值為10。該序列不迴圈,不使用記憶體。沒有定義最小值,預設最小值為1,最大值為9 999 999。
【案例一】
題目:
--觸發器:
--添加員工資訊,流水號作為自動編號(通過序列產生),
--並且判斷如果工資小於0,則改為0;如果大於10000,則改為10000。
CREATE TABLE emp2(
e_id NUMBER,
e_no NUMBER,
e_name VARCHAR2(20),
e_sal NUMBER
)
SELECT * FROM emp2;
CREATE SEQUENCE seq_trg_id;
INSERT INTO emp2(e_id,e_no,e_name,e_sal) VALUES(seq_trg_id.nextval,7788,'章子',
1000000000000)
INSERT INTO emp2(e_id,e_no,e_name,e_sal) VALUES(seq_trg_id.nextval,7788,'章子怡',-10)
CREATE OR REPLACE TRIGGER trg_add_emp_info
BEFORE INSERT
ON emp2
FOR EACH ROW
DECLARE
-- local variables here
BEGIN
SELECT seq_trg_id.NEXTVAL INTO :NEW.e_id FROM dual;
IF :NEW.e_sal < 0 THEN
:NEW.e_sal := 0;
ELSIF :NEW.e_sal > 10000 THEN
:NEW.e_sal := 10000;
END IF;
END;
【 案例二】
題目:
--擴充練習:
--為emp建立觸發器,將刪除的記錄放到emp3表中(autoid,deptno,empno,ename,del_rq-刪除日期)
--測試代碼
CREATE TABLE emp3(
autoid NUMBER PRIMARY KEY,
deptno NUMBER,
empno NUMBER,
ename VARCHAR2(20),
del_rq DATE
)
CREATE SEQUENCE seq_trg_del_autoid;
INSERT INTO emp
(empno, ename, deptno)
VALUES
(114, '阿嬌', 10);
COMMIT;
SELECT * FROM emp;
DELETE emp WHERE empno = 114;
SELECT * FROM emp3;
答案:
CREATE OR REPLACE TRIGGER trg_del_emp_info
BEFORE DELETE
ON emp
FOR EACH ROW
DECLARE
-- local variables here
BEGIN
INSERT INTO emp3(autoid,deptno,empno,ename,del_rq)
VALUES(seq_trg_del_autoid.NEXTVAL,:OLD.deptno,:OLD.empno,:OLD.ename,sysdate);
END;