DOBON.NET DOBON.NETプログラミング掲示板過去ログ

ORACLEへのADO接続がうまく行きません

環境/言語:[OS : Windows 7 / 言語 : Visual Basic .NET / .NET Framework : 3.5]
分類:[.NET]

【解決したい問題】

初めて投稿させていただきます。

VB.net にて簡単なORACLEへの接続方法が確立できず、困っています。

まず状況としては、プロバイダ:OraOLEDB.Oracle を使った
接続にはひとまず成功しています。ですが、詳しい方ならご存知のように、
OraOLEDB.Oracleによる接続(ADO)は、オラクルクライント(管理者用)をインスト
ールすることで初めて成り立ちます。
 ですので、このやり方ではアプリケーションを作成して一般ユーザーに配布す
るには不向きです。ゴールとしては、クライアントの環境に全く依存しないオラ
クルのADO接続を持ったアプリケーションを作成することです。

この点がまず一つです。
 次に不可解な点として、なぜ参考書やHPに出ているOracleへの接続文は全て、

cn.ConnectionString = "Provider=OraOLEDB.Oracle;" & _
"Data Source=TESTDB;" & _
"User ID=USER002;" & _
"Password=pass;"

というようになっているのか、という点について知りたいです。
このような記述のうち、Data Sourse=*** の部分は、明らかに
システムDSNにおいて、データソースの登録が事前にクライアントPC
に対してなされていることを前提としているはずです。
 なぜ、ORACLEの場合はSQLServerのように、ServerNameとDataBaseを指定して
、(つまりシステムDSNの設定と全く無関係に)接続を確立するような方法になって
いないのか?という点が不可解です。
 この点についてもご教授頂けたら幸いです。

以上の2点についてクリアになれば、この問題の解決の糸口が見えるのではと思います。

あるいは、全く別のアプローチで、「こうすればつながるようになる」という方法があればそれをご教授頂けると幸いです。



最後に、現状の環境について付記しておきます。
ORACLEに関する端末の設定は以下の通り:
 @ODTwithODAC 11gをインストール(ごく標準的な内容)
 A環境変数をORACLE用に設定
 BC:\oracleフォルダを作り、その中に必要なファイルを保存
 Cデータソース(ODBC)のシステムDSNで、接続したいDBのデータ
 ソースを作成。

この4つを全て行った上で、初めて、上記のような接続文での
接続が可能になったようです。(ちなみにProvider:=〜の部分は
OraOLEDB.Oracleでも、MSDAORAでも両方とも行けるようです。

勉強不足な点も多々あるかと思いますが、宜しくお願いいたします。
2012/07/02(Mon) 21:31:24 編集(投稿者)

■No30671に返信(kane123さんの記事)
> まず状況としては、プロバイダ:OraOLEDB.Oracle を使った
> 接続にはひとまず成功しています。

VB.NET からの ADO 接続は推奨されていません。
ADO.NET(ODP.NET) を利用されることをお奨めします。
http://docs.oracle.com/cd/E16635_01/win.111/e06104/InstallODP.htm

Instant Client であれば、ユーザー側のセットアップ作業も減らせるかと。
http://www.oracle.com/technetwork/jp/database/features/instant-client/index-352321-ja.html
http://hatsune.wankuma.com/Oracle/oic/install.html


> OraOLEDB.Oracleによる接続(ADO)は、オラクルクライント(管理者用)をインスト
> ールすることで初めて成り立ちます。
(ODP.NET ではなく)従来の OLE DB Provider や oo4o を使うにしても、
必ずしも管理者用の Oracle Client を入れる必要は無いと思いますよ。

かといってランタイムのみでは不十分なので、カスタムインストールは必要ですが。
それが面倒なので、管理者用を入れてしまう選択肢もありますが、
複数の環境にインストールする場合には、レスポンス・ファイルを利用して
非対話型のインストールとすることもできます。
http://otndnld.oracle.co.jp/document/products/oracle11g/111/windows/E05879-05/advance.htm


>  次に不可解な点として、なぜ参考書やHPに出ているOracleへの接続文は全て、
全て?

>  なぜ、ORACLEの場合はSQLServerのように、
接続のためにクライアントライブラリを必要とする点は、SQL Server も同様かと。
http://msdn.microsoft.com/ja-jp/library/ms190944(SQL.105).aspx


> (つまりシステムDSNの設定と全く無関係に)
システムDSN は、ODBC 接続の場合の話では無いでしょうか。
OraOLEDB.Oracle や MSDAORA ではシステムDSNは使いませんし、
仮に ODBC 接続であっても、『DSNレス接続』を使う事で対処可能かと思います。

DSN というのが tnsnames.ora での事前設定の事を指しているのだとすれば、
Oracle 10g 以降の『簡易接続ネーミング』を使う事で、tnsnames.ora での
設定作業を省くことができます。
> VB.NET からの ADO 接続は推奨されていません。
> ADO.NET(ODP.NET) を利用されることをお奨めします。

失礼しました。ADO.NETを意味したつもりでした。次からADO.NETと
明記します。


ご指摘いただいたことを総合すると、どうも私が、いくつかの前提を
勘違いしてしまっているかも知れません。どの時点で間違っているか
ご指摘いただけると非常に幸いです。
私のひとまずの理解は以下の通りです。

まず、MSDAORAで接続する際は通例、接続文字列には、Server:= , Database:=
が無く、DataSource:= のみとなっている。この点がSqlServerと異なる。

→したがって、ORACLEのADO.NET接続では、ソースコード内の記述だけで
接続は確立できるものではなく、クライアントPCに何らかの形で、DataSourceが
定義されている必要がある。(DataSource:=〜の部分にはその定義が来るため)

→その定義は何によってなされるのかと言えば、自分の記憶を辿れば、自分が行っ
たのはODBC接続のみなので、ODBCでのDSN設定がそれにあたると考えた。(そこで
Server名やDB名の登録を行っているため。)      (この辺が間違っているの
でしょうか?)

仮面弁士さんのおっしゃるように、MSDAORA はシステムDSNは使わないというの
であれば、どのようにしてADO.NETはServer名やDB名を認識するのでしょうか?
ODBCの設定をせずとも、それらが認識されて接続が確立するのは何を前提として、
なのでしょうか?

この辺がクリアになればと思います。私の話の中に推測も混ざっていると思うの
で、不勉強を怒られそうですが、どうしても参考HPの情報をかき集めても
ここまでしか問題を整理できません。また、教えて頂いたHPもこれから熟読して、
色々と試してみたいと思います。
<先ほどの返信に追記です>
odbc接続は確かに行わなくても、C:\oracle:tnsname.ora 内の
データソースの記述があるか無いかでデータソースは認識される/されない
が決まるようです。(比較・検証をしたところそうなりました。)

odbcは切り離して考えて行こうと思います。
(C:\oracle:tnsname.ora 内の記述は、最初のODBC設定ダイアログを
行った際にウラで自動的に書き込まれていたようです。
このため、ODBC接続が必須なのかと、勘違いした認識を
してしまっていました。申し訳無いです。
頂いたHPの中から下記を見つけ、
http://docs.oracle.com/cd/E16338_01/win.112/b62267/featConnecting.htm
データソースの定義を接続文字列内にハードコーディングする方法が
書かれているので、これを適用したら、接続に成功しました。
(tnsnames.ora や ODBC設定無しでの接続。)


"user id=scott;password=tiger;data source=" +
"(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)" +
"(HOST=sales-server)(PORT=1521))(CONNECT_DATA="+
"(SERVICE_NAME=sales.us.acme.com)))"

色々とご教授頂き、ありがとうございました。 
ただし、クライアント側の設定で、Instantclientのインストール
がどうしてもうまくいかず、壁に当たっています。

しかし、仮面弁士さんの回答で、望んでいたこと
@接続文字列の指定を.netのソース内で完結させること
A不必要な設定をせずにすませること(odbc)
は達成できました。

ありがとうございました。

ここから先のInstantclientのインストールは別問題として
切り離して、対処していこうと思います。

(他のサイトでInstantclientインストール失敗について
質問するかも知れません。ご了承を。)
■No30681に返信(kane123さんの記事)
■No30679に返信(kane123さんの記事)
> 次からADO.NETと明記します。

Oracle に接続可能な ADO.NET の DB 接続クラスとしては、
下記のクラスがあります(他にもあると思います)。

(1) System.Data.Odbc.OdbcConnection
(2) Microsoft.Data.Odbc.OdbcConnection
(3) System.Data.OleDb.OleDbConnection
(4) System.Data.OracleClient.OracleConnection
(5) Oracle.DataAccess.Client.OracleConnection
(6) DDTek.Oracle.OracleConnection
(7) Devart.Data.Oracle.OracleConnection


5 は Oracle 製、6 は DataDirect 製、7 は Devart 製、それ以外は Microsoft 製です。
1,2,3 は、別のミドルウェアを経由しての接続となるため、それ以外の方が望ましいかと。

1: .NET 2.0以降。別途、ODBC ドライバーが必要です。
2: .NET 1.x用。別途、ODBC ドライバーが必要です。
3: 別途、OLE DB Provider が必要です。
4: .NET 4 から非推奨となりました。廃止予定です。
5: Oracle 社製。「ODP.NET」
6: サードパーティ製品。「Connect for ADO.NET」
7: サードパーティ製品。「Devart dotConnect for Oracle」(旧名:OraDirect.NET)


1 や 2 の場合は、別途 ODBC ドライバーが必要です。たとえば下記など。

(a) Microsoft ODBC for Oracle
(b) Oracle ODBC Driver
(c) DataDirect Connect for ODBC (Oracle 用)


3 の場合は、別途 OLE DB Provider が必要です。たとえば下記など。

(A) MSDAORA
(B) OraOLEDB.Oracle
(C) DataDirect.Oracle*ADOProvider

※ OleDbConnection から MSDASQL (ODBC 用 OLE DB Provider)を使う事はできません。



> 失礼しました。ADO.NETを意味したつもりでした。

"OraOLEDB.Oracle を使った ADO 接続" と言えば、多くの場合 ADODB を指すことになります。
ADO.NET と ADO とでは名前こそ似ていますが、両者は別物ですのでご注意ください。


『ADO.NET』は、System.Data 名前空間のものを指しており、特に ADO.NET 2.0 では、
System.Data.Common 名前空間の抽象クラスを継承することになっています。

Oracle 社製の「ODP.NET」の場合、クラス自体は Oracle.DataAccesss 名前空間にありますが、
Oracle.DataAccess.Client.OracleConnection クラスも、
System.Data.Common.DbConnection 抽象クラスを継承していますし、ADO.NET 1.0 版でも
System.Data.IDbConnection インターフェイスを実装しています。


一方、『ADO (ActiveX Data Object)』の方は、ActiveX (COM) 系のテクノロジであり、
.NET 的には、主に ADODB 名前空間の事を指します(ADOX などを含む場合もあります)。

ADO からの接続は、「OLE DB Provider」を経由してのアクセスとなります。
具体的には、MSDAORA や OraOLEDB.Oracle などですね。

ちなみに、ADO.NET の System.Data.OleDb.OleDbDataAdapter.Fill メソッドは、
引数に ADO の ADODB.Recordset オブジェクトを受け取れるよう設計されており、
これを用いて、ADO.NET と ADO の橋渡しをすることもできるようになっています。



> まず、MSDAORAで接続する際は通例、接続文字列には、Server:= , Database:=
> が無く、DataSource:= のみとなっている。この点がSqlServerと異なる。

極端な話、Oracle では Data Source すら省略されることもありますが、
各種パラメータを省略すると、既定の設定が使われたとみなされるだけのことです。

SQL Server でも、Data Source の指定だけで接続することはできます。

もちろん、SQL Server と Oracle での管理形態の違いもありますので、
必要なパラメータ数や設定はそれぞれ異なりますけれども。



また、SQL Server への接続を、「ADO」や「ADO.NET の OleDbConnection」経由で行う場合は、
 "Provider=SQLOLEDB;Data Source=server;User ID=user;Password=pwd;Initial Catalog=dbName"
 "Provider=SQLNCLI;Data Source=server\instance;Initial Catalog=dbName"
 "Provider=SQLNCLI10;Data Source=server\instance;Initial Catalog=dbName"
 "Provider=SQLNCLI11;Data Source=(local);Database=db;Integrated Security=SSPI"
などの接続文字列となります(他にも幾つかのパラメータがありますが)。
しかし「ADO.NET の SqlConnection」経由での接続であれば、Provider= の指定はありません。

Oracle も同様で、「ADO」や「ADO.NET の OleDbConnection」経由で行う場合は、
Provider= の指定が必要ですが、「ADO.NET の OracleConnection」経由では不要です。


> →したがって、ORACLEのADO.NET接続では、ソースコード内の記述だけで
> 接続は確立できるものではなく、クライアントPCに何らかの形で、DataSourceが
> 定義されている必要がある。(DataSource:=〜の部分にはその定義が来るため)
Oracle の場合、Oracle Client をインストールしたフォルダ(ORACLE_HOME)に、
「NETWORK\ADMIN\tnsnames.ora」ファイルがあり、ここで接続先を定義できます。

ですが前回の回答にも書きましたように、最近のバージョンでは
tnsnames.ora での設定が無くても接続できます。


Dim c As New Oracle.DataAccess.Client.OracleConnection( _
    "User ID=scott;Password=tiger;Data Source=192.0.2.1:1521/ORCL")
c.Open()


Dim c As New System.Data.OracleClient.OracleConnection( _
    "User ID=scott;Password=tiger;" _
    & "Data Source=(DESCRIPTION=(ADDRESS_LIST=" _
    & "(ADDRESS=(PROTOCOL=TCP)(HOST=192.0.2.1)(PORT=1521))" _
    & ")(CONNECT_DATA=(SERVICE_NAME=ORCL)))")
c.Open()
解決後もいろいろと補足・説明頂き、恐縮です。
永久保存させていただきます。
ありがとうございました!
本日まで「解決済み」の方法が分からず、し忘れていました。
遅ればせですが、「解決済み」にさせて頂きます。

すみませんでした。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板