web-dev-qa-db-fra.com

ORA-00932: Types de données incohérents: attendus - Obtenu CLOB

Considérant que TEST_SCRIPT est une CLOB pourquoi, lorsque j'exécute cette requête simple à partir de SQL * PLUS sur Oracle, le message d'erreur suivant s'affiche:

ORA-00932: inconsistent datatypes: expected - got CLOB

J'ai lu beaucoup de questions sur la même erreur, mais aucune d'entre elles n'exécute une requête directe à partir de SQLPLUS 

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

Exemple complet:

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
51
user1298925

Vous ne pouvez pas mettre un CLOB dans la clause WHERE. De la documentation :

Les objets de grande taille (LOB) ne sont pas pris en charge dans les conditions de comparaison . Toutefois, vous pouvez utiliser des programmes PL/SQL pour effectuer des comparaisons sur des données CLOB.

Si vos valeurs sont toujours inférieures à 4k, vous pouvez utiliser:

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

De toute façon, il est étrange de chercher par un CLOB. Ne pourriez-vous pas simplement chercher dans la colonne ID?

56
Craig

La même erreur se produit également lors de l'exécution de SELECT DISTINCT ..., <CLOB_column>, ....

Si cette colonne CLOB contient des valeurs inférieures à la limite de VARCHAR2 dans toutes les lignes applicables, vous pouvez utiliser to_char(<CLOB_column>) ou concaténer les résultats de plusieurs appels à DBMS_LOB.SUBSTR(<CLOB_column>, ...).

22
Franc Drobnič

Prenez un sous-élément du CLOB puis convertissez-le en un caractère:

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

Le problème réside peut-être dans la sélection de valeurs null en combinaison avec une colonne de type 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

J'ai retravaillé le curseur . Le premier curseur est composé de quatre colonnes non nulles . Le deuxième curseur sélectionne trois colonnes non nulles . Les valeurs nulles ont été injectées dans le curseurForLoop.

1
Taeke

Je viens de passer en revue celui-ci et j'ai découvert par accident que des CLOB peuvent être utilisés dans une requête similaire

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

Cela a également fonctionné pour les CLOB supérieurs à 4K

La performance ne sera pas grande mais ce n’était pas un problème dans mon cas.

0
Turo

J'ai constaté que la sélection d'une colonne clob dans CTE avait provoqué cette explosion. c'est à dire

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

sans doute parce qu'Oracle ne peut pas gérer un clob dans une table temporaire.

Comme mes valeurs étaient supérieures à 4K, je ne pouvais pas utiliser to_char().
Mon travail consistait à le sélectionner dans la version finale select, c’est-à-dire

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

Dommage si cela pose un problème de performance.

0
Bohemian