觸發器中操作LOB
在觸發器中可以像其他資料型別一樣處理LOB欄位,但是僅侷限於SQL語句對LOB的修改。
如果看不懂上面的含義,沒有關係,下面透過一個例子來說明:
SQL> CREATE TABLE T
2 (ID NUMBER,
3 TEXT CLOB);
Table created.
下面在T表上新增一個觸發器,檢查插入的LOB列的長度,並在LOB列後加入一個字元傳“ END”:
SQL> CREATE OR REPLACE TRIGGER T
2 BEFORE INSERT ON T
3 FOR EACH ROW
4 BEGIN
5 DBMS_OUTPUT.PUT_LINE(DBMS_LOB.GETLENGTH(:NEW.TEXT));
6 :NEW.TEXT := :NEW.TEXT || ' END';
7 END;
8 /
Trigger created.
SQL> SET SERVEROUT ON
SQL> SET LONG 10000000
首先嚐試直接插入記錄:
SQL> INSERT INTO T
2 VALUES (1, 'ABCDEFG');
7
1 row created.
SQL> SELECT * FROM T;
ID TEXT
---------- --------------------------------------------------------------------------------
1 ABCDEFG END
下面透過PL/SQL中巢狀SQL的方式插入,繫結字串的長度是32767:
SQL> DECLARE
2 V_STR VARCHAR2(32767) := RPAD('A', 32767, 'A');
3 BEGIN
4 INSERT INTO T VALUES (2, V_STR);
5 COMMIT;
6 END;
7 /
32767
PL/SQL procedure successfully completed.
SQL> SELECT * FROM T WHERE ID = 2;
ID TEXT
---------- --------------------------------------------------------------------------------
2 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
.
.
.
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA END
下面測試一下透過PL/SQL,利用臨時LOB,直接插入LOB物件的方式:
SQL> DECLARE
2 V_LOB CLOB;
3 V_STR VARCHAR2(32767) := RPAD('A', 32767, 'A');
4 BEGIN
5 DBMS_LOB.CREATETEMPORARY(V_LOB, TRUE);
6 FOR I IN 1..5 LOOP
7 DBMS_LOB.WRITEAPPEND(V_LOB, 32767, V_STR);
8 END LOOP;
9 INSERT INTO T VALUES (3, V_LOB);
10 COMMIT;
11 END;
12 /
163835
PL/SQL procedure successfully completed.
SQL> SELECT * FROM T WHERE ID = 3;
ID TEXT
---------- --------------------------------------------------------------------------------
3 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
.
.
.
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA END
下面看一下透過SQL語句INSERT AS SELECT的方式插入LOB型別:
SQL> INSERT INTO T
2 SELECT ID + 3, TEXT
3 FROM T;
11
32771
163839
3 rows created.
SQL> SELECT ID,
2 DBMS_LOB.SUBSTR(TEXT, 10, DBMS_LOB.GETLENGTH(TEXT) - 9) TEXT,
3 DBMS_LOB.GETLENGTH(TEXT) LENGTH
4 FROM T;
ID TEXT LENGTH
---------- ------------------------------------------------------------ ----------
1 BCDEFG END 11
2 AAAAAA END 32771
3 AAAAAA END 163839
4 FG END END 15
5 AA END END 32775
6 AA END END 163843
6 rows selected.
可以看到,無論上面哪種方式,觸發器都可以正常的處理LOB,而且處理方式和其他資料型別並沒有什麼不同。不過下面這種透過PL/SQL直接處理LOB的方式,觸發器就無能為力了:
SQL> DECLARE
2 V_LOB CLOB;
3 V_STR VARCHAR2(32767) := ' PL/SQL DIRECT WRITE LOB';
4 BEGIN
5 INSERT INTO T VALUES (7, EMPTY_CLOB) RETURN TEXT INTO V_LOB;
6 DBMS_LOB.WRITEAPPEND(V_LOB, LENGTH(V_STR), V_STR);
7 COMMIT;
8 END;
9 /
0
PL/SQL procedure successfully completed.
SQL> SELECT * FROM T WHERE ID = 7;
ID TEXT
---------- ------------------------------------------------------------
7 END PL/SQL DIRECT WRITE LOB
觸發器也工作了,但是獲取到的LOB長度是0,而且追加的內容也寫到了LOB開頭的部分。
其實這並非是觸發器的問題,因為對於觸發器而言,觸發的SQL語句實際上確實只是寫入了一個空的LOB,而LOB隨後的內容是透過PL/SQL程式碼透過LOB的定位符直接寫入的,這個操作就不是觸發器能捕獲的了。
舉個不太恰當的例子,比如透過直接路徑方式裝載記錄,或者利用EXCHANGE PARTITION方式是的資料進入到表中,都是不會導致觸發器觸發的,而這種PL/SQL方式寫入LOB也是一樣的。利用觸發器沒有辦法獲取到這部分資訊,而只能透過類似LOGMINER之類的工具才能獲取到。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4227/viewspace-619364/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- postgresql 觸發器操作SQL觸發器
- PLSQL方式更新LOB不會被觸發器捕獲SQL觸發器
- DML操作 DDL觸發器觸發器
- 包含觸發器的LOB表執行IMP導致EMPTY_LOB變為空觸發器
- Oracle 觸發器 限制DDL操作Oracle觸發器
- Oracle中的LOB操作(轉)Oracle
- Oracle中審計刪除(DELETE)操作的觸發器Oracledelete觸發器
- 資料庫觸發器,禁止DDL操作資料庫觸發器
- (15)mysql 中的觸發器MySql觸發器
- 觸發器中不能commit觸發器MIT
- 瞭解SQL Server觸發器及觸發器中的事務AWSQLServer觸發器
- SQL Sever 2000中的前觸發器和後觸發器SQL觸發器
- 透過觸發器禁止模式物件的DDL操作觸發器模式物件
- Oracle觸發器觸發級別Oracle觸發器
- 操作lob,居然成功了!
- Oracle中觸發器的應用 (zt)Oracle觸發器
- 觸發器中獲取SQL語句觸發器SQL
- Oracle觸發器6(建立系統事件觸發器)Oracle觸發器事件
- 根據業務寫觸發器(oracle觸發器片)觸發器Oracle
- mysql——觸發器MySql觸發器
- mysql 觸發器MySql觸發器
- SQL觸發器SQL觸發器
- Mysql觸發器:MySql觸發器
- Oracle觸發器Oracle觸發器
- mysql觸發器MySql觸發器
- SQL Server中類似Oracle中before觸發器SQLServerOracle觸發器
- 【SQL Server】-- 一觸即發之觸發器SQLServer觸發器
- mysql 觸發器/過程中的變數!!MySql觸發器變數
- mysql繞過行觸發器,實現語句觸發器MySql觸發器
- oracle 觸發器實現禁止在資料庫中建立dblink ---透過觸發器實現Oracle觸發器資料庫
- sqlserver 列觸發器SQLServer觸發器
- 除錯觸發器除錯觸發器
- 建立MySQL觸發器MySql觸發器
- SqlServer-觸發器SQLServer觸發器
- MySQL使用觸發器MySql觸發器
- MySql-觸發器MySql觸發器
- MySQL 建立觸發器MySql觸發器
- mysql建立觸發器MySql觸發器