最近在写一个东西用到了UTL_FILE,目的在于每天取DBMS_METADATA.GET_DDL以作备份,在这里遇到了一些问题还希望有熟悉这个的高手帮帮忙。有一个存储过程长度为 用dbms_lob.GetLengt 取的长度为30564,按理说没有超过utl_file.fopen buffer的32767但是我无论如何也放不进去  一直报 ORA-06502: PL/SQL: 数字或值错误。于是我开始测试到底要多长才能放进去  最后发现当长度减少到16383的时候就可以成功放进去了。想到既然这样能成功放进去那么我就用dbms_lob.substr来截取吧所以我又试了下 dbms_lob.substr来做 但是发现这样最多只能截取3812 在长了也要报 ORA-06502 和 ORA-06512的错误。
自己想 难道会我这个procedure 里面是每个占了8个byte?如果这样截下去的话未免太麻烦了  所以我放弃了这种尝试,
还是把注意力转移到了  utl_file上面,这个buffer为什么是32767而我procedure没有达到这个长度就要报错呢?不明白还希望大家讲解下。部分代码如下:
FOR V_LOOP IN (SELECT * FROM ALL_PROCEDURES) LOOP
   IF V_LOOP.OWNER IN ('CI') AND V_LOOP.OBJECT_TYPE IN ('PROCEDURE','FUNCTION') AND V_LOOP.OBJECT_NAME='P_CI_SALES_MISSIN_EXE_2' THEN
        V_SQL := DBMS_METADATA.GET_DDL(V_LOOP.OBJECT_TYPE,V_LOOP.OBJECT_NAME,V_LOOP.OWNER); 
V_D_SQL := 'CREATE OR REPLACE DIRECTORY ' || V_LOOP.OBJECT_NAME || ' AS ''' || V_DIRECTORY || '/ci' || ''' ';
vLength := dbms_lob.GetLength(V_SQL);
DBMS_OUTPUT.PUT_LINE(vLength);
EXECUTE IMMEDIATE V_D_SQL;
V_FILE_NAME := LOWER(V_LOOP.OBJECT_NAME) || '_' || V_ACCT_DATE || '.sql';
V_UTL_FILE := UTL_FILE.FOPEN(V_LOOP.OBJECT_NAME,V_FILE_NAME,'W','32767');
        UTL_FILE.PUT_line(V_UTL_FILE,V_SQL);
UTL_FILE.FFLUSH(V_UTL_FILE);
        UTL_FILE.FCLOSE(V_UTL_FILE); 
  END IF;
END LOOP;