2015-09-10 171 views
0

我下面的查询工作:SQL错误:ORA-01489:字符串连接的结果是太长

select ip.intake_id, 
     ip.estimated_years, 
     ip.gender_code, 
     LISTAGG(ip.race_code, ',') WITHIN GROUP (ORDER BY ip.race_code) as race_code, 
     eth.ethnicity_code, 
     i.living_arrangements, 
     p.dep_actv_military_flag, 
     LISTAGG(ale.allegation_super_type_code) WITHIN GROUP (ORDER BY ale.allegation_super_type_code) as maltreatment_type_code, 
     LISTAGG(ale.initial_report_disp_code) WITHIN GROUP (ORDER BY ale.initial_report_disp_code) as maltreatment_dispo_lvl, 
     ip.deceased_flag, 
     LISTAGG(ch.characteristic_code, ',') WITHIN GROUP (ORDER BY ch.characteristic_code) as chara_codes, 
     LISTAGG(ich.intake_characteristic_code, ',') WITHIN GROUP (ORDER BY ich.intake_characteristic_code) as intake_chara_codes, 
     pe.removed_date,cm.petition_submitted_flag,cm.created_date,atr.person_id 
from intake i inner join intake_participant ip on i.intake_id = ip.intake_id 
     left outer join reporter r ON i.intake_id=r.intake_id 
     left outer join ethnicity eth on eth.person_id = ip.person_id 
     left outer join person p on p.person_id = ip.person_id 
     left outer join allegation ale on ale.intake_id = i.intake_id 
     left outer join characteristic ch on ch.person_id = ip.person_id 
     left outer join intake_characteristic ich on ich.intake_id = i.intake_id 
     left outer join placement_episode pe on pe.child_id = ip.person_id 
     left outer join complaint cm on cm.petitioner_id = ip.person_id 
     left outer join attorney atr on atr.person_id = ip.person_id 
     left outer join intake_participant_role apr on apr.intake_participant_id = ip.intake_participant_id 
group by ip.intake_id,ip.estimated_years,ip.gender_code,eth.ethnicity_code,i.living_arrangements,p.dep_actv_military_flag, 
    ip.deceased_flag,pe.removed_date,cm.petition_submitted_flag,cm.created_date,atr.person_id 

当我运行此查询我收到以下错误信息:

Error report: 
SQL Error: ORA-01489: result of string concatenation is too long 
01489. 00000 - "result of string concatenation is too long" 
*Cause: String concatenation result is more than the maximum size. 
*Action: Make sure that the result is less than the maximum size. 

但是当我删除行:从我的查询

left outer join reporter r ON i.intake_id=r.intake_id 

则执行没有任何错误信息。工作查询如下:

select ip.intake_id, 
     ip.estimated_years, 
     ip.gender_code, 
     LISTAGG(ip.race_code, ',') WITHIN GROUP (ORDER BY ip.race_code) as race_code, 
     eth.ethnicity_code, 
     i.living_arrangements, 
     p.dep_actv_military_flag, 
     LISTAGG(ale.allegation_super_type_code) WITHIN GROUP (ORDER BY ale.allegation_super_type_code) as maltreatment_type_code, 
     LISTAGG(ale.initial_report_disp_code) WITHIN GROUP (ORDER BY ale.initial_report_disp_code) as maltreatment_dispo_lvl, 
     ip.deceased_flag, 
     LISTAGG(ch.characteristic_code, ',') WITHIN GROUP (ORDER BY ch.characteristic_code) as chara_codes, 
     LISTAGG(ich.intake_characteristic_code, ',') WITHIN GROUP (ORDER BY ich.intake_characteristic_code) as intake_chara_codes, 
     pe.removed_date,cm.petition_submitted_flag,cm.created_date,atr.person_id 
from intake i inner join intake_participant ip on i.intake_id = ip.intake_id 
     left outer join ethnicity eth on eth.person_id = ip.person_id 
     left outer join person p on p.person_id = ip.person_id 
     left outer join allegation ale on ale.intake_id = i.intake_id 
     left outer join characteristic ch on ch.person_id = ip.person_id 
     left outer join intake_characteristic ich on ich.intake_id = i.intake_id 
     left outer join placement_episode pe on pe.child_id = ip.person_id 
     left outer join complaint cm on cm.petitioner_id = ip.person_id 
     left outer join attorney atr on atr.person_id = ip.person_id 
     left outer join intake_participant_role apr on ipr.intake_participant_id = ip.intake_participant_id 
group by ip.intake_id,ip.estimated_years,ip.gender_code,eth.ethnicity_code,i.living_arrangements,p.dep_actv_military_flag, 
    ip.deceased_flag,pe.removed_date,cm.petition_submitted_flag,cm.created_date,atr.person_id 

我不确定为什么会出现此错误。有人能帮我弄清楚这个问题吗?我从这些链接link1link2得到了相同的问题,但我没有从这些链接得到解决我的问题。

+1

没有数据,这纯粹是一种猜测 - 但我怀疑LISTAGG函数中发生的错误是聚合一组数据的LISTAGG函数。如果查询返回大量数据,LISTAGG可能会构造一个非常大的列表 - 并且删除一个连接条件可能会减少返回的数据量,从而使LISTAGG不再失败。 –

+1

我在您的查询中没有看到任何其他地方的记者。 –

+1

当您添加额外的左连接 - 从一对多关系时,您是否获得了要汇总的值的重复值?您可以暂时取出listagg调用,并对两个查询进行计数,并查看其差异。你可能已经找回了比你想要的更多的行/值。 –

回答

4

表格“记者”的加入可能会增加记录数(只有在列“intake_id”不是“记者”的唯一键时才会出现这种情况)。通过增加记录数量,可以生成更多的字符串,LISTAGG必须在每个组内连接在一起。如果连接字符串的总长度超过4000字节,则LISTAGG将失败并显示错误。

+0

这是一个众所周知的限制,Oracle 12有一个解决方法。 https://blogs.oracle.com/datawarehousing/entry/managing_overflows_in_listagg – kevinsky

+0

回到LISTAGG之前,我实现了一个非常类似于Tom Kyte的“STRAGG”函数的函数(使用ODCI函数 - Google“STRAGG”和“ODCI”许多实现)。我几乎立即遇到了4K限制,但能够使用STRAGG:STRAGG_CLOB的简单变体进行解析。它的工作原理与STRAGG(和LISTAGG)完全相同,但返回CLOB时没有令人讨厌的4K限制。我很震惊Oracle没有(也没有)提供LISTAGG_CLOB版本的LISTAGG。国际海事组织将是一个“修复”而非解决方法。 – KevinKirkpatrick

0

让我们采取一种不同的方法:就像当您汇总汇总并加入其他表格时一样,有时您必须在实现额外的一对多连接之前实现结果,以避免因汇总而人为膨胀连接表中的多条记录。这种方法假设您不需要因附加表连接而发生的重复。

我认为通过创建内联视图,race_Code的结果将符合大小限制。这也可以使用CTE完成。简而言之,如果您不需要记录重复,则可能需要先单独实现listAgg结果,然后再将它们重新加入。如果其他listAggs存在其他问题,则可能需要创建多个CTE,然后加入它们所有这些都结束了。这种方法只是使用内联视图。

select B.intake_id, 
     B.estimated_years, 
     B.gender_code, 
     B.race_code, 
     eth.ethnicity_code, 
     B.living_arrangements, 
     p.dep_actv_military_flag, 
     LISTAGG(ale.allegation_super_type_code) WITHIN GROUP (ORDER BY ale.allegation_super_type_code) as maltreatment_type_code, 
     LISTAGG(ale.initial_report_disp_code) WITHIN GROUP (ORDER BY ale.initial_report_disp_code) as maltreatment_dispo_lvl, 
     B.deceased_flag, 
     LISTAGG(ch.characteristic_code, ',') WITHIN GROUP (ORDER BY ch.characteristic_code) as chara_codes, 
     LISTAGG(ich.intake_characteristic_code, ',') WITHIN GROUP (ORDER BY ich.intake_characteristic_code) as intake_chara_codes, 
     pe.removed_date,cm.petition_submitted_flag,cm.created_date,atr.person_id 
from (SELECT ip.intake_id, 
     ip.estimated_years, 
     ip.gender_code, 
     ip.deceased_flag, 
     ip.person_id, 
     ip.intake_participant_id, 
     LISTAGG(ip.race_code, ',') WITHIN GROUP (ORDER BY ip.race_code) as race_code, i.living_arrangements 
     FROM intake i 
     INNER JOIN intake_participant ip on i.intake_id = ip.intake_id 
     GROUP BY ip.intake_id, ip.estimated_years, ip.gender_code, 
       i.living_arrangements, ip.deceased_flag, ip.person_id,     
       ip.intake_participant_id) B 
left outer join ethnicity eth on eth.person_id = B.person_id 
left outer join person p on p.person_id = B.person_id 
left outer join allegation ale on ale.intake_id = B.intake_id 
left outer join characteristic ch on ch.person_id = B.person_id 
left outer join intake_characteristic ich on ich.intake_id = i.intake_id 
left outer join placement_episode pe on pe.child_id = B.person_id 
left outer join complaint cm on cm.petitioner_id = B.person_id 
left outer join attorney atr on atr.person_id = B.person_id 
left outer join intake_participant_role apr on ipr.intake_participant_id = B.intake_participant_id 
GROUP BY ip.intake_id,ip.estimated_years,ip.gender_code, eth.ethnicity_code,i.living_arrangements,p.dep_actv_military_flag, ip.deceased_flag,pe.removed_date,cm.petition_submitted_flag, cm.created_date,atr.person_id