【问题标题】:SYS_CONNECT_BY_PATH leads to "ORA-01489: result of string concatenation is too long"SYS_CONNECT_BY_PATH 导致“ORA-01489:字符串连接的结果太长”
【发布时间】:2012-05-12 02:48:19
【问题描述】:

我正在使用 SYS_CONNECT_BY_PATH 进行字符串聚合。查询的一般形式是这样的:

select /*a bunch of fields unrelated to the problem*/,
--Use SYS_CONNECT_BY_PATH to glue together all the chunks of XML. 
--The XSL header and footer are prepended and appended here.
 , XMLType(to_clob('<?xml version="1.0"?><!-- begining of XSL file -->,'<!-- Next Section -->'))||'</xsl:stylesheet>')) AS XSL
from (
  select /*a bunch of fields unrelated to the problem*/
    case when x = 1 then to_clob('
    /*a bunch of XSL*/
     <xsl:text>'||subq.new_c_value||'</xsl:text>
    /*a whole bunch more xsl*/')
    else
     to_clob('/*a bunch of different XSL*/             
     <xsl:text>'||subq.new_f_value||'</xsl:text>
    /*a whole bunch more xsl*/')
    end as xsl,
  --curr and prev are to help with using sys_connect_by_path do string aggregation.
    rownum AS curr,
    rownum -1 AS prev
  from (Select /* details of subq not relevant */ ) as subq
)
CONNECT BY prev = PRIOR curr 
START WITH curr = 1;

基本上,我正在运行一个查询来生成用于更正 XML 文件的 XSL。我正在使用 sys_connect_by_path 将字符串组合成一个块,这比从多行复制和粘贴许多值更容易。我不能使用任何自定义字符串聚合函数,因为此查询在生产数据库上运行,我不能随心所欲地创建函数。

问题是运行我的查询会返回:

ORA-01489: 字符串连接的结果太长 01489. 00000 - “字符串连接的结果太长” *原因:字符串连接结果大于最大大小。 *行动:确保结果小于最大大小。

...在数据过多的情况下。如您所见,我一直在将to_clob() 函数应用于我认为可能有帮助的任何地方,但似乎并没有太大的不同。除了使用 PL/SQL 之外,还有其他方法可以处理这个问题吗?我更愿意将其保留为查询,因为此查询的结果被导出到报告模板中,该模板与 XSL 并排显示了许多有用的信息。能够在一个步骤而不是几个步骤中完成所有这些会很好。

(Oracle 10g)


最终,我找到了这个页面:

http://www.sqlsnippets.com/en/topic-11787.html

关于 Oracle 中的字符串聚合技术。我怀疑在我的情况下唯一可以使用的是 XML 方法和 Model 方法。我无法让模型方法正常工作,所以我只使用 XML 方法。

【问题讨论】:

  • 这将是艰难的。 Here's an interesting forum post on the topic。引用一个答案:“您可以使用 SYS_CONNECT_BY_PATH 在子查询中形成部分字符串,然后将这些部分连接到主查询中的 CLOB 中。”。祝你好运!

标签: sql oracle


【解决方案1】:
select
    xmlroot
    (
        xmlelement
        (
            "xsl:stylesheet"
            ,XMLAttributes
            (
                '1.0' as version
                ,'http://www.w3.org/1999/XSL/Transform' as "xmlns:xsl"
                ,'http://test' as "xmlns:ns0"
            )
            ,(
                xmlagg(xmlelement("xsl:text", val))
            )
        )
        ,version '1.0'
    )
from
(
    --Test >4000 characters
    select 1 id, cast(rpad('a',4000,'a') as varchar2(4000)) val from dual union all
    select 1 id, cast(rpad('b',4000,'b') as varchar2(4000)) val from dual union all
    select 1 id, cast(rpad('c',4000,'c') as varchar2(4000)) val from dual union all
    select 1 id, cast(rpad('d',4000,'d') as varchar2(4000)) val from dual
);

【讨论】:

  • 这似乎有效,但我现在有两个查询:一个用于报告数据,一个用于 xmlagg 的结果。可能没有别的办法了……
【解决方案2】:

对不起,我的回答依赖于创建字符串聚合包,但从长远来看可能会有用 您可以使用 Stragg 包而不是 sys_connect_by_path AskTom 在下面的链接中提到了

http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:2196162600402

在该包中有一个声明和一些处理 long 的逻辑,您可以根据需要更改以处理 CLOB

【讨论】:

  • 这可能会起作用,尽管我正在对生产服务器运行此查询以报告生产数据。因为它是生产服务器,所以我不能仅仅为了报告方便而编译新包。
猜你喜欢
  • 2017-02-06
  • 2011-08-13
  • 2016-05-28
  • 2013-04-04
  • 1970-01-01
  • 2015-06-28
  • 1970-01-01
  • 2013-01-29
  • 1970-01-01
相关资源
最近更新 更多