2012-02-10 5 views
2

DB2 v9.7とSQL LIKE演算子で面白い問題が見つかりました。これをチェックアウト:DB2 LIKE演算子で奇妙な長さの制限

-- this works and returns one record 
select 1 
from SYSIBM.DUAL 
where 'abc' like concat('a', 'bc') 

-- this doesn't work 
select 1 
from SYSIBM.DUAL 
where 'abc' like concat(cast('a' as varchar(2001)), cast('bc' as varchar(2000))) 

-- It causes this error (from JDBC): 
-- No authorized routine named "LIKE" of type "FUNCTION" having compatible 
-- arguments was found.. SQLCODE=-440, SQLSTATE=42884, DRIVER=4.7.85 

私は長さをいじったのだが、問題は、すぐに長さが4000よりも大きくなるまで追加として表示されているようです。私は長さ4000に戻す全体を連結した文字列を「切り捨て」した場合、問題が消える:

select 1 
from SYSIBM.DUAL 
where 'abc' like 
    cast(concat(cast('a' as varchar(2001)), cast('bc' as varchar(2000))) 
    as varchar(4000)) 

興味深いことに、本当にCONCAT機能に関係しているようです。以下も同様です:

select 1 
from SYSIBM.DUAL 
where 'abc' like cast('abc' as varchar(32672)) 

誰もこのような問題を経験しましたか? DB2のバグですか?あるいは何らかの文書化されていない制限? NB:他のIBM製品は、2010年にこの問題の回避策を作成することを考えると

https://www-304.ibm.com/support/docview.wss?uid=swg1PM18687

を、私はそれが本当にバグではありませんだと思う、それ以外の場合は平均時間で修正されているだろう:私はここに同様の問題を発見しました?

+0

これは、JDBCドライバーとの相互作用に関連している可能性があります。私のiSeries(V6R1)でネイティブに実行してもエラーは発生しません。 –

+0

@ X-Zero:私の場合はありません。私はコンソールに同じエラー42884を再現することができます... –

答えて

2

編集: Aha!

VARCHARの上の知識の他のビットのための情報センターを探している間、私はcharacter data type page上の情報のこの気の利いたちらほら発見:それはDB2の知られている「機能」だようなので、

The functions in the SYSFUN schema taking a VARCHAR as an argument will not accept VARCHARs greater than 4 000 bytes long as an argument. However, many of these functions also have an alternative signature accepting a CLOB(1M). For these functions, the user may explicitly cast the greater than 4 000 VARCHAR strings into CLOBs and then recast the result back into VARCHARs of desired length.

を、それが見えます。

私はいくつかの追加テストを行いました。Linux/Unix/Windows上のDB2では上記の「回避策」が機能しますが、メインフレーム上のDB2では機能しません。あなたは表7(第3行)を見れば、情報センターからSQL and XML Limitsページのオフに行く


、それは言うこと4Kページ・サイズの表スペースのすべてのオーバーヘッドを含む行の最大長4005バイトです。

私の推測では、SYSIBM.DUALは4kページ・サイズの表スペースにあり、エラーが発生しています。 SYSCAT.TABLESPACESを確認することができます。これにより、この疑惑が確認されたり拒否されたりする可能性があります。

あなたはそうのようなクエリを使用して情報を得ることができます。

SELECT ts.PAGESIZE 
FROM SYSCAT.TABLESPACES ts 
JOIN SYSCAT.TABLES tb 
    ON tb.TBSPACEID = ts.TBSPACEID 
WHERE tb.TABSCHEMA = 'SYSIBM' 
    AND tb.TABNAME = 'DUAL' 
+0

うーん、それはマイケルの提案とよく似ています。しかし、あなたのクエリは私のデータベースインスタンスで '8192'を返します。私がこの質問で言及したように、この問題は 'CONCAT'では発生しません。' abc 'のようなキャスト(' abc 'はvarchar(32672)) '...面白いです。 –

+1

DB2 Linux/ERROR [42824] [IBM] [DB2] SQL0132N LIKE述部またはPOSSTRスカラー関数は有効ではないため、このエラーは発生します。最初のオペランドは文字列式ではなく、2番目のオペランドは文字列ではありません。最初のオペランドが文字列でないか、2番目のオペランドが文字列式ではないため、LOCATEまたはPOSITIONスカラー関数は無効です。 SQLSTATE = 42824'となります。 'VARCHAR'の制限参照には32704という最大の長さがあるので、問題の原因はわかりません。興味深い。 :) – bhamby

+0

本当に面白いです。もし私が知っていれば、私はDB2にバグ報告を提出するでしょう... –

1

これは、テーブルが存在するテーブルスペースのrowsizeに関連する可能性がありますか?

DB2 varcharが問合せ対象の表のrowsizeを超えている場合は、LONG VARCHARとして宣言し、残りの表データに外部に格納し、ポインタおよびLIKE問合せで参照する必要があります。もはや不可能である。しかし、私はDB2を何年も使っていません。 :)

+0

どうすればこれをチェックできますか? 'SYSIBM.DUAL'から選択すると、そのような設定が適用されますか?そして、これはどのようにして問題が 'CONCAT'でのみ起こると説明できますか? –

4

本当のなるほど!はこちら

最初に、rules for the concatenation operator結果タイプによれば、2つのVARCHARを4000バイト以下の結合長で連結すると、その結合された長さのVARCHARが生成されます。 concat(varchar(2000), varchar(2000)) = varchar(4000)。 4001バイト以上の長さの結合された2つのVARCHARを連結すると、長さが32 700のLONG VARCHARが生成されます.LONG VARCHAR型は推奨されなくなりましたが、連結動作でも引き続き従来のロジックが使用されています。

$ db2 describe "values concat(cast('a' as varchar(2000)), cast('bc' as varchar(2000)))" 

Column Information 

Number of columns: 1 

SQL type    Type length Column name      Name length 
-------------------- ----------- ------------------------------ ----------- 
448 VARCHAR    4000 1           1 


$ db2 describe "values concat(cast('a' as varchar(2001)), cast('bc' as varchar(2000)))" 

Column Information 

Number of columns: 1 

SQL type    Type length Column name      Name length 
-------------------- ----------- ------------------------------ ----------- 
456 LONG VARCHAR   32700 1  

第二に、LIKE predicateは、パターン式が32672バイトの最大長VARCHARことを期待します。

その後、パターン表現として知らないうちにLONG VARCHARを使用しようとすると、エラーが発生します。オペランドの長さは、データ型と同じくらいです。

+0

それはうまく説明します、ありがとう。結果をカバーするのに十分な大きさの 'varchar'型がまだあっても、データ型が変更されることはまだ面白いです... –

+0

ある種の遺産でなければなりません。 LONG VARCHARは推奨されておらず、組み込み関数によって返されるべきではないので、PMRをオープンしました。 – mustaccio

+0

ニース。そのPMRへのリンクをここに投稿して、それを追跡するのは興味深いでしょう –

関連する問題