来自collect调用的ORA-00932数据类型不一致

时间:2016-04-29 14:50:26

标签: sql oracle ora-00932

当我能够使用cast(collect(value) as DBMSOUTPUT_LINESARRAY)在一行中聚合结果时,我感到非常高兴,如下例所示:

select site, lote, material, cast(collect(value) as DBMSOUTPUT_LINESARRAY) AS valueagg
from table1
GROUP BY site, lote, material, status;

SITE   LOTE    MA VALUEAGG
------ ------- -- ----------------------------------------------------------------------------------
AAKI01 0000443 HW SYS.DBMSOUTPUT_LINESARRAY('9362','10k','1st','USERS','8','100MW','2','V2','CELL')

但是当我尝试对第一个查询(如cast(collect(valueagg) as DBMSOUTPUT_LINESARRAY))的结果进行另一次聚合时,我收到错误,如下例所示:

SELECT site, material, cast(collect(valueagg) as DBMSOUTPUT_LINESARRAY) AS valueagg2
FROM table1_agg -- result of first query
GROUP BY site, material;

Error report -
SQL Error: ORA-00932: inconsistent datatypes: expected - got -
00932. 00000 -  "inconsistent datatypes: expected %s got %s"

我试图转换为varchar2,即使它会限制结果 - 我并不担心这一点,因为字符串的前4000个字符对我来说已经足够了 - 但我无法做到这一点。

1 个答案:

答案 0 :(得分:0)

DBMSOUTPUT_LINESARRAY是varchar2的varray,所以你的第一个查询很好; collect()调用获取字符串集合,并且可以将其强制转换为DBMSOUTPUT_LINESARRAY varray集合类型。

您的第二个查询是尝试创建集合集合。 As the documentation says

  

如果column本身就是一个集合,那么COLLECT的输出就是一个嵌套的集合表。

collect()调用尝试创建的是字符串集合的集合,它与DBMSOUTPUT_LINESARRAY的类型不同。您可以创建自己的类型来支持:

create type demo_type as varray(100) of DBMSOUTPUT_LINESARRAY -- or as big as you need
/

然后你可以这样做:

SELECT site, material, cast(collect(valueagg) as DEMO_TYPE) AS valueagg2
FROM table1_agg GROUP BY site, material;

SITE   MA VALUEAGG2
------ -- ---------------------------------------------------------------------------------------------------------
AAKI01 HW MYSCHEMA.DEMO_TYPE(PUBLIC.DBMSOUTPUT_LINESARRAY('9362','10k','1st','USERS','8','100MW','2','V2','CELL'))

或者可能更明显地显示不同的lote值,因此您的第一个查询会有两行:

select site, lote, material, cast(collect(value) as DBMSOUTPUT_LINESARRAY) AS valueagg
from table1 GROUP BY site, lote, material;

SITE   LOTE    MA VALUEAGG
------ ------- -- ----------------------------------------------------------------------------------------------------
AAKI01 0000443 HW SYS.DBMSOUTPUT_LINESARRAY('9362','8','100MW','2','V2','CELL')                                       
AAKI01 0000444 HW SYS.DBMSOUTPUT_LINESARRAY('USERS','10k','1st')

SELECT site, material, cast(collect(valueagg) as DEMO_TYPE) AS valueagg2
FROM table1_agg GROUP BY site, material;

SITE   MA VALUEAGG2
------ -- ---------------------------------------------------------------------------------------------------------------------------------------
AAKI01 HW MYSCHEMA.DEMO_TYPE(PUBLIC.DBMSOUTPUT_LINESARRAY('9362','8','100MW','2','V2','CELL'),PUBLIC.DBMSOUTPUT_LINESARRAY('USERS','10k','1st'))

我不确定这真的是你想要的;我怀疑你想要一个包含两个聚合值的值的集合。这意味着要取消它们并重新组合它们:

SELECT site, material, cast(collect(column_value) as DBMSOUTPUT_LINESARRAY) AS valueagg2
FROM table1_agg CROSS JOIN TABLE(valueagg) v
GROUP BY site, material;

SITE   MA VALUEAGG2
------ -- ----------------------------------------------------------------------------------
AAKI01 HW SYS.DBMSOUTPUT_LINESARRAY('9362','1st','10k','USERS','CELL','V2','2','100MW','8')

回到原始数据并从头开始聚合可能更简单,因为您使用的varray类型不能用于多集操作。