C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Oracle接続方法

[トピック内 12 記事 (1 - 12 表示)]  << 0 >>

■90715 / inTopicNo.1)  Oracle接続方法
  
□投稿者/ kiku (75回)-(2019/04/11(Thu) 19:45:07)

分類:[.NET 全般] 

アプリの種類:WinFormアプリ
言語:C#
OS:Win10 64bit
バージョン:.NETFramework4.7
Oracleバージョン:11gR2

現在、Oracle.ManagedDataAccessライブラリを利用して
アプリを作り、DBにアクセスしているのですが、
不具合が出て困っています。

不具合の内容ですが、あるテーブルをselectしているだけなのですが、
例えばAAAAAAAを期待しているのにAAAのように文字列が途中で切れる現象が
発生しています。

同じDBに対して、TOMCATのJavaサービスからは、文字列が切れずに
問題なく動作しています。

DBとOracle.ManagedDataAccessの組み合わせの場合のみ
本現象が発生しています。

DBは本番環境でのみ発生し、開発環境では発生していません。
どうやら本番環境のDBは、いくつものDBがDBリンクされている状況のようで
その本番環境と同じ開発環境を作りたいと思っているのですが、
事情によりできない状況です。

Oracle.ManagedDataAccessを利用しない方法で
DBにアクセスし、テストしてみたいと考えました。
いろいろ検索しているのですが、
最新の環境でどんなライブラリや接続方法が
利用できるのかお教えて頂けないでしょうか?

アドバイス頂けますと助かります。
引用返信 編集キー/
■90716 / inTopicNo.2)  Re[1]: Oracle接続方法
□投稿者/ 魔界の仮面弁士 (2143回)-(2019/04/11(Thu) 22:42:18)
No90715 (kiku さん) に返信
> どうやら本番環境のDBは、いくつものDBがDBリンクされている状況のようで
> その本番環境と同じ開発環境を作りたいと思っているのですが、
> 事情によりできない状況です。

グローバリゼーションもしくは、Oracle Client バージョンの問題ということはないでしょうか。
https://docs.oracle.com/cd/E57425_01/121/ODPNT/featGlobal.htm

検索結果に半角カナが含まれる場合に、文字欠損が発生するパターンを見たことはありますが、
再現するためには、Oracle PSR の組み合わせなどいろいろと条件が複雑なこともありますので、
個人的には、My Oracle Support に相談するべきかと思います。
https://www.oracle.com/jp/support/software/premier/my-oracle-support-068523-ja.html
引用返信 編集キー/
■90718 / inTopicNo.3)  Re[2]: Oracle接続方法
□投稿者/ kiku (76回)-(2019/04/12(Fri) 09:03:00)

> 検索結果に半角カナが含まれる場合に、文字欠損が発生するパターンを見たことはありますが、
> 再現するためには、Oracle PSR の組み合わせなどいろいろと条件が複雑なこともありますので、
> 個人的には、My Oracle Support に相談するべきかと思います。
> https://www.oracle.com/jp/support/software/premier/my-oracle-support-068523-ja.html

まさしくその通りで、
半角カナが含まれていると、文字列が切れます。
ただし、半角カナの部分でちょうど切れるわけではなく、
それが起因しているかもあやふやな状況です。

半角カナとグローバリぜージョンは関係性がありますでしょうか?
引用返信 編集キー/
■90719 / inTopicNo.4)  Re[3]: Oracle接続方法
□投稿者/ 魔界の仮面弁士 (2145回)-(2019/04/12(Fri) 09:37:49)
2019/04/12(Fri) 09:54:52 編集(投稿者)

No90718 (kiku さん) に返信
> 半角カナが含まれていると、文字列が切れます。

しかし最初の質問では、'AAAAAAA' → 'AAA' と説明されていたように見えます。


いずれにせよ欠損障害は重篤な問題ですし、それが Managed ODP.NET 接続時に
発生している内容なのであれば、Oracle サポート契約の範囲で対応すべき案件かと思います。

KROWN を「半角カナ」で検索すると、個別 Patch の適用で欠損が解消されたケースもあるそうですし。
(ODP.NET に起因するかどうかは別として)


もう一つの可能性としては、該当の文字列中に、C# でいうところの
Char.MinValue が混入していた…とかでしょうか。

処理系によっては、NULL 文字以降のデータが欠損してしまうことも
ありそうなので、再現性のある障害である場合には、
SELECT DUMP(該当フィールド, 1016) FROM 〜 を用いて、その場所に
想定外の文字が含まれていないか、確認しておいた方が良いかもしれません。



> ただし、半角カナの部分でちょうど切れるわけではなく、
> それが起因しているかもあやふやな状況です。

そちらの事象と関連するものであるかどうかは定かではありませんが、以下参考までに。

自分が経験した障害は、ざっくり言うと、半角カナが多く含まれている文字列の際に、
バッファ長が不足することで、文字列の後半部分が欠落(または ORA-24345)になるという事象でした。

殆どのレコードは欠落せずに受信できていたのですが、欠落するレコードが
常に同じであったことから、ベンダーのサポートに調査依頼を出して対応しました。
(.NET での自社アプリ開発時ではなく、SQL を処理する他社製ソフトウェアでの事象)

その時に受けた報告内容によれば、Shift_JIS (Oracle なら JA16SJISTILDE) と
UTF-8 (Oracle なら AL32UTF8) の変換処理に関連する文字列バッファの問題であり、
半角カナが前者では 1 バイト、後者では 3 バイトとなることが
十分に考慮されていなかった……というのが大まかな原因だったそうです。

この場合は Oracle 側の問題ではなく、そのソフト側(VC++製)に要因があったことが
判明したため、制作元に連絡して改修してもらったという経緯があります。

なお、当方の事象は DBLINK とは関係なく、それこそ単純な
 SELECT '固定の文字列' FROM DUAL
という SQL の問い合わせでも、常に再現する状況となっています。

ちなみにその時、'固定の文字列' 部分にあった内容は、
 半角英大文字×2
 半角カナ×14(内、濁点×2、半濁点×1)
 漢字×5
 半角カナ×6(内、濁点×2)
 漢字×4
というものでした。

具体的なサンプルデータを明かすことはできないのですが、
上記の漢字部を数文字削るだけで再現しないこともあったので、
文字種の組み合わせにも左右される可能性がありそうです。
引用返信 編集キー/
■90720 / inTopicNo.5)  Re[4]: Oracle接続方法
□投稿者/ kiku (77回)-(2019/04/12(Fri) 09:54:01)
> その時に受けた報告内容によれば、Shift_JIS (Oracle なら JA16SJISTILDE) と
> UTF-8 (Oracle なら AL32UTF8) の変換処理に関連する文字列バッファの問題であり、
> 半角カナが前者では 1 バイト、後者では 3 バイトとなることが
> 十分に考慮されていなかった……というのが大まかな原因だったそうです。

貴重な情報ありがとうございます。感謝しかないです。
おそらく上記事象ではないかと思います。

Oracleサポートにユーザが入っているか確認してみます。
※入ってないような気がしますが。。。。。;;

>グローバリゼーションもしくは、Oracle Client バージョンの問題ということはないでしょうか。
>https://docs.oracle.com/cd/E57425_01/121/ODPNT/featGlobal.htm

こちらの現在設定を取得しようと思ったのですが、
Oracle.ManagedDataAccess.Clientではメソッドがなく実装できませんでした。
Oracle.ManagedDataAccess.Clientで取得する方法はあるのでしょうか?

質問ばかりですみません。
引用返信 編集キー/
■90724 / inTopicNo.6)  Re[5]: Oracle接続方法
□投稿者/ 魔界の仮面弁士 (2146回)-(2019/04/12(Fri) 10:47:32)
No90720 (kiku さん) に返信
> Oracleサポートにユーザが入っているか確認してみます。
> ※入ってないような気がしますが。。。。。;;

おぉぅ…(;;)

Managed ODP.NET は、12c 以降でリリースされたものであり、11gR2 向けの物は無いはずですが、
両者の組み合わせはサポートされているはずなのですよね。(11gR1 と 12cR2 の組み合わせは NG)


>> https://docs.oracle.com/cd/E57425_01/121/ODPNT/featGlobal.htm
> こちらの現在設定を取得しようと思ったのですが、
> Oracle.ManagedDataAccess.Clientではメソッドがなく実装できませんでした。
> Oracle.ManagedDataAccess.Clientで取得する方法はあるのでしょうか?

昨晩は確認していませんでしたが、
OracleGlobalization クラスの GetClientInfo メソッドが使えるのは、
Oracle.DataAccess.Client 名前空間のものだけで、
Oracle.ManagedDataAccess.Client 名前空間のものには
含まれていないですね…。済みません。

代わりに、SELECT * FROM V$NLS_PARAMETERS で確認してみてください。
設定変更は、OracleConnection.SetSessionInfo もしくは "ALTER SESSION SET 〜" です。

ClientGlob.Language プロパティ に相当するのが NLS_LANGUAGE で
ClientGlob.ClientCharacterSet は NLS_CHARACTERSET だと思いますが、
Language / NLS_LANGUAGE は読み書き可能、
ClientCharacterSet / NLS_CHARACTERSET は読取専用です。



もしも、特定のレコードで再現することが判明しているのであれば、
とりあえず InstantClient でも良いので ( http://apis.jpn.ph/fswiki/wiki.cgi?page=Oracle%2FInstantClient )
問題箇所の切り分けのため、実験的なコンソール アプリケーションを作るなどして、
 Managed な ODP.NET (事象の再現確認用)
とは別に、
 Unmanaged の方の ODP.NET
 .NET Core 向けの ODP.NET
 Microsoft の Obsolte な OracleClient
などの検証アプリを別途用意し、同じ障害が再現するかを確認してみては如何でしょう。
引用返信 編集キー/
■90727 / inTopicNo.7)  Re[6]: Oracle接続方法
□投稿者/ kiku (78回)-(2019/04/12(Fri) 11:38:45)

> Managed ODP.NET は、12c 以降でリリースされたものであり、11gR2 向けの物は無いはずですが、
> 両者の組み合わせはサポートされているはずなのですよね。(11gR1 と 12cR2 の組み合わせは NG)

えーーーー。
Managed ODP.NETと11gR2との組み合わせの利用はサポートされていないのですね。
無知ですみません。
きちんとサポート対象のライブラリや接続方法に切り替えたいです。

> 代わりに、SELECT * FROM V$NLS_PARAMETERS で確認してみてください。
> 設定変更は、OracleConnection.SetSessionInfo もしくは "ALTER SESSION SET 〜" です。

ありがとうございます。
試してみます。

> もしも、特定のレコードで再現することが判明しているのであれば、

再現するレコードは特定されているため、
テストアプリを何回かリリースさせて頂いて、
お客様環境で試してもらっています。

> とりあえず InstantClient でも良いので ( http://apis.jpn.ph/fswiki/wiki.cgi?page=Oracle%2FInstantClient )
> 問題箇所の切り分けのため、実験的なコンソール アプリケーションを作るなどして、
>  Managed な ODP.NET (事象の再現確認用)
> とは別に、
>  Unmanaged の方の ODP.NET
>  .NET Core 向けの ODP.NET
>  Microsoft の Obsolte な OracleClient
> などの検証アプリを別途用意し、同じ障害が再現するかを確認してみては如何でしょう。

SQLPLUSで同じPCからアクセスした場合、文字が切れないことを確認しています。

Unmanaged の方の ODP.NETでテストアプリを作りたいのですが、
検索すると、Managedの方の情報ばかりがヒットし、
Unmanagedの方の情報に行きついていない状況です。
申し訳ありませんが、参考になりそうなサイトがご存知でしたらお教えて頂きたいです。


引用返信 編集キー/
■90730 / inTopicNo.8)  Re[7]: Oracle接続方法
□投稿者/ 魔界の仮面弁士 (2149回)-(2019/04/12(Fri) 13:20:18)
2019/04/12(Fri) 13:34:19 編集(投稿者)

No90727 (kiku さん) に返信
>>Managed ODP.NET は、12c 以降でリリースされたものであり、11gR2 向けの物は無いはずですが、
>>両者の組み合わせはサポートされているはずなのですよね。(11gR1 と 12cR2 の組み合わせは NG)
> Managed ODP.NETと11gR2との組み合わせの利用はサポートされていないのですね。

いや。Managed 版が提供されたのが 12c からである、ということです。

11.1.0 以下のサーバーへの接続はサポートされていませんが、
11.2.0、12.1.0、12.2.0、18.0.0 への接続は OK のはず。

導入の手間を考えると、基本的には Managed ODP.NET 一択なんですが、
今回は検証のための一時的なものということで。



> 再現するレコードは特定されているため、
DUMP( , 1016) の内容は、特に問題なさそうなのですよね。


> Unmanaged の方の ODP.NETでテストアプリを作りたいのですが、
先の回答のように、名前空間こそ Oracle.DataAccess.Client に変わりはしますが、
クラス名やメソッドは基本的に同じなので、ほぼ同じコードで動きます。
(GetClientInfo メソッドのように、幾つかの差はありますが)


ただし Unamatged 版の方は、Oracle Client をインストールしておく必要があります。
インストールしたくない場合は InstantClient を配置する形でも構いませんが、
いずれにせよ、ODP.NET のバージョンと適合するバージョンの Oracle Client をご用意ください。
https://www.oracle.com/technetwork/jp/indexes/downloads/index.html
引用返信 編集キー/
■90731 / inTopicNo.9)  Re[8]: Oracle接続方法
□投稿者/ kiku (79回)-(2019/04/12(Fri) 15:54:13)
> いや。Managed 版が提供されたのが 12c からである、ということです。
> 11.1.0 以下のサーバーへの接続はサポートされていませんが、
> 11.2.0、12.1.0、12.2.0、18.0.0 への接続は OK のはず。

そうなのですね。
ではサポート内ということで安心しました。

>>再現するレコードは特定されているため、
> DUMP( , 1016) の内容は、特に問題なさそうなのですよね。

こちらは、それを実行するテストアプリを
お客様へ提供し、現在待ち状態。
来週になるかもです。

>>Unmanaged の方の ODP.NETでテストアプリを作りたいのですが、
> 先の回答のように、名前空間こそ Oracle.DataAccess.Client に変わりはしますが、
> クラス名やメソッドは基本的に同じなので、ほぼ同じコードで動きます。
> (GetClientInfo メソッドのように、幾つかの差はありますが)
> ただし Unamatged 版の方は、Oracle Client をインストールしておく必要があります。
> インストールしたくない場合は InstantClient を配置する形でも構いませんが、
> いずれにせよ、ODP.NET のバージョンと適合するバージョンの Oracle Client をご用意ください。
> https://www.oracle.com/technetwork/jp/indexes/downloads/index.html

アドバイスありがとうございます。
まずは開発環境のDBに対して、Oracle.DataAccess.Clientを
用いた方法でテストアプリを作ってみます。

引用返信 編集キー/
■90740 / inTopicNo.10)  Re[9]: Oracle接続方法
□投稿者/ kiku (80回)-(2019/04/15(Mon) 13:07:55)
> >>再現するレコードは特定されているため、
>>DUMP( , 1016) の内容は、特に問題なさそうなのですよね。
>
> こちらは、それを実行するテストアプリを
> お客様へ提供し、現在待ち状態。
> 来週になるかもです。

その後、DUMPの結果の返答があり、
下記の状況でした。
他にも文字列が切れるパターンはあるようですが、
現在、半角カナのメがあるところから文字が切れる状況です。
 Typ=96
 CharacterSet=JA16SJISTILDE
 バイナリ:d2
 SJIS:メ(半角カナ)

現在、取得したバイナリデータを
開発環境にインサートすることによって、
文字列が切れる現象の再現に成功しました。

Oracle.ManagedDataAccess.Clientの名前空間を
利用して、明示的に文字コードを指定できないか現在実験しています。

OracleConnection.GetSessionInfo()で取得したインスタンスの
Language = "JAPANESE"
をうまく設定変更して、
OracleConnection.SetSessionInfo()
試していますがLanguageプロパティでは、文字コードは設定できないようです。

現在、他に設定できるところがないか探している状況ですが、
まだ探せていません。
もし、知見がありましたらアドバイス頂けないでしょうか?

引用返信 編集キー/
■90741 / inTopicNo.11)  Re[10]: Oracle接続方法
□投稿者/ 魔界の仮面弁士 (2150回)-(2019/04/15(Mon) 14:52:27)
No90740 (kiku さん) に返信
> 現在、取得したバイナリデータを
> 開発環境にインサートすることによって、
> 文字列が切れる現象の再現に成功しました。

少し前進しましたね。


> OracleConnection.GetSessionInfo()で取得したインスタンスの
> Language = "JAPANESE"

Language は、レジストリ設定(あるいは環境変数)の NLS_LANG を設定するものです。
既定の日付書式やエラーメッセージの表示言語に影響を与えるだけで、
今回の事象にはあまり関係しないのでは、と予想しています。


気にするべきは NLS_CHARACTER_SET の方かと思います。
実行時に動的に変更できるものではないので、レジストリまたは環境変数で調整する必要があるかもしれませんが。
https://stackoverflow.com/questions/24307580/set-nls-lang-for-oracle-managed-data-access

サーバー側のキャラクタセットとクライアント側のキャラクタセットが不一致の場合、
追加の変換処理が入るため、そこで問題が生じる可能性があるようです。



>  Typ=96
>  CharacterSet=JA16SJISTILDE
>  バイナリ:d2
>  SJIS:メ(半角カナ)

Typ=96 ということは、VARCHAR2/NVARCHAR2 ではなく CHAR/NCHAR ですね。


(1) VARCHAR2 / NVARCHAR2 項目で同じ現象が起きるか試してみてください。

(2) Managed ODP.NET のバージョンを変えて試してみてください。(VerUp / VerDown)
 なお、現在の最新版は 18.6.0 だと思います。

(3) パラメータクエリを用いている場合、DbType に指定される
 System.Data.DbType に注意してください。文字列パラメータの場合、
  VARCHAR2 → AnsiString
  CHAR → AnsiStringFixedLength
  NVARCHAR2 → String
  NCHAR → StringFixedLength
 のようにマッピングされています。
 ※ OracleDbType の方も確認を。
引用返信 編集キー/
■90745 / inTopicNo.12)  Re[11]: Oracle接続方法
□投稿者/ kiku (81回)-(2019/04/16(Tue) 11:31:43)
>> Typ=96
>> CharacterSet=JA16SJISTILDE
>> バイナリ:d2
>> SJIS:メ(半角カナ)
> Typ=96 ということは、VARCHAR2/NVARCHAR2 ではなく CHAR/NCHAR ですね。
> (1) VARCHAR2 / NVARCHAR2 項目で同じ現象が起きるか試してみてください。

対象項目はCHAR型でした。
また、同項目のバイナリはSJISで来ていることがわかりました。
このことから、アプリからのSQL文にて、CHAR型をNCHAR型に変換して取得したら
どうだろうと実験したところ、改善することを確認しました。
ライブラリ側の設定は結局のところ、設定変更をしていないです。

また、本番環境でもテストアプリにて確認したところ、
改善していることを確認できたため、この改修方法で大丈夫そうです。

いろいろとアドバイス頂きありがとうございました。
大変助かりました。
解決済み
引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ