TEST_SCRIPT
がCLOB
であると考えると、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
WHERE句にCLOBを含めることはできません。 ドキュメント から:
比較条件では、ラージオブジェクト(LOB)はサポートされていません。ただし、CLOBデータの比較にはPL/SQLプログラムを使用できます。
値が常に4kより小さい場合は、次を使用できます。
UPDATE IMS_TEST
SET TEST_Category = 'just testing'
WHERE to_char(TEST_SCRIPT) = 'something'
AND ID = '10000239';
とにかくCLOBで検索するのは奇妙です。ID列だけで検索することはできませんか?
SELECT DISTINCT ..., <CLOB_column>, ...
を実行するときにも同じエラーが発生します。
このCLOB列に、該当するすべての行にVARCHAR2の制限よりも短い値が含まれる場合、to_char(<CLOB_column>)
を使用するか、DBMS_LOB.SUBSTR(<CLOB_column>, ...)
の複数の呼び出しの結果を連結できます。
CLOBのsubstrを取得して、charに変換します。
UPDATE IMS_TEST
SET TEST_Category = 'just testing'
WHERE to_char(substr(TEST_SCRIPT, 1, 9)) = 'something'
AND ID = '10000239';
問題は、CLOB型の列と組み合わせて選択されたnull値にある可能性があります。
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
カーソルを作り直しました。最初のカーソルは、4つの非ヌル列で構成されています。 2番目のカーソルは、3つの非NULL列を選択します。 null値はcursorForLoopに注入されました。
私はこれを実行しましたが、偶然にCLOBを同様のクエリで使用できることがわかりました。
UPDATE IMS_TEST
SET TEST_Category = 'just testing'
WHERE TEST_SCRIPT LIKE '%something%'
AND ID = '10000239'
これは、4Kを超えるCLOBでも機能しました。
パフォーマンスは素晴らしいものではありませんが、私の場合は問題ありませんでした。
CTEでclob
列を選択すると、この爆発が発生することがわかりました。すなわち
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 ...
これがパフォーマンスの問題を引き起こす場合は、残念です。