透過觸發器複製包含LONG型別的表
前兩天論壇上有人問如何才能透過觸發器來實現對包含LONG或LONG RAW型別欄位的表的複製。給他做了個最簡單的例子,在這裡記錄一下。
由於在觸發器中不能對LONG或LONG RAW型別的欄位進行引用,所以原本最簡單的方式直接將:NEW.COL插入到新表的方法無法奏效,必須採用其他方法解決。
SQL> CREATE TABLE T (ID NUMBER PRIMARY KEY, COMMENTS LONG RAW);
表已建立。
SQL> CREATE TABLE T1 (ID NUMBER PRIMARY KEY, COMMENTS BLOB);
表已建立。
SQL> CREATE OR REPLACE TRIGGER TRI_T BEFORE INSERT ON T FOR EACH ROW
2 BEGIN
3 INSERT INTO T1 VALUES (:NEW.ID, :NEW.COMMENTS);
4 END;
5 /
CREATE OR REPLACE TRIGGER TRI_T BEFORE INSERT ON T FOR EACH ROW
*
ERROR 位於第 1 行:
ORA-04093: 不允許在觸發器中引用 LONG 型別的列
只能透過查詢原表的方式,不過查詢原表會面臨一個變異表的問題,解決這個變異表的問題一般是透過三個觸發器和一個程式包來完成。
SQL> CREATE OR REPLACE PACKAGE P_RECORD_ID AS
2 TYPE T_NUMBER IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
3 V_ID T_NUMBER;
4 END;
5 /
程式包已建立。
SQL> CREATE OR REPLACE TRIGGER TRI_B_T BEFORE INSERT ON T
2 BEGIN
3 P_RECORD_ID.V_ID.DELETE;
4 END;
5 /
觸發器已建立
SQL> CREATE OR REPLACE TRIGGER TRI_B_R_T BEFORE INSERT ON T FOR EACH ROW
2 BEGIN
3 P_RECORD_ID.V_ID(P_RECORD_ID.V_ID.COUNT + 1) := :NEW.ID;
4 END;
5 /
觸發器已建立
SQL> CREATE OR REPLACE TRIGGER TRI_A_T AFTER INSERT ON T
2 BEGIN
3 FOR I IN 1..P_RECORD_ID.V_ID.COUNT LOOP
4 INSERT INTO T1 SELECT ID, TO_LOB(COMMENTS) FROM T WHERE ID = P_RECORD_ID.V_ID(I);
5 END LOOP;
6 END;
7 /
觸發器已建立
簡單測試一下:
SQL> INSERT INTO T VALUES (1, '1234567890ABCD');
已建立 1 行。
SQL> SELECT * FROM T;
ID C
---------- -
1 1
SQL> COL COMMENTS FORMAT A50
SQL> SELECT ID, CAST(COMMENTS AS RAW(255)) COMMENTS FROM T1;
ID COMMENTS
---------- --------------------------------------------------
1 1234567890ABCD
SQL> INSERT INTO T VALUES (2, 'A');
已建立 1 行。
SQL> SELECT ID, CAST(COMMENTS AS RAW(255)) COMMENTS FROM T1;
ID COMMENTS
---------- --------------------------------------------------
1 1234567890ABCD
2 0A
SQL> INSERT INTO T SELECT ID + 2, 'ABC' FROM T;
已建立2行。
SQL> SELECT ID, CAST(COMMENTS AS RAW(255)) COMMENTS FROM T1;
ID COMMENTS
---------- --------------------------------------------------
1 1234567890ABCD
2 0A
3 0ABC
4 0ABC
對於8i版本,由於PL/SQL的編譯器還不認識TO_LOB函式,可以改用動態SQL:
SQL> CREATE OR REPLACE TRIGGER TRI_A_T AFTER INSERT ON T
2 BEGIN
3 FOR I IN 1..P_RECORD_ID.V_ID.COUNT LOOP
4 EXECUTE IMMEDIATE 'INSERT INTO T1 SELECT ID, TO_LOB(COMMENTS) FROM T WHERE ID = :ID'
5 USING P_RECORD_ID.V_ID(I);
6 END LOOP;
7 END;
8 /
觸發器已建立
對於LONG、LONG RAW型別的複製,用觸發器並不是個好的辦法,唯一的好處就是相對簡單,而且不需要修改程式,完全在資料庫級上實現,不過效率肯定不會太高
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7916042/viewspace-889348/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- LONG型別複製型別
- [20120910]建立包含long型別的表.txt型別
- Java long型別和Long型別的那些事Java型別
- 透過觸發器禁止模式物件的DDL操作觸發器模式物件
- 含LONG型別欄位的表無法MOVE型別
- 操作LONG型別型別
- 自動啟用表的FLASHBACK ARCHIVE續之觸發器型別的選擇Hive觸發器型別
- int型別和long long型別運算執行時間的差別型別
- 10g包含同名觸發器的表執行PURGE TABLE出錯觸發器
- Long raw和Long型別總結型別
- Oracle觸發器觸發級別Oracle觸發器
- long型別相關型別
- 透過API觸發airflow的DAG任務APIAI
- Day 7.5 資料型別總結 + 複製 淺複製 深複製資料型別
- LONG型別遷移到LOB型別(三)型別
- LONG型別遷移到LOB型別(二)型別
- LONG型別遷移到LOB型別(一)型別
- oracle 觸發器實現禁止在資料庫中建立dblink ---透過觸發器實現Oracle觸發器資料庫
- OGG同步複製時與相容觸發器解決方法觸發器
- 包含觸發器的LOB表執行IMP導致EMPTY_LOB變為空觸發器
- mysql一些複製表、增刪改索引、建儲存過程、建立函式、建立觸發器的一些命令MySql索引儲存過程函式觸發器
- Oracle Long型別轉換為Clob型別Oracle型別
- 關於long型別的轉換型別
- oracle裡long型別的總結Oracle型別
- long型別資料的擷取型別
- oracle 觸發器-表同步Oracle觸發器
- 觸發器支援透過DBLINK進行遠端更新, YES.觸發器
- 從值型別複製引發的Swift記憶體的思考01型別Swift記憶體
- mysql繞過行觸發器,實現語句觸發器MySql觸發器
- 透過原始碼分析RocketMQ主從複製原理原始碼MQ
- oracle裡long型別詳解Oracle型別
- 陣列(引用型別)複製問題陣列型別
- 全表複製過程建立指令碼指令碼
- 透過 Drone CLI 手動觸發 CI/CD 流程
- 測試Java中的long,int基本型別Java型別
- 禁止oracle表的觸發器triggerOracle觸發器
- PLSQL Language Reference-PL/SQL資料型別-SQL資料型別-LONG和LONG RAW變數SQL資料型別變數
- 讀取oracle long型別及判斷是否自動分割槽表Oracle型別