OracleへのODBC接続で「ORA-01406」エラーが発生した時に行なった対応

2020.04.22

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは。DA事業本部 インテグレーション部のおおたきです。

オラクルにODBC接続してデータを取得しようとした際に「ORA-01406」というエラーが発生し、データが取得できない現象が発生した際に行なった対応方法について備忘録として記載しておきます。

エラーが発生した原因

オラクルの文字コードはShift_JISが採用されてました。データを取得する側はUTF-8を使用していたため環境変数に「NLS_LANG」で文字コードをUTF-8に変更しました。この変更が原因で特定のテーブルに対してSELECT文でデータを取得しようとするとエラーが発生するようになってしまいました。

エラーが発生する特定のテーブルというのは文字列型が含まれているテーブルである程度以上の文字データが登録されているテーブルでした。(日本語が登録されているからエラーが発生する訳ではありませんでした)

解決方法

まずこのエラーを調べてみるとオラクルのページでは原因は以下のように記載されてます。

エラーコード: ORA-01406 詳細: フェッチされた列の値は切り捨てられました 原因: フェッチされた列の値が切り捨てられました。 アクション: 適切なデータ型を使用して切捨てを回避してください。

この情報だけだとちょっと対応方法がわかりませんででしたが、バッファサイズが小さくして切り捨てられてしまったのかと思い、ODBCドライバの「Oracle」タブにあるフェッチバッファサイズを大きくしてみました。

フェッチバッファサイズはドキュメントに以下のように説明があります。

単一の問合せでアプリケーション・プログラムがリクエストする行数に関係なく、ODBCドライバがOracle Databaseから一度にプリフェッチするデータの行数を決定するために使用されるメモリー量。ただし、プリフェッチされる行数は、単一の問合せで指定された列の幅と数に依存します。通常一度に20行未満をフェッチするアプリケーションでは、低速なネットワーク接続上で動作する場合や非常に負荷の高いサーバーにアクセスする場合には特に、レスポンス時間が向上します。フェッチ・バッファ・サイズを大きく設定しすぎると、レスポンス時間が悪化したり、メモリーを大量に消費することがあります。

結果としては変わらずエラーでした。

他にODBCドライバの設定を確認していたところ、「SQL_WCHAR強制サポート」という設定項目がありこのオプションの設定をしてみました。

SQL_WCHAR強制サポートドキュメントに以下のように説明があります。

この機能により、これらのODBCコールの結果に依存するアプリケーション(たとえば、ADOアプリケーション)でのUnicodeのサポートが可能になります。デフォルトでは、このサポートは無効になっています。

この設定をしたところ無事エラーが解消されました。

最後に

当初、本設定に気が付く前は環境変数の文字コードにUTF8を設定しないで、SQLのCONVERT関数を使って文字化けしないように考えていました。これでも同様に解決はできましたが、SELECTで取得する項目1つ1つに関数を設定しないといけなくなるため、ODBCの設定で解決できよかったです。

もし同じエラーが悩まされている方がいたら参考にしていただけたら幸いです。