2016-09-05 316 views
0

(使用Oracle 11.2)获取ORA-22922(不存在LOB值)或者没有结果与wm_concat在所有的()

我有类似

wm_concat(distinct abc) 

一个相当复杂的SQL,预计到返回一些varchar2(4000)兼容结果

它导致ORA-00932: inconsistent datatypes在我选择的某些coalesce(some_varchar_col, wm_concat(...))中使用。


所以我试图通过两种不同的方法铸造它:

dbms_lob.substr(..., 4000) -- L) tried even with 3000 in case of "unicode byte blow-up" 
cast(... as varchar2(4000)) -- C) tried even with 3000 in case of "unicode byte blow-up" 

(将在视图中使用,但玩弄它表明,它是不相关的意见)

取决于柱等运营商我要么得到N)无结果或O)ORA-22922

select * from view_with_above_included where rownum <= 100 
  • N)我的Eclipse数据浏览器JDBC连接返回没有任何结果(无结果没有列,没有(0 rows effected),只有查询时间统计)。 (?它可以是一个内部异常不作这样的处理)

  • O)

    ORA-22922: nonexistent LOB value 
    ORA-06512: in "SYS.DBMS_LOB", line 1092 
    ORA-06512: in line 1 
    

奇怪以下测试查询工作:

-- rownum <= 100 would already cause the above problems 
select * from view_with_above_included where rownum <= 10 

select * from view_with_above_included 

但是查看实际的聚合数据不会显示聚合的数据,其长度将超过1000个字符。

+0

这可能与:http://stackoverflow.com/questions/12969274,https://community.oracle.com/thread/2383469 –

回答

1

幸运的是,它的工作原理与自11.2(我们正在运行)提供的listagg(...)功能,所以我们没有进一步调查:

listagg(abc, ',') within group (order by abc) 

(其中wm_concat(...)是,作为一个人应该知道,一些内部和官方不支持的功能。)


一个rather nice solution(因为它不是那么臃肿)实施distinct功能是通过自引用的正则表达式的功能应该在很多情况下工作:

regexp_replace( 
    listagg(abc, ',') within group (order by abc) 
, '(^|,)(.+)(,\2)+', '\1\2') 

(也许/希望未来我们会看到一些可以工作的功能listagg(distinct abc),这个功能将会非常简洁并且很酷,就像wm_concat的语法一样。例如,这对Postgres'很长时间来说并不是问题)

-- 1: postgres sql example: 
select string_agg(distinct x, ',') from unnest('{a,b,a}'::text[]) as x` 

如果列表超过4000个字符,一个不能使用listaggORA-22922再次)。 但幸运的是我们可以在这里使用xmlagg函数(如提到的here)。 如果你想实现distinct在4000字符截断的结果在这里,你可以注释(1) - 标记行

-- in smallercase everything that could/should be special for your query 
-- comment in (1) to realize a distinct on a 4000 chars truncated result 
WITH cfg AS ( 
    SELECT 
    ','     AS list_delim, 
    '([^,]+)(,\1)*(,|$)' AS list_dist_match, -- regexp match for distinct functionality 
    '\1\3'    AS LIST_DIST_REPL -- regexp replace for distinct functionality 
    FROM DUAL 
) 
SELECT 
    --REGEXP_REPLACE(DBMS_LOB.SUBSTR(   -- (1) 
    RTRIM(XMLAGG(XMLELEMENT(E, mycol, listdelim).EXTRACT('//text()') 
    ORDER BY mycol).GetClobVal(), LIST_DELIM) 
    --, 4000), LIST_DIST_MATCH, LIST_DIST_REPL) -- (1) 
    AS mylist 
FROM mytab, CFG 
+0

的**'distinct'但必须处理不同* *,例如:http://stackoverflow.com/a/11511203/1915920 –

+0

wm_concat反正在Oracle11g中不受支持。它直到Oracle 10g才可用。 – XING

+0

@Raj_Te:错误...在Oracle 12c中被移除(在11.2中工作),可用,但在不存在的情况下不受支持。 –