我有这个问题:
(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',','))))
我得到一个空白的结果......我做错了什么?
答案 0 :(得分:6)
您必须避免wm_concat
功能,因为它没有记录,并在Oracle 8i时被发现为变通方法。
自从Tom Kyte here发现自定义聚合函数的旧方法时,有一些新的解决方法,如下面的示例所示。
所有这些都转载于this SQL Fiddle。
解决方法1 - LISTAGG功能,适用于11g:
select listagg(object_id,',') within group (order by rownum) id_string
from cr_object_group_entries_vw
解决方法2 - SYS_CONNECT_BY_PATH,自10g起作用:
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 - XMLAGG,自10g起作用:
select replace(
replace(
replace(
xmlagg(xmlelement("x",object_id)).getStringVal(),
'</x><x>',
','
),
'<x>',
''
),
'</x>',
''
) id_string
from cr_object_group_entries_vw
P.S。我不确切地知道引入了哪个Oracle版本sys_connect_by_path
和xmlagg
,但两者在10.2.0.4.0上运行良好
答案 1 :(得分:4)
如果您使用11g,请尝试LISTAGG
而不是wm_concat
作为初学者。
答案 2 :(得分:3)
我刚看到有关wm_concat
的帖子,并想过分享一些信息。
任何一直依赖wm_concat
功能的应用程序在升级到12c
后将无效。因为,它已从最新的12c版本中删除。见Why not use WM_CONCAT function in Oracle?
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
因此,没有必要依赖未记录的功能,这在最新版本中不再可用。
有关其他解决方案,请参阅 Oracle String Aggregation Techniques
答案 3 :(得分:2)
你似乎没有做错任何事。使用虚拟表函数返回您显示的数据,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
您已将问题标记为[11g];正如@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 Fiddle(仅适用于listagg
,因为它不支持wm_concat
- 也许您的实例也不支持,但它应该出错?)