【问题标题】:Union causing an ORA-01790: expression must have same datatype as corresponding expression导致 ORA-01790 的联合:表达式必须具有与相应表达式相同的数据类型
【发布时间】:2023-04-01 06:43:01
【问题描述】:

以如下查询为例:

  select p.product_id, p.product_name, 
     product_type as product_type,
      from products
    group by p.product_id, p.product_name
  union
    select p.product_id, p.product_name, 
     cast(collect(coalesce(product_type, decode(product_description,null,'DESCR' || '-' product_description) as my_type) as product_type,
    from products
    group by p.product_id, p.product_name

第一个查询中的 select 语句以 varchar 形式返回 product_type,第二个查询中 product_type 的类型为 my_type。 这是导致 ORA-01790: 表达式必须具有与相应表达式相同的数据类型,因为数据类型不相同。

是否可以将第一个查询的 product_type 转换为 my_type 类型?

我尝试如下所示更改第一个查询,但没有成功。

select p.product_id, p.product_name, 
     cast(product_type as my_type) as product_type,
     decode(product_source_location, null, 'NO_SOURCE', product_source_location)
    from products
    group by p.product_id, p.product_name

编辑

my_type 定义为'TYPE "my_type" AS TABLE OF varchar2(4000)'

【问题讨论】:

  • 有可能吗?当你尝试时发生了什么?如果没有,您可以在 my_type 字段上运行 to_char 吗?
  • 当我尝试它时,它给了我一个 [1]: ORA-00902: invalid datatype error。
  • my_type 被定义为 'TYPE "my_type" AS TABLE OF varchar2(4000)'
  • 我怀疑第一个 SELECT 是否正确,因为 product_typeproduct_source_location 都不是 GROUP BY 的一部分。
  • 我已更正查询。

标签: sql oracle collections oracle10g oracle11g


【解决方案1】:

我认为你不能在 SQL 中进行这种转换。但在 PL/SQL 中,您可以:

CREATE OR REPLACE TYPE STRARRAY AS TABLE OF VARCHAR2 (255)
/

DECLARE
  tab STRARRAY;
  cnt NUMBER:= 0;
BEGIN
 SELECT COUNT(*)
  INTO cnt
   FROM TABLE(CAST(tab AS strarray));
  dbms_output.put_line(cnt);
END;
/

我认为我上面的假设是错误的。我没有删除它,因为它仍然是有效的例子。下面的示例使用 COLLECT 将现有表列(emp 表)转换为 table_type 类型:

CREATE OR REPLACE TYPE varchar2_ntt AS TABLE OF VARCHAR2(4000);
/

SELECT deptno
    , CAST(COLLECT(ename) AS varchar2_ntt) AS emps
  FROM   scott.emp
GROUP  BY deptno
/

-- This is dumb but works:

SELECT deptno
     , CAST(COLLECT(ename) AS varchar2_ntt) AS emps
  FROM   scott.emp
 GROUP  BY deptno
 UNION ALL
 SELECT deptno
     , CAST(COLLECT(ename) AS varchar2_ntt) AS emps
   FROM   scott.emp
  GROUP  BY deptno
 /

【讨论】:

  • 谢谢。我正在使用 JDBC 运行此查询,因此无法使用 PL/SQL
  • 如果你把它做成一个存储过程呢?
  • 您的铸造示例正是我在联合的第二个查询中所做的。问题是您不能将该查询与返回 varchar 的列联合。我尝试使用 to_Clob 转换为 clob,但数据类型不一致。
  • @ziggy - 请发布您的示例结构。我也许可以帮助你更多。尝试 UNION ALL 和 group by。请看我的例子。
  • @Art 好的,我尝试使用 Union All,这似乎有效。它不喜欢 Union 本身。我不希望有重复,所以 Union All 应该没问题。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多