为什么是 ORA-00932:不一致类型错误?

Jac*_*ung 5 oracle oracle-11g-r2

抱歉这个毫无意义的标题,但我想不出更好的标题。我正在使用 Oracle 11g r2。

以下查询引发 ORA-00932 错误:

SELECT BBB.FIELD1 FROM TABLE0 AAA
  JOIN (SELECT * FROM (SELECT AAA.*, RANK() OVER (PARTITION BY SUBSTR(FIELD1,1,1) ORDER BY SUBSTR(FIELD1,1,1),ROWNUM) AS RANK
      FROM TABLE1@DBLINK AAA WHERE UPPER(NAME)!='XXX')
    WHERE RANK<=1) BBB ON CAST(CAST(CAST(SUBSTR(BBB.FIELD1,2,LENGTH(BBB.FIELD1)-2) AS NUMBER) AS VARCHAR2(10))||SUBSTR(BBB.FIELD1,LENGTH(BBB.FIELD1)) AS VARCHAR2(4000))=CAST(CAST(CAST(SUBSTR(AAA.FIELD0,2,LENGTH(AAA.FIELD0)-2) AS NUMBER) AS VARCHAR2(10))||SUBSTR(AAA.FIELD0,LENGTH(AAA.FIELD0)) AS VARCHAR2(4000));
Run Code Online (Sandbox Code Playgroud)

但是,以下查询完全正常。

SELECT * FROM TABLE0 AAA
  JOIN (SELECT * FROM (SELECT AAA.*, RANK() OVER (PARTITION BY SUBSTR(FIELD1,1,1) ORDER BY SUBSTR(FIELD1,1,1),ROWNUM) AS RANK
      FROM TABLE1@DBLINK AAA WHERE UPPER(NAME)!='XXX')
    WHERE RANK<=1) BBB ON CAST(CAST(CAST(SUBSTR(BBB.FIELD1,2,LENGTH(BBB.FIELD1)-2) AS NUMBER) AS VARCHAR2(10))||SUBSTR(BBB.FIELD1,LENGTH(BBB.FIELD1)) AS VARCHAR2(4000))=CAST(CAST(CAST(SUBSTR(AAA.FIELD0,2,LENGTH(AAA.FIELD0)-2) AS NUMBER) AS VARCHAR2(10))||SUBSTR(AAA.FIELD0,LENGTH(AAA.FIELD0)) AS VARCHAR2(4000));
Run Code Online (Sandbox Code Playgroud)

唯一的区别是我选择了所有 (*) 列,而不是指定一个特定的列。为什么会这样?

编辑

引发的错误是(完全如此):

ORA-00932: inconsistent datatypes: expected  got 
ORA-02063: preceding line from DBLINK
00932. 00000 -  "inconsistent datatypes: expected %s got %s"
*Cause:    
*Action:
Run Code Online (Sandbox Code Playgroud)

小智 3

当您将 varchar 转换为数字时,您必须确保此表中的所有值都可以这样做。因此,在您的情况下,您认为也可以通过“WHERE UPPER(NAME)!='XXX'”过滤值。原因是优化器不必遵循查询中逻辑的特定顺序。因此它可以首先进行表的转换和连接,然后才进行内部查询中指定的过滤。将 * 更改为特定字段可以更改优化器选择的执行计划,因此您可能会遇到一个版本的问题,而另一个版本不会出现问题。

您可以使用自己的函数来避免此错误:

create or replace function tonumberorzero(txt in varchar2) return number
 is
   retval number;
 begin
    return to_number(txt);
 exception
    when invalid_number then return 0;
 end;
Run Code Online (Sandbox Code Playgroud)