【问题标题】:ERROR at line 191: ORA-01489: result of string concatenation is too long [duplicate]第 191 行的错误:ORA-01489:字符串连接的结果太长 [重复]
【发布时间】:2013-10-03 00:50:36
【问题描述】:
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:字符串连接的结果太长。

请帮忙!!!

【问题讨论】:

标签: sql oracle


【解决方案1】:

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;

【讨论】:

    【解决方案2】:

    如何增加 LONG 的值?您可能必须将 long 变量增加到更高的值。详细说明请点击here

    例子:

     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 个字符的限制并且已超出。

    【讨论】:

    • SET LONG 是系统范围的参数还是仅适用于正在启动的查询?
    • @DavideInglima 来自文档:“SET 语句将值分配给影响服务器或客户端操作的不同类型的变量。”
    【解决方案3】:

    在显示 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 数据类型!

    【讨论】:

    • 您仍在连接 VARCHAR > 4000 字节。
    • @ Jean-Francois Savard,不。PL/SQL 的输出不再是 VARCHAR。因此它不会受到 4000 大小限制的限制。
    【解决方案4】:

    试试 xmlagg 函数。当我遇到类似问题时,这对我很有效。

    http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions215.htm

    【讨论】:

    • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接的答案可能会失效。
    猜你喜欢
    • 2016-05-28
    • 2017-02-06
    • 2015-06-28
    • 1970-01-01
    • 2011-08-13
    • 2013-04-04
    • 1970-01-01
    • 2021-01-18
    • 2012-05-12
    相关资源
    最近更新 更多