Select TO_CLOB(a)|| TO_CLOB(b)|| TO_CLOB(c) || TO_CLOB(d)
from table1
上面的查询没有正确地将数据假脱机到文本文件中。
然而,
Select a||b||c||d
from table1.
结束于
第 191 行的错误:ORA-01489:字符串连接的结果太长。
请帮忙 !!!
VARCHAR2 限制为 4000 字节。如果您收到此错误
第 191 行的错误:ORA-01489:字符串连接的结果太长。
那么很明显,串联超过了 4000 个字节。
现在该怎么办?
您使用 CLOB 的第一个解决方案是正确的。
select TO_CLOB(a)|| TO_CLOB(b)|| TO_CLOB(c) || TO_CLOB(d)
看起来你真正的问题是保存到文件
上面的查询没有正确地将数据假脱机到文本文件中。
虽然您没有发布如何将生成的 clob 保存到文件中,但我相信您没有正确执行此操作。如果您尝试以与使用 VARCHAR2 相同的方式保存到文件,那么您做错了。
您需要先使用dbms_lob.read
从数据库中读取 clob,然后使用utl_file.put_raw
写入文件。
DECLARE
position NUMBER := 1;
byte_length NUMBER := 32760;
length NUMBER;
vblob BLOB;
rawlob RAW(32760);
temp NUMBER;
output utl_file.file_type;
BEGIN
-- Last parameter is maximum number of bytes returned.
-- wb stands for write byte mode
output := utl_file.fopen('DIR', 'filename', 'wb', 32760);
position := 1;
select dbms_lob.getlength(yourLob)
into len
from somewhere
where something;
temp := length;
select yourLob
into vlob
from somewhere
where something;
IF len < 32760 THEN
utl_file.put_raw(output, vblob);
-- Don't forget to flush
utl_file.fflush(output);
ELSE -- write part by part
WHILE position < len AND byte_length > 0
LOOP
dbms_lob.read(vblob, byte_length, position, rawlob);
utl_file.put_raw(output,rawlob);
-- You must admit, you would have forgot to flush.
utl_file.fflush(output);
position := position + byte_length;
-- set the end position if less than 32000 bytes
temp := temp - bytelen;
IF temp < 32760 THEN
byte_length := temp;
END IF;
END IF;
END;
如何增加 LONG 的值?您可能必须将 long 变量增加到更高的值。点击此处查看详细说明。
例子:
SET LONG 100000;
SPOOL test_clob.txt
SELECT to_clob(lpad('A',4000,'A'))
||'B'
||to_clob(lpad('C',4000,'C'))
||'D'
||to_clob(lpad('E',4000,'E'))
||'F'
FROM dual;
SPOOL OFF;
您的第二个查询返回错误,因为查询中的 concat(||) 运算符试图返回 varchar2,它有 4000 个字符的限制并且被超出。
显示 CLOB 时 SQL*Plus 硬编码行大小为 81,似乎没有办法绕过它。因此,如果您想生成一个 csv 文件以加载到其他数据库,您将遇到解析这些额外换行符的问题。
最终的解决方案是使用 PL/SQL。例如,要从表“xyz”生成逗号分隔的 csv 文件,请使用以下代码:
set lin 32766
set serveroutput on size unlimited
DECLARE
TYPE arraytable IS TABLE OF xyz%ROWTYPE;
myarray arraytable;
CURSOR c IS
select * from xyz ;
BEGIN
OPEN c;
LOOP
FETCH c BULK COLLECT INTO myarray LIMIT 10000;
FOR i IN 1 .. myarray.COUNT
LOOP
DBMS_OUTPUT.PUT_LINE(
myarray(i).col1||','||
myarray(i).col2||','||
myarray(i).col3||','||
myarray(i).col4;
END LOOP;
EXIT WHEN c%NOTFOUND;
END LOOP;
END;
/
这种方法的一个好处是它甚至适用于 LONG 数据类型!
试试 xmlagg 函数。当我遇到类似的问题时,这对我很有效。
http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions215.htm