为什么wm_concat不在这里工作?为什么wm_concat不在这里工作?(Why does th

2019-05-12 09:49发布

我有这个疑问:

(SELECT OBJECT_ID from cr_object_group_entries_vw where object_group_id IN
    (SELECT ITEM FROM TABLE(CR_FN_SPLIT_STRING('28,56',','))))

该回报:

但是,当我这样做:

SELECT wm_concat(object_id) FROM
    (SELECT OBJECT_ID from cr_object_group_entries_vw where object_group_id IN
        (SELECT ITEM FROM TABLE(CR_FN_SPLIT_STRING('28,56',','))))

我得到了一个空白的结果......我究竟做错了什么?

Answer 1:

你必须避免wm_concat功能,因为它是未记录发现的甲骨文8i的时间解决方法。

由于与由汤姆凯特发现自定义聚合函数旧方法的时候这里有一些新的解决方法,显示在下面的例子。

他们都在转载这个SQL小提琴 。

解决方法1 - LISTAGG功能,工作在11g中:

select listagg(object_id,',') within group (order by rownum) id_string
from cr_object_group_entries_vw

解决方法2 - 因为10克SYS_CONNECT_BY_PATH,工作原理:

select id_string from (
  select rn, substr(sys_connect_by_path(object_id, ','),2) id_string
  from (select object_id, rownum rn from cr_object_group_entries_vw)
  start with rn = 1
  connect by prior rn + 1 = rn
  order by rn desc
)
where rownum = 1

解决方法3 - 由于10克XMLAGG,工作原理:

select replace(
         replace(
           replace(
             xmlagg(xmlelement("x",object_id)).getStringVal(),
             '</x><x>',
             ','
           ),
           '<x>',
           ''
         ),
         '</x>',
         ''
       ) id_string
from cr_object_group_entries_vw

PS我并没有完全在Oracle版本知道sys_connect_by_pathxmlagg介绍,但都效果很好的10.2.0.4.0



Answer 2:

如果你是11g上试LISTAGG而不是wm_concat对于初学者。



Answer 3:

我刚刚看到有关这个帖子wm_concat和思想分享一些信息。

任何已被依靠应用wm_concat功能将无法正常工作,一旦升级到12c 。 因为,它已经从最新12C版本中删除。 请参阅为什么在Oracle中不使用WM_CONCAT功能?

SQL> select banner from v$version where rownum = 1;

BANNER
----------------------------------------------------------------------------
Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production

SQL> SELECT object_name
  2  FROM dba_objects
  3  WHERE owner='WMSYS'
  4  AND object_name LIKE 'WM\_%' ESCAPE '\';

OBJECT_NAME
----------------------------------------------------------------------------
WM_REPLICATION_INFO
WM_RDIFF
WM_PERIOD
WM_PERIOD
WM_OVERLAPS
WM_MEETS
WM_LESSTHAN
WM_LDIFF
WM_INTERSECTION
WM_INSTALLATION
WM_GREATERTHAN
WM_EVENTS_INFO
WM_ERROR
WM_ERROR
WM_EQUALS
WM_DDL_UTIL
WM_DDL_UTIL
WM_CONTAINS
WM_COMPRESS_BATCH_SIZES
WM_COMPRESSIBLE_TABLES

20 rows selected.

您会收到“ 无效的标识符 ”错误:

SQL> SELECT banner FROM v$version;

BANNER
----------------------------------------------------------------------------
Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production
PL/SQL Release 12.1.0.1.0 - Production
CORE    12.1.0.1.0      Production
TNS for 64-bit Windows: Version 12.1.0.1.0 - Production
NLSRTL Version 12.1.0.1.0 - Production

SQL> SELECT deptno, wm_concat(ename) FROM emp;
SELECT deptno, wm_concat(ename) FROM emp
               *
ERROR at line 1:
ORA-00904: "WM_CONCAT": invalid identifier

因此,没有一点依靠它没有更多的最新版本提供无证功能

对于替代解决方案,请访问甲骨文字符串聚合技术



Answer 4:

你似乎并没有做任何事。 随着虚拟表函数返回你显示数据, wm_concat为我工作:

select wm_concat(object_id) from
    (select object_id from cr_object_group_entries_vw where object_group_id in
        (select item from table(cr_fn_split_string('28,56',','))))
/

WM_CONCAT(OBJECT_ID)                                                           
--------------------------------------------------------------------------------
36,1,11,121,13,14,17,18,2,24,3,32,33,34,35,36,37,38,39,40,42,43,44,6,7,8,81      

您已经标记了一个问题,[11克] 作为@beherenow说,如果你能,你应该使用支持lisgagg在不支持的wm_concat ,尽管它只能从11gR2的,我认为:

select listagg(object_id, ',') within group (order by object_id)
from cr_object_group_entries_vw
where object_group_id in
    (select item from table(cr_fn_split_string('28,56',',')))
/

LISTAGG(OBJECT_ID,',')WITHINGROUP(ORDERBYOBJECT_ID)
---------------------------------------------------------------------------
1,11,121,13,14,17,18,2,24,3,32,33,34,35,36,36,37,38,39,40,42,43,44,6,7,8,81

SQL小提琴 (为listagg而已,因为它不支持wm_concat -也许你的实例不下去,但那么它应该报错?)



文章来源: Why does the wm_concat not work here?