SQL Serverへの接続処理について

タグの編集
投稿者 acwg  (社会人) 投稿日時 2012/6/8 18:50:20
お世話になります。

開発言語 : VB2010 Pro
DB : SQL Server 2008 R2 Express 
DBが入ってるサーバー : 別PCのWIndows2003サーバー
実行環境 : WindowsXP

上記環境で開発したVB2010のプログラムをVisual Staduo2010のセットアッププロジェクトにて
セットアップEXEを作成し、他の実行環境となるPCにインストールをしたのですが、ADO.NETにて
接続する処理にて、エラーメッセージ

System.InvalidOperationException 'SQLNCLI10.1Persist Security Info=False' プロバイダーはローカルのコンピュータに登録されていません。

と表示されて、例外処理に飛んでしまいます。
開発環境では、問題なく接続されるのですが、実際の実行PCにセットアップすると、この事象になってしまいます。

ちなみにエラーが出てる接続処理のソースは、下記です。

------------ ソース ------------------------------------------
Public Const CONNECTION_STRING As String = "Provider=SQLNCLI10.1Persist Security Info=False;User ID=sa;Password=allsys;Initial Catalog=;Data Source=;"

        'ADO.NET用コネクション接続(For SQL Server)
        Try
            With gado_cn
                .ConnectionString = CONNECTION_STRING
                Call .Open()
            End With
        Catch ex As Exception
            Call MsgBox(ex.ToString())
            Call MsgBox("DB接続中に異常が発生しました。" & vbCrLf & _
                        "処理を中断します。", vbCritical + vbOKOnly, Me.Text)
            Exit Sub
        End Try
------------ ソース ------------------------------------------

※接続文字列のCatalog(DB名)、Source(接続先⇒IP)は、設定していますが、
投稿では伏せさせて頂きます…。

プログラムの作りが問題なのか、セットアップにあたっての何か注意点があるのか
困り果ててます。

みなさま、どうかご教授の程、宜しくお願い致します。
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2012/6/8 19:27:56
> ADO.NETにて
コードを見る限りは、ADO.NET ではなく SQL Server Native Client のように見えるのですが、
gado_cn は System.Data.SqlClient.SqlConnection クラスになっていますか?
もしも SqlConnection だとしたら、接続文字列に Provider 句は不要なはずです。


> プロバイダーはローカルのコンピュータに登録されていません。
"Provider=SQLNCLI10.1Persist Security Info=False;" ではなく
"Provider=SQLNCLI10.1;Persist Security Info=False;"とか?
投稿者 acwg  (社会人) 投稿日時 2012/6/11 08:55:44
お世話になります。

即日回答頂けていたのに、返答が遅くなってしまいまして申し訳ありませんでした…。

> ADO.NETにて
>コードを見る限りは、ADO.NET ではなく SQL Server Native Client のように見えるのですが、
>gado_cn は System.Data.SqlClient.SqlConnection クラスになっていますか?
>もしも SqlConnection だとしたら、接続文字列に Provider 句は不要なはずです。

ADO.NETだと思って使用していました…。
こちらは、「Imports System.Data.OleDb」をインポートしていまして、「gado_cn」の宣言は、
    Public gado_cn                  As New OleDbConnection 
となっています。

プロバイバーの書き方については、これから早速試してみます。

ご協力ありがとうございます。
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2012/6/11 14:06:56
> ADO.NETだと思って使用していました…。
ADODB 名前空間の Connection だとしたら、ADO.NET ではなく ADO となります。
OleDb 名前空間のものは、ADO.NET には違いありませんが、ブリッジ接続となります。

System.Data.OleDb 名前空間そのものは ADO.NET ですし、
System.Data.Odbc  名前空間も、一種の ADO.NET ですが、
これらは OLEDB 経由/ODBC 経由での ADO.NET 接続となります。

これらのブリッジ接続を利用して SQL Server にアクセスすることも可能ですが、どうせならば、
『SQL Server へのADO.NET接続』には、『System.Data.SqlClient 名前空間』のオブジェクトを
利用するようにしましょう。SqlClient は SQL Server 7.0 以降に最適化されています。
(ADOMD.NET なら、Microsoft.AnalysisServices.AdomdClient 名前空間です)

※なお、OLE DB Provider との比較のため、System.Data.SqlClient のライブラリは
 「.NET Framework Data Provider for SQL Server」と呼ばれることがあります。


これは SQL Server に限った話ではありません。たとえば『Oracle への ADO.NET接続』なら、
ODP.NET と呼ばれる Oracle.DataAccess.Client.OracleConnection が推奨されており、
現在では、旧テクノロジーである下記名前空間からの接続が非推奨となっています。
 System.Data.OleDb.OleDbConnection
 System.Data.Odbc.OdbcConnection
 Microsoft.Data.Odbc.OdbcConnection


もちろん、OLE DB 以外の接続手段が用意されていないデータベース等において、
System.Data.OleDb.OleDbConnection 等を使う事は問題無いですけれどね。


> プロバイバーの書き方については、これから早速試してみます。
どうしても OLE DB で繋ぐのであれば、下記のプロバイダーを利用できます。
(この他、サードパーティから市販されているプロバイダーもあります)

「SQLOLEDB」 … SQL Server 6.5以降用 OLE DB プロバイダー
「SQLNCLI」  … SQL Server 2005 用 Native Client OLE DB プロバイダー
「SQLNCLI10」… SQL Server 2008 用 Native Client OLE DB プロバイダー
「SQLNCLI11」… SQL Server 2012 用 Native Client OLE DB プロバイダー



接続文字列は、ConnectionStringBuilder を通じて生成することもできます。

Dim ocb As New OleDbConnectionStringBuilder()
ocb.Provider = "SQLNCLI10.1"
ocb.DataSource = "serverName"
ocb("Initial Catalog") = "targetDB"
ocb("User ID") = "sa"
ocb("Password") = "allsys"
' Provider=SQLNCLI10.1;Data Source=serverName;Persist Security Info=False;Password=allsys;User ID=sa;Initial Catalog=targetDB 
connectionString = ocb.ToString()
Dim con As New SqlConnection(connectionString)
con.Open()



Dim scb As New SqlConnectionStringBuilder()
scb.PersistSecurityInfo = False
scb.UserID = "sa"
scb.Password = "allsys"
scb.InitialCatalog = "targetDB"
scb.DataSource = "serverName"
' Data Source=serverName;Initial Catalog=targetDB;Persist Security Info=False;User ID=sa;Password=allsys 
connectionString = scb.ToString()
Dim con As New SqlConnection(connectionString)
con.Open()


上記はサンプルなので、各パラメータは適宜調整してください。

また、実際に運用するアプリで固定的に「sa アカウント」で接続することは避けるべきです。
http://www.atmarkit.co.jp/fwin2k/special/secseminar2003/wsseminar1_04.html



以下、関連情報として:

・SQL Server Native Client と ADO の併用
http://msdn.microsoft.com/ja-jp/library/ms130978.aspx
》 新しいアプリケーションを開発している場合は、SQL Server の
》 最新バージョンのすべての新機能にアクセスできるように、
》 SQL Server Native Client ではなく、ADO.NET および
》 .NET Framework Data Provider for SQL Server の使用を
》 検討することをお勧めします。


・SQL Server 2012 は、OLE DB をサポートする最後のバージョンとなる見込み
http://news.mynavi.jp/news/2011/09/01/083/index.html
http://www.infoq.com/jp/news/2011/09/OLE-DB-End
》 SQL Serverのデータにネイティブにアクセスする方法として
》 「OLE DB」のサポートを廃止し、かわりに「ODBC」に比重を移すことを発表した。
》 Denali(SQL Server 2012)はOLE DBをサポートする最後のSQL Serverになる。
》 マイクロソフトによると、ADO.NET(OLE DBの上で実行できる)は
》 継続してサポートされるが、非OLE DBプロバイダにアップデートする必要がある。
投稿者 acwg  (社会人) 投稿日時 2012/6/11 14:44:34
魔界の仮面弁士様
丁寧な説明ありがとうございます。

今ご相談しているプログラムが、ほぼ出来上がってしまってまして、配布するにあたって、
この問題が出ている状況なのです…。

なので、今回は時間的な都合上OLEDBのまま進めようと思います。ただ、SQLClientなどの
専用接続を使ったほうが最適化されているとのことなので、今後の為に調べてみます。

ちなみに、頂いた情報を元に見直してみたのですが、状況がかわらないです…。

整理の意味で現状を再度書かせて頂きますと、

・開発環境では問題なく、ServerPCにあるSQL Serverには接続できています。
・実行環境のPCでは、エラーメッセージ「プロバイダーはローカルコンピュータに登録されていません。」が出て、接続に失敗します。
・配布は、セットアッププロジェクトを使用してSetup.exeを作成し、それで配布しています。

といった状態なのですが、状況的にセットアッププロジェクトの作るところの作業に問題があるのかと
思えてきました…。(頂いたアドバイスと、開発環境では接続できているところからも)

ちなみに、セットアッププロジェクトのアプリケーションフォルダにて、
「プロジェクト出力」⇒「プライマリ出力」と操作して、配布ファイルを作成しているのですが、
この操作で関連するDLLファイルが表示されるのですが、この中にOLEDBのDLLらしきものは
表示されていません。
これは正常なことなのでしょうか??

質問が多岐にわたってしまってきていますが、アドバイスを頂けると助かります。
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2012/6/11 15:31:36
> ちなみに、頂いた情報を元に見直してみたのですが、状況がかわらないです…。

状況が変わらないという事は、相変わらず
 『'SQLNCLI10.1Persist Security Info=False' プロバイダーは~~登録されていません。』
と表示されるという事でしょうか?

『'SQLNCLI10.1' プロバイダー』や『'SQLNCLI10' プロバイダー』なら分かりますが、
'SQLNCLI10.1Persist Security Info=False' と表示されているいう事は、Provider= 指定時の
セミコロンが抜けているという事なので、接続文字列を見直してみてください。



> ・開発環境では問題なく、ServerPCにあるSQL Serverには接続できています。
(1) Server は x64 ですか? x86 ですか?
64bit 環境の場合は、EXE のコンパイルモードを AnyCPU / x86 ビルドで
切り替えてみて、動作に差異があるかどうかを確認してみてください。

(2) UDL での接続は出来ていますか?
拡張子 .udl の 0 バイトのファイルをデスクトップ上に配置し、
それをダブルクリックして、接続設定を行ってみてください。
([プロバイダー]タブで、"SQL Server Native Client 10.0"を選択します)
もしも UDL での接続テストが成功するのであれば、その *.udl を
メモ帳で開いて、接続文字列の内容を確認してみてください。


>・実行環境のPCでは、エラーメッセージ「プロバイダーはローカルコンピュータに登録されていません。」が出て、接続に失敗します。
(3) SQLNCLI10 が正しくインストールされていないか、利用不可になっている可能性があります。
実行環境に SQL Server Native Client をインストールしてあるかどうかを確認してみてください。
(SQLNCLI10 は、OS 標準部品でも無ければ、VB のランタイムの一部でもありません)


> ・配布は、セットアッププロジェクトを使用してSetup.exeを作成し、それで配布しています。
(3') そのインストーラーは、SQL Server Native Client のインストール機能を有していますか?
sqlncli.msi を使うか、またはそれに相当するマージモジュールを組み込む必要があると思います。


> この中にOLEDBのDLLらしきものは表示されていません。
EXE と同じフォルダに配置して使う類のライブラリではないためでしょう。
OLE DB は通常、Side-by-Side インストールには対応していません。

これは SQL Server Native Client だけではなく、OLE DB Provider for SQL Server の場合も同様です。
投稿者 acwg  (社会人) 投稿日時 2012/6/11 16:13:59
魔界の仮面弁士様

丁寧な回答ありがとうございます。
頂いた回答のおかげで実行環境で接続できるようになりました。

>状況が変わらないという事は、相変わらず
> 『'SQLNCLI10.1Persist Security Info=False' プロバイダーは~~登録されていません。』
>と表示されるという事でしょうか?
すいません…。自分がエラーメッセージを前の投稿からコピペしてしまっていまして、お伝えしたかった
のが、「~登録されていません。」というメッセージが出るということで、接続文字列に関しましては、先に頂いたご指摘にて、誤りがわかり修正してあります。

解決の決め手ですが、

>(3') そのインストーラーは、SQL Server Native Client のインストール機能を有していますか?
>sqlncli.msi を使うか、またはそれに相当するマージモジュールを組み込む必要があると思います。

こちらでした。配布時にsqlncli.msiでSQL Server Native Clientを入れなくてはいけないということを
わかっていませんでした…。こちらを入れてみた所、実行環境でも接続できるようになりました。

いつも的確な回答で、本当に助けられています。
ありがとうございました!
他の情報も、十分に読ませて頂いて、知識として覚えたいと思います。

本件は、これで解決とさせて頂きます。ありがとうございました!
投稿者 acwg  (社会人) 投稿日時 2012/6/11 16:15:03
すいません…。
解決チェックを入れるのを忘れました…。