目前有个表  com_sql 结构如下 
Name       Type           Nullable Default Comments                 
---------- -------------- -------- ------- ------------------------ 
ID         VARCHAR2(500)                   编码                     
NAME       LONG           Y                是否可用
MEMO       VARCHAR2(2000) Y                备注                     
TYPE       VARCHAR2(20)   Y                类型                     
SPELL_CODE VARCHAR2(6)    Y                拼音吗                   
MODUAL     VARCHAR2(20)   Y                模块名称                 
INPUT      VARCHAR2(200)  Y                输入参数                 
OUTPUT     VARCHAR2(200)  Y                输出参数                 
ISVALID    VARCHAR2(1)    Y               sql                      
               
现在小弟想写个触发器 保存改动内容 触发器如下
create or replace trigger TRG_COM_SQL_LOGO
  after UPDATE  on COM_SQL 
  for each row
begin
      --SQL 信息
      INSERT INTO COM_SQL_LOGO(
       ID ,                  --ID          
       NAME ,                 --SQL       
       OPER ,            --操作员代码
       OPER_DATE              --操作时间
      )  
      VALUES(
        :OLD.ID ,
        :OLD.NAME,
       '' ,       --操作员代码
       sysdate          --操作时间
      ) ;END TRG_COM_SQL_LOGO;
提示我 long 类型的不能直接插入 高手指点一下 这个触发器该怎么写

解决方案 »

  1.   


    TThe LONG DatatypeA variable declared LONG can store variable-length strings of up to 32760 bytes梩his is actually seven fewer bytes than allowed in VARCHAR2 type variables! The LONG datatype for PL/SQL variables is quite different from the LONG datatype for columns in the Oracle Server. The LONG datatype can store character strings of up to two gigabytes or 231-1 bytes; this large size makes the LONG column a possible repository of multimedia information, such as graphics images. As a result of these maximum length differences, you can always insert a PL/SQL LONG variable value into a LONG database column, but you cannot select a LONG database value larger than 32760 bytes into a PL/SQL LONG variable.In the Oracle database, there are many restrictions on how the LONG column can be used in a SQL statement. PL/SQL LONG variables are free of these restrictions:w A table may contain more than one single LONG column.
    w You can use the LONG column in a GROUP BY, ORDER BY, WHERE, or CONNECT BY clause.
    w You can apply character functions (such as SUBSTR, INSTR, or LENGTH), to the LONG column. In your PL/SQL code you can use a variable declared LONG just as you would a variable declared VARCHAR2. You can apply character functions to the variable. You can use it in the WHERE clause of a SELECT or UPDATE statement. This all makes sense given that at least from the standpoint of the maximum size of the variables, there is really little difference between VARCHAR2 and LONG in PL/SQL. Given the fact that a VARCHAR2 variable actually has a higher maximum length than the LONG and has no restrictions attached to it, I recommend that you always use the VARCHAR2 datatype in PL/SQL programs. LONGs have a place in the RDBMS, but that role is not duplicated in PL/SQL. This makes some sense since you will very rarely want to manipulate truly enormous strings within your program using such functions as SUBSTR or LENGTH or INSTR.
      

  2.   

    通过触发器复制包含LONG类型的表
    发表人:yangtingkun | 发表时间: 2005年九月27日, 11:28前两天论坛上有人问如何才能通过触发器来实现对包含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 1SQL> COL COMMENTS FORMAT A50
    SQL> SELECT ID, CAST(COMMENTS AS RAW(255)) COMMENTS FROM T1;ID COMMENTS
    ---------- --------------------------------------------------
    1 1234567890ABCDSQL> INSERT INTO T VALUES (2, 'A');已创建 1 行。SQL> SELECT ID, CAST(COMMENTS AS RAW(255)) COMMENTS FROM T1;ID COMMENTS
    ---------- --------------------------------------------------
    1 1234567890ABCD
    2 0ASQL> 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类型的复制,用触发器并不是个好的办法,唯一的好处就是相对简单,而且不需要修改程序,完全在数据库级上实现,不过效率肯定不会太高。
      

  3.   

    在触发器中不能对LONG或LONG RAW类型的字段进行引用,所以原本最简单的方式直接将:NEW.COL插入到新表的方法无法奏效,必须采用其他方法解决。不管怎么触发,不能对LONG或LONG RAW类型的字段进行引用
    也就是不能用:new or :old访问。访问其他表的long字段应该是可以的