問題
次のようなクエリを実行する SQLRPGLE プログラムがあります。
SELECT orapdt, oraptm, orodr#, c.ccctls, orbill, b.cuslmn, b.cusvrp, orocty, orost, o.cubzip, o.cucnty, ordcty, ordst, d.cubzip, d.cucnty
FROM order
LEFT JOIN cmtctlf c ON orbill = c.cccode
LEFT JOIN custmast b ON orbill = b.cucode
LEFT JOIN custmast o ON orldat = o.cucode
LEFT JOIN custmast d ON orcons = d.cucode
WHERE
orstat != 'C' AND
orbill IN ('ABCDE', 'VWXYZ', 'JKFRTE') AND
orapdt BETWEEN 2012365 AND 2013362 AND
o.cucnty = 'USA' AND
(o.cubzip LIKE '760%' OR o.cubzip LIKE '761%' OR o.cubzip LIKE '762%') AND
d.cubzip = '38652' AND
ordcty = 'NA' AND
ordst = 'MS' AND
d.cucnty = 'USA'
ORDER BY orapdt, oraptm, orodr#
フィールド定義:
orapdt 7 0
oraptm 4a
orodr# 7a
c.ccctls 6a
orbill 6a
b.cuslmn 2a
b.cusvrp 3a
orocty 4a
orost 2a
o.cubzip 5a
o.cucnty 3a
ordcty 4a
ordst 2a
d.cubzip 5a
d.cucnty 3a
c.cccode 6a
b.cucode 6a
o.cucode 6a
d.cucode 6a
ジョブ ログに次のエラーが表示されます。
Field HVR0001 and value 1 not compatible. Reason 7.
Conversion error on host variable or parameter *N.
追加のメッセージ情報を求めるプロンプトが表示されると、次のように表示されます。
The attributes of variable field HVR0001 in query record format FORMAT0001 are not compatible with the attributes of value number 1. The value is *N. The reason code is 7.
7 -- Value contains numeric data that is not valid
と
Host variable or parameter *N or entry 1 in a descriptor area contains a value that cannot be converted to the attributes required by the statement. Error type 6 occurred.
6 -- Numeric data that is not valid.
これらのエラーは、カーソルを開くとトリガーされます。
...
exec sql PREPARE S1 FROM :sql_stmt;
exec sql DECLARE C1 SCROLL CURSOR FOR S1;
exec sql OPEN C1;
...
outq には、ダンプ情報で満たされた QSQSVCDMP ファイルもあります。そこにある唯一の有用なものは、CPF4278 と CPD4374 への参照です。
CPF4278 の意味Query definition template &1 not valid.
CPD4374 の意味Field &1 and value &3 not compatible. Reason &5.
残念ながら、エラー メッセージ自体は存在せず、"CPF4278" と "CPD4374" という文字列のみです。
プログラムでは、SQLエラーコードを監視していますが、それらはすべて同じです:
SQLSTATE: 22023
SQLCODE: -302
SQLERRMC: <non-displayable character>*N
エラー状態/コードは、「パラメーターまたは変数の値が無効です」を意味します。
私が試したこと...
多くのグーグルの後、私は試しました:
- ORDER BY 句の削除 (OPEN では、ORDER BY 句がある場合、データがフェッチされて並べ替えられます)
- すべての LEFT JOIN を INNER JOIN に変更します (右側の結果レコードに NULL がないことを確認するためにこれを行いました)
- WHERE句に「AND orapdt IS NOT NULL」を追加
- 私が忘れてしまった多くのこと
私が求めているのは...
どのフィールドに不正なデータが含まれているかを調べるにはどうすればよいですか? 無効であることはわかってHVR0001
いますが、どのフィールドが で表されHVR0001
ますか? フィールドを別の順序で選択しようとしましたが、常にHVR0001
無効な値が含まれています。
理想的には、すべての HVR* フィールド/値を印刷して検査できるようにしたいと考えています。
コンパイル リストを見ると、HVR* フィールドがリストされていません。いくつかの SQL_* フィールドがリストされており、SQL_00011
に入れられるデータを一時的に保持するために使用されていることがわかりorapdt
ます。(7,0 パック)SQL_00011
とまったく同じように定義されます。orapdt
それが私のクエリの唯一の数値フィールドです...
私の問題は、ファイルがどのように結合されているか、無効な値 (おそらく NULL) がorapdt
フィールドに配置されていることが原因であると感じています。
また、私の問題は、これらのクエリの多くを次々に実行することと関係があると思います (クエリごとに WHERE 仕様の一部が変更されます)。失敗したクエリの 1 つを取得して、それを独自のプログラムに入れて実行できるからです。そしてそれはうまくいきます。
これは DB2 for i (V6R1) 上にあり、関連するすべてのファイルは DDS を使用して作成されました
編集:ホスト変数(データ構造)とLIKEステートメントに必要な2つの外部データ構造は次のとおりです。
d eds_custmast e ds extname('CUSTMAST') inz
d eds_order e ds extname('ORDER') inz
d o ds
d orapdt like(ORAPDT)
d oraptm like(ORAPTM)
d orodr# like(ORODR#)
d orctls like(CUCODE)
d orbill like(ORBILL)
d orslmn like(CUSLMN)
d orcsr like(CUSVRP)
d orocty like(OROCTY)
d orost like(OROST)
d orozip like(CUBZIP)
d orocntry like(CUCNTY)
d ordcty like(ORDCTY)
d ordst like(ORDST)
d ordzip like(CUBZIP)
d ordcntry like(CUCNTY)
// Define an array to indicate nulls...
d o1nv s 3i 0 dim(15)
実際にデータを取得する fetch ステートメントは次のとおりです。
dow sqlcode = *zeros;
exec sql FETCH NEXT FROM C1 INTO :o :o1nv;
if sqlcode = *zeros;
// process the data.
endif;
enddo;
exec sql CLOSE C1;
行をFETCHするのではなく、カーソルをOPENするときにエラーが発生するため、以前はこれを含めませんでした。o
OPEN ステートメントは、データ構造について何も認識してはなりません。
WHERE 句で何が変更されるかについては、次のもの以外はすべて動的に構築されます (したがって、変更される可能性があります)。
orstat != 'C' AND orapdt BETWEEN 2012365 AND 2013362