How To
Summary
Error code = -4220 は文字変換中にエラーが発生した事を意味します。問題の抜本的解決には、エラーの原因となったデーターの除去や修正などの対応が必要です。
Objective
文字変換に失敗したデーターを特定だけではなく、該当のデーターを含むレコードを特定する事が重要です。
そこで、以下のステップでは、問題のデーターを戻した SQL ステートメントや、ステートメントのパラメーター・マーカーに渡された値、データーが格納された表とカラムの型もあわせて確認し、最後にレコード全体を取り出します。
Steps
1. JCC トレースの取得
次のいずれかの方法で JCC トレースを取得します。
[DB2 LUW] アプリケーションを変更せずに JDBC トレースを採取する方法
[DB2 LUW] JDBC トレース取得手順 (Universal JDBC Driver)
2. -4220 を受けたデーターを含む ResultSet オブジェクトの確認
JCC トレースで -4220 エラーが戻された場所を確認すると、ここでは、 ResultSet オブジェクトの getObject メソッドでエラーを受けていることが分かります。
ここで [ResultSet@54d7df97]getObject(1) は ResultSet オブジェクト ResultSet@54d7df97 に含まれる、ある行の 1 列目のデーターを取り出すことを意味します。
[jcc][Time:2017-11-15-11:23:46.752][Thread:pool-1-thread-1][ResultSet@54d7df97]getObject (1) called [jcc] BEGIN TRACE_DIAGNOSTICS [jcc][Thread:pool-1-thread-1][SQLException@6242e669] java.sql.SQLException [jcc][Thread:pool-1-thread-1][SQLException@6242e669] SQL state = null [jcc][Thread:pool-1-thread-1][SQLException@6242e669] Error code = -4220 [jcc][Thread:pool-1-thread-1][SQLException@6242e669] Message = [jcc][t4][1065][12306][4.21.29] java.io.CharConversionException をキャッチしました。 詳しくは、添付の Throwable を参照してください。 ERRORCODE=-4220, SQLSTATE=null [jcc][Thread:pool-1-thread-1][SQLException@6242e669] Stack trace follows com.ibm.db2.jcc.am.SqlException: [jcc][t4][1065][12306][4.21.29] java.io.CharConversionException をキャッチしました。 詳しくは、添付の Throwable を参照してください。 ERRORCODE=-4220, SQLSTATE=null at com.ibm.db2.jcc.am.kd.a(kd.java:794) at com.ibm.db2.jcc.am.kd.a(kd.java:66) at com.ibm.db2.jcc.am.kd.a(kd.java:125) at com.ibm.db2.jcc.am.mc.a(mc.java:2963) at com.ibm.db2.jcc.am.mc.a(mc.java:630) at com.ibm.db2.jcc.am.mc.q(mc.java:609) at com.ibm.db2.jcc.am.mc.bb(mc.java:2830) at com.ibm.db2.jcc.am.ResultSet.getObjectX(ResultSet.java:1482) at com.ibm.db2.jcc.am.ResultSet.getObject(ResultSet.java:1453) |
3. ResultSet を返した SQL ステートメントの特定
ステップ 2 で確認した ResultSet@54d7df97 を戻す SQL ステートメントを突き止め、問題のデーターを格納する表と列の名前を確認します。
ResultSet@54d7df97 の @ の後の番号 54d7df97 を return している関数を、トレース上で時間を遡って探すと、次の行が見つかりました。
[jcc][Time:2017-11-15-11:20:02.128][Thread:pool-1-thread-1][PreparedStatement@3224a577]executeQuery () returned com.ibm.db2.jcc.t4.h@54d7df97 |
ここでは 54d7df97 を戻したのは PrepareStatement (準備済み SQL ステートメント) のオブジェクト PreparedStatement@3224a577 に対する executeQuery (PreparedStatement の実行) とわかります。 トレースをさらに遡り、この PreparedStatement@3224a577 を 準備 (Prepare) している箇所を探すと、次の SQL ステートメントが確認できました。
[jcc][Time:2017-11-15-11:19:12.250][Thread:main][Connection@13df2a8c]prepareStatement (SELECT Q1.C1 A1, Q1.C2 A2, Q1.C3 A3, Q1.C4 A4, Q1.C5 A5, Q1.C6 A6, Q1.C7 A7, Q1.C8 A8, Q1.C9 A9, Q1.C10 A10, Q1.C11 A11, Q1.C12 A12, Q1.C13 A13, Q1.C14 A14, Q1.C15 A15, Q1.C16 A16, Q1.C17 A17, Q1.C18 A18, Q1.C19 A19, Q1.C20 A20, Q1.C21 A21, SUBSTR(Q2.C22,1,10) A22 FROM MYTAB1 Q1 INNER JOIN MYTAB2 Q2 ON Q1.C1 = Q2.C1 AND Q2.C2 = ' ' INNER JOIN (SELECT MYTAB3.C1, MYTAB3.C2 FROM MYTAB3 INNER JOIN (SELECT C1, MAX(C3) C3 FROM MYTAB3 GROUP BY C1 ) Q3 ON MYTAB3.C1 = Q3.C1 AND MYTAB3.C3 = Q3.C3 WHERE C4 = '2' ) Q4 ON Q1.C2 = Q4.C2 WHERE Q1.C1 BETWEEN ? AND ? AND Q1.C21 <> 0 GROUP BY Q1.C1, Q1.C2, Q1.C3, Q1.C4, Q1.C5, Q1.C6, Q1.C7, Q1.C9, Q1.C8, Q1.C10, Q1.C11, Q1.C12, Q1.C13, Q1.C14, Q1.C15, Q1.C16, Q1.C17, Q1.C18, Q1.C19, Q1.C20, Q1.C21, Q1.C22, SUBSTR(Q2.C22,1,10)) called [jcc][Time:2017-11-15-11:19:12.250][Thread:main][Connection@13df2a8c]prepareStatement () returned LogicalPreparedStatement@352ff4da[com.ibm.db2.jcc.am.tp@3224a577] |
4. SQL ステートメントに渡されたパラメーター・マーカー値の確認 (オプション作業)
ステップ 3 で確認した SQL ステートメントの条件には「Q1.C1 BETWEEN ? AND ?」と 2 つのパラメーター・マーカーが使用されていました。そこで、パラメーター・マーカーに設定されていた値を確認してみます。
パラメーター・マーカーへの値の設定は、PreparedStatement クラスの setObject メソッドを使用します。
そこで、トレースで prepareStatement がコールされる箇所から executeQuery がコールされまでの間で setObject を探すと、準備済み SQL ステートメント PreparedStatement@3224a577 の 1 つ目のパラメーター・マーカーには 000000000000 が、2 つ目には 008063134327 が設定されていました。
[jcc][Time:2017-11-15-11:19:12.351][Thread:pool-1-thread-1][PreparedStatement@3224a577]setObject (1, 000000000000) called [jcc][Time:2017-11-15-11:19:12.361][Thread:pool-1-thread-1][PreparedStatement@3224a577]setObject (2, 008063134327) called [jcc][Time:2017-11-15-11:19:12.361][Thread:pool-1-thread-1][PreparedStatement@3224a577]executeQuery () called |
これらの値を、ステップ 3 で確認した SQL ステートメント中のパラメーター・マーカーに置き換えて実行すれば、表のデーターが変更されていない限り、問題発生時と同じレコードが戻されるはずです。
5. 問題のデーターを含むカラムの情報確認 (オプション作業)
トレースには、準備済み SQL ステートメント PreparedStatement@3224a577 の実行で戻される ResultSet の Column 1 から 22 までのカラムのメタデーターが出力されています。
この出力より、問題となっている getObject(1) がアクセスする Column 1 は、データベース MYDB のスキーマ MYSCHEMA1 の表 MYTAB1 の列 C1 と分かります。また列タイプは CHAR で長さは 12、NOT NULL でないと分かります。
[jcc][ResultSetMetaData@268489c5] BEGIN TRACE_RESULT_SET_META_DATA [jcc][ResultSetMetaData@268489c5] Column 22: { label=A22 , name=A22 , type name=CHAR, type=1, nullable=1, precision=10, scale=0, schema name=, table name=, writable=false, sqlPrecision=0, sqlScale=0, sqlLength=10, sqlType=453, sqlCcsid=1208, sqlArrExtent=0, sqlName=A22 , sqlLabel=null, sqlUnnamed=0, sqlComment=null, sqludtxType=<null>, sqludtRdb=<null>, sqludtSchema=<null>, sqludtName=<null>, sqlxKeymem=0, sqlxGenerated=0, sqlxParmmode=0, sqlxOptlck=0, sqlxCorname=null, sqlxName=null, sqlxBasename=null, sqlxUpdatable=0, sqlxSchema=null, sqlxRdbnam=MYDB, internal type=1, is locator parameter=false } |
6. Error code = -4220 を生じたレコードの1つ前のレコードの確認
JCC トレースには受信バッファーの内容がダンプされています。
このダンプには、 読み出しに失敗したレコードを含む ResultSet の内容が出力されています。
そこで、まず読み出しに成功した最後のレコードを確認し、そのレコードの次のレコード(=問題のレコード)を受信バッファーのダンプより探します。
まず Error -4220 を出力した行を改めてトレースより探します。
[jcc][Thread:pool-1-thread-1][SQLException@6242e669] Error code = -4220 |
次に、この行よりトレースを遡り、最後に成功した getObject を探します。
ここでは getObject (22) に戻された 640384084 が、最後に読み出したレコードのデーターでした。
レコードの 1 番目のカラム値(getObject(1) の戻り値) から最後の 22 番目のカラム値(getObject(22) の戻り値) を記録しておきます。
その後の next() で ResultSet より取り出している次のレコードが、getObject(1) が失敗した問題のデーターです。
[jcc][Time:2017-11-15-11:23:46.741][Thread:pool-1-thread-1][ResultSet@54d7df97]getObject (1) called [jcc][Time:2017-11-15-11:23:46.741][Thread:pool-1-thread-1][ResultSet@54d7df97]getObject (21) called |
上記のトレース出力よりさらにトレースを遡って確認した、直近の "RECEIVE BUFFER: QRYDTA" が、問題のレコードを含む ResultSet です。
下記の例では、 QRYDTA の最初の12バイト 190AD05300011904 241BFF00 以降が ResultSet のデーターです。
各レコードはFF00で区切られ、各カラム・データーは00で区切られています。
[jcc][t4] RECEIVE BUFFER: QRYDTA (ASCII) (EBCDIC) [jcc][t4] 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF 0123456789ABCDEF [jcc][t4] 0000 190AD05300011904 241BFF0030303830 ...S....$...0080 ..}............. [jcc][t4] 0010 3135333435303534 0031333739003230 15345054.1379.20 ................ [jcc][t4] 0020 31373034000C0000 0000323031373039 1704......201709 ................ [jcc][t4] 0030 0032303137313000 8A01000000310000 .201710......1.. ................ [jcc][t4] 0040 0000000000000000 0000000000000000 ................ ................ [jcc][t4] 0050 0000000000000000 1401000000140100 ................ ................ [jcc][t4] 0060 00000D0000000000 0000000000000000 ................ ................ [jcc][t4] 0070 0000000000000000 0000009701000000 ................ ...........p.... [jcc][t4] 0080 2020202020202020 2020FF0030303830 ..0080 ................ [jcc][t4] 0090 3135333436343832 0038303937003230 15346482.8097.20 ................ [jcc][t4] 00A0 3137303900010000 0000323031373039 1709......201709 ................ [jcc][t4] 00B0 0032303137313000 0000000000330000 .201710......3.. ................ [jcc][t4] 00C0 0000000000000000 0000000000000000 ................ ................ [jcc][t4] 00D0 0000000000000000 0000000000000000 ................ ................ [jcc][t4] 00E0 000000000000005B 0000000000000000 .......[........ .......$........ [jcc][t4] 00F0 0000000000000000 0000005B00000000 ...........[.... ...........$.... .......... |
ここで最初の12バイトは先頭から、次のようになります。
- 4バイトのLength:190A
- 4バイトのDDM Carrier:Chained OBJDSS(D053)
- 4バイトのCorrelation identifier:0001
- 4バイトのLength:1904
- 4バイトのDDM Object:QRYDTA(241B)
- データーの先頭のFF00
※詳細は The Open Group Library より DRDA : FORMATTED DATA OBJECT CONTENT ARCHITECTURE 等をご確認ください。
QRYDTA の中から、1 番目のカラム値が 008015354197 、2 番目が 8097、・・・22列目のカラム値が 640384084 のレコードを探すと、オフセット050C 以降に見つかりました。
640384084 の16進標記 0x36343033383430383420 の後のレコード・セパレーター FF00 以降の 12 バイト 0x2B29226C1E1DA86BAF296AB8 が異常なデーターです。
[jcc][t4] 0500 3536313130313036 3020FF0030303830 561101060 ..0080 ................ [jcc][t4] 0510 3135333534313937 0038303937003230 15354197.8097.20 ................ [jcc][t4] 0520 3137303900010000 0000323031373039 1709......201709 ................ [jcc][t4] 0530 0032303137313000 0000000000330000 .201710......3.. ................ [jcc][t4] 0540 0000000000000000 0000000000000000 ................ ................ [jcc][t4] 0550 0000000000000000 0000000000000000 ................ ................ [jcc][t4] 0560 00000000000000DD 0000000000000000 ................ ................ [jcc][t4] 0570 0000000000000000 000000DD00000000 ................ ................ [jcc][t4] 0580 3634303338343038 3420FF002B29226C 640384084 ..+)"l ...............% [jcc][t4] 0590 1E1DA86BAF296AB8 00522E722D00E6D3 ...k.)j..R.r-... ..y,..|.......WL [jcc][t4] 05A0 B6095BA5008A5648 0E00B355513CA9B1 ..[...VH...UQ<.. ..$v..........z. [jcc][t4] 05B0 0038AF017D83BD00 E7205AA9004F0075 .8..}.... Z..O.u ....'c..X.!z.|.. [jcc][t4] 05C0 39C97800EECF240F 00CCA92FD10061AD 9.x...$..../..a. .I........z.J./. [jcc][t4] 05D0 FF6E003F12D33F00 9089C5460001B543 .n.?..?....F...C .>...L...iE..... [jcc][t4] 05E0 79008F832FD3000C 15FD2D008326E45D y.../.....-..&.] `..c.L......c.U) [jcc][t4] 05F0 00C42D4EDA00F87E FA4200EECA4CC90 ..-N...~.B...L.. .D.+..8=.....<A. [jcc][t4] 0600 4DCD1BE57D461B21 64CFFF0030303830 M...}F.!d...0080 (..V'........... [jcc][t4] 0610 3135333535343334 0030393639003230 15355434.0969.20 ................ [jcc][t4] 0620 31373034000C0000 0000323031373039 1704......201709 ................ [jcc][t4] 0630 0032303137313000 1400000000330000 .201710......3.. ................ [jcc][t4] 0640 0000000000000000 0000000000000000 ................ ................ [jcc][t4] 0650 0000000000000000 0A000000000A0000 ................ ................ [jcc][t4] 0660 0000000000000000 0000000000000000 ................ ................ [jcc][t4] 0670 0000000000000000 0000001400000000 ................ ................ [jcc][t4] 0680 3034393138303431 2020FF0030303830 04918041 ..0080 ................ |
ステップ 3 で確認した SQL ステートメントもしくはステップ 5 で確認した ResultSet カラムのメタ情報より、問題のデーターは表 MYTAB1 の列 C1 と分かりました。
そこで、問題のデーターを含むレコード全体を確認するには、次の SQL を実行します。必要に応じて、フィールド・セパレーター 00 で区切られた他の値も用いて検索してください。
SELECT * FROM MYTAB1 where C1=x'29226C1E1DA86BAF296AB8'
Additional Information
DB2 V10.5 Fix Pack 7 より古いレベルの JDBC ドライバーをご利用の場合は、次の技術文書を確認の上、必要な措置を取るようにしてください。
Related Information
Was this topic helpful?
Document Information
Modified date:
29 November 2022
UID
ibm10744699