ITPub博客

首页 > 数据库 > 数据库开发技术 > 通过触发器复制包含LONG类型的表

通过触发器复制包含LONG类型的表

原创 数据库开发技术 作者:rainbowbridg 时间:2007-01-10 15:00:17 0 删除 编辑
上个月有人问我这个long的表是建立触发器的问题,结果在这里找到了:

前两天论坛上有人问如何才能通过触发器来实现对包含LONGLONG RAW类型字段的表的复制。给他做了个最简单的例子,在这里记录一下。

由于在触发器中不能对LONGLONG 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 /

触发器已创建

对于LONGLONG RAW类型的复制,用触发器并不是个好的办法,唯一的好处就是相对简单,而且不需要修改程序,完全在数据库级上实现,不过效率肯定不会太高

ref: http://yangtingkun.itpub.net/post/468/41936

[@more@]

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/7916042/viewspace-889348/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
  • 博文量
    237
  • 访问量
    1587632