预期的CHAR得到了NUMBER



DB:Oracle 11g

查询:

SELECT CASE
      WHEN rs.OPTION = '3'
      THEN
        (SELECT COUNT(DISTINCT ex.EXTS) AS TMPCOL0
        FROM CRSIDM.SUB_OPTS ex
        INNER JOIN CRSIDM.SUB_OPTS_GRP cg
        ON  cg.GROUP_ID   = ex.GRP_ID        
        )
      ELSE
        (SELECT COUNT(DISTINCT ex.EXTS) AS TMPCOL0
        FROM CRSIDM.SUB_OPTS ex
        INNER JOIN CRSIDM.SUB_OPTS_POL cg
        ON  cg.GROUP_ID   = ex.GRP_ID
        )
    END    AS PROPTS
  FROM PR_OPTS

我得到错误"预期的CHAR得到了数字",这里是EXTS,GROUP_ID&GRP_ID是数字。那么怎么会有机会期待CHAR呢?

通常,当Oracle比较不同的数据类型(如NUMBER和CHARACTER)时,会进行隐式转换,一切都很好(前提是数据可以转换。)例如,如果您有一个函数需要一个CHARACTER值,但您给它传递了一个NUMBER,一切都好-Oracle只需将NUMBER转换为字符。

例如,像这样的函数:

create or replace function get_something(p_id VARCHAR2) return number ...

如果你这样称呼它:

get_dno(10);

或者这个:

get_dno('10');

以及在SQL中:

select * from some_table where numeric_column = '10' -- no problem.

在CASE语句中的返回值是常见的此类错误。例如,如果你有这样的东西,你会得到错误:

SQL> SELECT CASE WHEN 1 = 1 THEN '1' ELSE 2 END
  2  FROM dual
  3  ;
SELECT CASE WHEN 1 = 1 THEN '1' ELSE 2 END
                                     *
ERROR at line 1:
ORA-00932: inconsistent datatypes: expected CHAR got NUMBER

(第一个WHEN子句的数据类型是它在后面的其他WHEN/ELSE子句中所期望的数据类型。)

但在您的情况下,WHEN和THEN都返回计数-数据类型是一致的。所以,我认为你在转移注意力。

正如Alex上面提到的,OPTION是一个关键字,如果你试图用它作为列名创建一个表,Oracle不同意:

SQL> create table dummy
  2  (option varchar2(10)
  3  );
(option varchar2(10)
 *
ERROR at line 2:
ORA-00904: : invalid identifier

这项工作:

SQL> create table dummy
  2  (option_col varchar2(10)
  3  );
Table created.

或者你可以用引号:

SQL> create table dummy
  2  ("option" varchar2(10));
Table created.

但现在你身处一个充满伤害的世界——从现在起你需要引用:

SQL> select option from dummy;
select option from dummy
       *
ERROR at line 1:
ORA-00936: missing expression
SQL> select d.option from dummy d;
select d.option from dummy d
         *
ERROR at line 1:
ORA-01747: invalid user.table.column, table.column, or column specification

带引号:

SQL> select d."option" from dummy d;
no rows selected

所以,如果你的查询真的给了你"预期的CHAR,得到的NUMBER",在我看来好像有什么不对劲

本质上,这意味着您正在使用的某些字段彼此不兼容。这基本上是一种"类型不匹配"。只需检查是否有任何类型的CHAR与NUMBER类型一起使用即可。然后,您可以切换一个的类型,也可以简单地将转换作为查询的一部分。

问题是OPTION = '3',引号表示您正在查找包含单独字符3的字符串。

试试这个:

SELECT CASE 
    WHEN rs.OPTION = 3 
    THEN 
        (SELECT COUNT(DISTINCT ex.EXTS) AS TMPCOL0 
        FROM CRSIDM.SUB_OPTS ex 
        INNER JOIN CRSIDM.SUB_OPTS_GRP cg 
        ON cg.GROUP_ID = ex.GRP_ID)
    ELSE
        (SELECT COUNT(DISTINCT ex.EXTS) AS TMPCOL0
        FROM CRSIDM.SUB_OPTS ex
        INNER JOIN CRSIDM.SUB_OPTS_POL cg
        ON cg.GROUP_ID = ex.GRP_ID)
    END AS PROPTS
FROM PR_OPTS

最新更新