ラベル SQL Server の投稿を表示しています。 すべての投稿を表示
ラベル SQL Server の投稿を表示しています。 すべての投稿を表示

2014年9月2日火曜日

[C#][SQL Server Express LocalDB] キー 'attachdbfilename' には無効な値です。

SQL Server Express CE(Compact Edition)が廃止されて、代わりにSQL Server LocalDB という SQL Server の機能がフルで使えるデータベースが使えるようになりました。前者はインプロセスでしたし、SQL Serverはサービスとして動作しますが、LocalDBは使用時にプロセスが起動し、使わなくなったらプロセスが終了します。これは便利だと思い、ちょうど以前 SQL Server CE を使用したアプリケーションのリメイクを行うこととなったので、ついでに LocalDB に移行しました。
順調に試験が終わってリリースしたところ、実機でエラーが出て起動できないと報告がありました。調べてみると次のエラーが出ていました。

キー 'attachdbfilename' には無効な値です。
   場所 System.Data.SqlClient.SqlConnectionString.VerifyLocalHostAndFixup(String& host, Boolean enforceLocalHost, Boolean fixup)
   場所 System.Data.SqlClient.SqlConnectionString..ctor(String connectionString)
   場所 System.Data.SqlClient.SqlConnectionFactory.CreateConnectionOptions(String connectionString, DbConnectionOptions previous)
   場所 System.Data.ProviderBase.DbConnectionFactory.GetConnectionPoolGroup(String connectionString, DbConnectionPoolGroupOptions poolOptions, DbConnectionOptions& userConnectionOptions)
   場所 System.Data.SqlClient.SqlConnection.ConnectionString_Set(String value)
   場所 System.Data.SqlClient.SqlConnection.set_ConnectionString(String value)
   場所 System.Data.SqlClient.SqlConnection..ctor(String connectionString)

うぬぬ、よくわからんです。海外のサイトとかも含めて調べていたら、どうもバージョンが不一致だからダメだっていうことらしいです。実機には「Microsoft SQL Server 2014 Express のダウンロード 」をインストールしています。Visual Studio の 2013 で LocalDB を追加したら、LocalDB の は v11.0 で生成されますが、実機にインストールした LocalDB は v12.0 なんだとか。Visual Studio の最新のサービスパックを適用しても v11.0 で生成されてしまう。どうしろというのだ。まったく。

苦肉の策ですが、開発環境は v11.0 だけどインスタンス名を v12.0 にしてしまって接続することで回避できました。アプリケーション起動時に下記コマンドを実行します。


    // V12インスタンスのインストール
    var process = new Process()
    {
        StartInfo = new ProcessStartInfo(System.Environment.GetEnvironmentVariable("ComSpec"))
                    {
                        Arguments = "/c sqllocaldb create v12.0",
                        CreateNoWindow = true,
                        RedirectStandardOutput = true,
                        RedirectStandardInput = false,
                        UseShellExecute = false,
                    },
    };
    process.Start();
    var result = process.StandardOutput.ReadToEnd();
    process.WaitForExit();
    process.Close();
    if(!result.Contains("v12.0"))
    {
        throw new Exception(result);
    }

接続文字列(ConnectionString)を次のように変更します。

Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\Database1.mdf;Integrated Security=True
                       ↓
Data Source=(LocalDB)\v12.0;AttachDbFilename=|DataDirectory|\Database1.mdf;Integrated Security=True


これで開発機でも実機でもうまく動作するようになりました。




2012年8月7日火曜日

[SQL Server] ERROR [08001] [Microsoft][ODBC SQL Server Driver][Shared Memory]SSL セキュリティ エラー

現地で異常が発生したとのこと。
もはやそのプロジェクトからは外れているが、今の担当者だとお手上げらしく、お声がかかる。

ログを見てみた。



ERROR [08001] [Microsoft][ODBC SQL Server Driver][Shared Memory]SSL セキュリティ エラー
ERROR [01000] [Microsoft][ODBC SQL Server Driver][Shared Memory]ConnectionOpen (SECDoClientHandshake()).
   場所 System.Data.Odbc.OdbcConnection.HandleError(OdbcHandle hrHandle, RetCode retcode)
   場所 System.Data.Odbc.OdbcConnectionHandle..ctor(OdbcConnection connection, OdbcConnectionString constr, OdbcEnvironmentHandle environmentHandle)
   場所 System.Data.Odbc.OdbcConnectionOpen..ctor(OdbcConnection outerConnection, OdbcConnectionString connectionOptions)
   場所 System.Data.Odbc.OdbcConnectionFactory.CreateConnection(DbConnectionOptions options, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningObject)
   場所 System.Data.ProviderBase.DbConnectionFactory.CreateNonPooledConnection(DbConnection owningConnection, DbConnectionPoolGroup poolGroup)
   場所 System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection)
   場所 System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
   場所 System.Data.Odbc.OdbcConnection.Open()
   場所 System.Data.Common.DbDataAdapter.QuietOpen(IDbConnection connection, ConnectionState& originalState)
   場所 System.Data.Common.DbDataAdapter.FillInternal(DataSet dataset, DataTable[] datatables, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)
   場所 System.Data.Common.DbDataAdapter.Fill(DataTable[] dataTables, Int32 startRecord, Int32 maxRecords, IDbCommand command, CommandBehavior behavior)
   場所 System.Data.Common.DbDataAdapter.Fill(DataTable dataTable)


うん、わからん。


これがDBにアクセスする度に発生している。
アプリケーションを再起動したら発生しなくなったとか。

Handshakeっていうことは、要求と応答がどっかで入れ替わっちゃったのかな。



google先生に聞いてみよう。

この辺がそれっぽいけど、現地のはSQL Server2005なんだよね。


ただ、確かSPが全くあたってなかったと思うので、後者は去年の話だし、アップデートすれば解決するかも。

それにしても情報が少なすぎる。






後は、同じように困っている人が、


■接続文字列に「Trusted_Connection=yes;」付けました


とか


■レジストリをいじってみました



ぐらいしか見つからんかった。

原因がはっきりせんから再現もさせられんし、させられんイコール上記対応したところで動作確認できんし。


Microsoft のサポートになげても時間がかかりすぎるし、もしそれで不具合だと認められても対応はいつになるかわからん。


アプリ側での対処するなら、DBアクセス部分を切り離してプロセスを解放して動的にまたロードするとか、アクセス箇所(TableAdapter)をちゃんとusingしてあげて解放させる(明示的にしないとしばらく保持されるらしいが、現状ほとんど放置状態;;)ぐらいだが、インパクトが大きすぎる。(後者はそれほどでもないが)


とりあえずサービスパックで様子見させてくださいが落としどころかもしれない。お客さんが許してくれれば。