ORA-00932: 数据类型不一致:期望 - 得到 CLOB。

88

考虑到TEST_SCRIPTCLOB类型,为什么当我在Oracle的SQL*PLUS中运行这个简单的查询时会出现错误:

ORA-00932: inconsistent datatypes: expected - got CLOB

我阅读了许多关于同一个错误的问题,但没有一个是直接从SQLPLUS运行查询

    UPDATE IMS_TEST 
       SET TEST_Category  = 'just testing'  
     WHERE TEST_SCRIPT    = 'something'
       AND ID             = '10000239' 

完整示例:

SQL> create table ims_test(
  2  test_category varchar2(30),
  3  test_script clob,
  4  id varchar2(30)
  5  );

Table created.

SQL> insert into ims_test values ('test1','something','10000239');

1 row created.

SQL> UPDATE IMS_TEST
  2  SET TEST_Category  = 'just testing'
  3  WHERE TEST_SCRIPT    = 'something'
  4  AND ID             = '10000239';
WHERE TEST_SCRIPT    = 'something'
      *
ERROR at line 3:
ORA-00932: inconsistent datatypes: expected - got CLOB

@user1298925,这个查询语句可以工作,但如果您尝试在CLOB字段中插入超过4000个字符,它将失败。 - rs.
1
@user1298925 - 在你发布的问题中,围绕字符串 just testing 的引号是微软花式引号 而不是普通单引号 '。我在我的编辑中更正了这个问题,但我不确定这是否会影响你的原始脚本,或者这是否是创建和发布你的问题过程中引入的问题。你是说,在示例脚本中,字符串实际上只有大约10个字符长吗? - Justin Cave
是的,它们只有大约10个字符,而且我确保我的单引号也正确输入了。 - user1298925
我添加了一个完整的示例,因此可以轻松地重新创建它。 - Craig
潜在重复:https://dev59.com/GUXRa4cB1Zd3GeqPqD5b - StevieG
显示剩余2条评论
8个回答

92

你不能在WHERE子句中使用CLOB。根据文档

大型对象(LOB)不支持比较条件。 但是,您可以使用PL/SQL程序进行CLOB数据的比较。

如果您的值始终小于4k,则可以使用:

UPDATE IMS_TEST 
   SET TEST_Category           = 'just testing'  
 WHERE to_char(TEST_SCRIPT)    = 'something'
   AND ID                      = '10000239';

无论如何,按CLOB搜索是奇怪的..你不能只按ID列搜索吗?


1
CLOB字段也不能在MINUS操作中使用。 - Bor
10
如果您的值可能超过4K,您可以使用 where dbms_lob.compare(testscript,:var2) = 0 ,参见https://dev59.com/vmjWa4cB1Zd3GeqPutuA#12590223 - Roland
@Jewels:我也遇到了404错误,然后再次尝试链接,就奇怪地成功了。 - bernard paulus
1
只是另一个Oracle的奇怪错误消息。在where子句中使用CLOB和“期望-得到CLOB”之间没有任何关联。顺便说一下,谢谢。 - yılmaz
2
"比较条件"还包括SELECT DISTINCTGROUP BY - mike

51

当执行 SELECT DISTINCT ..., <CLOB_column>, ... 命令时,也会出现同样的错误。

如果此 CLOB 列包含的值在所有适用行中都短于 VARCHAR2 的限制,则可以使用 to_char(<CLOB_column>) 或将多次调用 DBMS_LOB.SUBSTR(<CLOB_column>, ...) 的结果连接起来。


3
也适用于GROUP BY子句中的CLOB。同样的原因。 :-) - mike

13

截取CLOB的子串,然后将其转换为char:

UPDATE IMS_TEST 
  SET TEST_Category           = 'just testing' 
WHERE to_char(substr(TEST_SCRIPT, 1, 9))    = 'something'
  AND ID                      = '10000239';

5

我刚刚无意中发现CLOBs可以用于LIKE查询:

   UPDATE IMS_TEST 
   SET TEST_Category  = 'just testing'  
 WHERE TEST_SCRIPT    LIKE '%something%'
   AND ID             = '10000239' 

这也适用于大于4K的CLOB。

性能可能不会很好,但在我的情况下这不是问题。


你可以在不使用 % 通配符的情况下使用 LIKE。这样可以确保只匹配精确值(并且应该更快,但我不知道实际上是否如此)。 WHERE TEST_SCRIPT LIKE 'something' - Scar

2

我发现在CTE中选择一个列会导致这种情况。即

with cte as (
    select
        mytable1.myIntCol,
        mytable2.myClobCol
    from mytable1
    join mytable2 on ...
)
select myIntCol, myClobCol
from cte
where ...

可能是因为Oracle无法处理临时表中的CLOB。

由于我的值超过了4K,我不能使用to_char()函数。
我的解决方法是从最终的select语句中选择它。

with cte as (
    select
        mytable1.myIntCol
    from mytable1
)
select myIntCol, myClobCol
from cte
join mytable2 on ...
where ...

如果这导致性能问题,那就太糟糕了。


1
问题可能在于选择的空值与 CLOB 类型列的组合。
select valueVarchar c1 ,
       valueClob c2 ,
       valueVarchar c3 ,
       valueVvarchar c4
of Table_1
union
select valueVarchar c1 ,
       valueClob c2 ,
       valueVarchar c3 ,
       null c4
of table_2

我重新制作了游标。 第一个游标由四个非空列组成。 第二个游标选择三个非空列。 空值被注入到游标循环中。


0
在我的情况下,我正在使用EntityFramework,并且我尝试使用的列名为value - 即Oracle的保留关键字。

0
通常解决这个问题,只需使用TO_CHAR函数,例如将日期转换为 'DD/MM/RRR hh24:mi:ss' 格式。
TO_CHAR(date_value ,''DD/MM/RRRR hh24:mi:ss'') 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接