5

C# Windows アプリケーションからデータベースでスクリプト (.sql ファイル) を実行しようとしています。SQL ファイルには「GO」ステートメントが含まれています。これは、オブジェクト SMO を使用していることを意味します。

エラーを続行し、データベースでのスクリプトの実行中に発生する可能性のあるエラーをログに記録しようとしています。これを行う方法はありますか?

これは私が使用しているコードです:

using (SqlConnection sqlConnection = new SqlConnection(connectionString))
{
    ServerConnection svrConnection = new ServerConnection(sqlConnection);
    Server server = new Server(svrConnection);

    string script = File.ReadAllText("upgradeDatabase.sql");

    try
    {
        server.ConnectionContext.ExecuteNonQuery(script, ExecutionTypes.ContinueOnError);
     }
     catch (Exception ex)
     {
         //handling and logging for the errors are done here
     }
}

どんな助けでも大歓迎です!

4

4 に答える 4

4

ここには2つの問題があると思います:

まず、StringCollection ではなく文字列を受け入れる ExecuteNonQuery メソッドを呼び出します。このメソッドは、バッチ ステートメントを区切るために使用される GO を認識しないと思います。代わりに、StringCollection を受け入れるメソッドExecuteNonQueryのドキュメントには、GO が認識されると記載されています。

2番目の問題はExecutionTypes.ContinueOnError合格です。この場合、同じドキュメントには、何かが失敗した場合に例外を受け取ることができないと記載されています。

入力テキストを GO で分割し、 StringCollectionを作成して ExecuteNonQuery メソッドに渡し、返された影響を受ける行の配列を確認するのが最善の方法だと思います。このようなもの(テストする必要があります)

using (SqlConnection sqlConnection = new SqlConnection(connectionString))
{
    ServerConnection svrConnection = new ServerConnection(sqlConnection);
    Server server = new Server(svrConnection);

    string script = File.ReadAllText("upgradeDatabase.sql");
    string[] singleCommand = Regex.Split(script, "^GO", RegexOptions.Multiline);
    StringCollection scl = new StringCollection();
    foreach(string t in singleCommand)
    {
        if(t.Trim().Length > 0) scl.Add(t.Trim());
    }
    try
    {
        int[] result = server.ConnectionContext.ExecuteNonQuery(scl, ExecutionTypes.ContinueOnError);
        // Now check the result array to find any possible errors??
     }
     catch (Exception ex)
     {
         //handling and logging for the errors are done here
     }
}

もちろん、別の方法は、各ステートメントを実行してContinueOnErrorフラグを削除することです。次に、考えられる例外をキャプチャして記録します。しかし、これは確かに遅くなります。

于 2013-01-09T11:56:12.190 に答える
1

私は、InfoMessage イベントとハンドラーを使用するこのバリアントが本当に気に入っています。

        using(SqlConnection sc = new SqlConnection(connStr))
        {
            sc.InfoMessage += new SqlInfoMessageEventHandler(sc_InfoMessage);
            sc.FireInfoMessageEventOnUserErrors = true;
            Server db = new Server(new ServerConnection(sc));
            db.ConnectionContext.ExecuteNonQuery(commandFileText, ExecutionTypes.ContinueOnError); 
        }

次への参照を追加する必要があります。

  • Microsoft.SqlServer.ConnectionInfo.dll
  • Microsoft.SqlServer.Management.Sdk.Sfc.dll
  • Microsoft.SqlServer.Smo.dll
  • Microsoft.SqlServer.SqlEnum.dll
于 2016-09-08T05:24:49.617 に答える
0

you can use smo library, where is how to add to the project

FileInfo file = new FileInfo("upgradeDatabase.sql");
string script = file.OpenText().ReadToEnd();
SqlConnection conn = new SqlConnection(sqlConnectionString);
Server server = new Server(new ServerConnection(conn));
server.ConnectionContext.ExecuteNonQuery(script);
于 2013-01-09T11:43:12.117 に答える