2016-03-01 39 views
-1

當我執行3行腳本(或多個)(實施例:我更新,II DELETE,III SELECT),SSMS給我3消息(一個或多個)和1個結果:SqlCommand時使用多結果執行

  1. 我UPDATE - > X行(多個)受影響的
  2. II刪除 - > X行(多個)受影響的
  3. III SELECT - > X行(多個)受影響的

  4. III SELECT - >網格視圖

我怎樣才能讓它成爲我自己的?使用C#。

我創建:

SqlConnection cn = new SqlConnection("blabla"); 
SqlCommand cmd = new SqlCommand("my script", cn); 

現在我需要執行,並得到所有類型的結果

  1. 行(S)的影響
  2. 行(S)的影響
  3. 的DataTable(或DataSet)
+0

爲什麼你需要將它們作爲1腳本運行?你只需要受影響的'INSERT','UPDATE'和'DELETE'的行數? –

+2

爲什麼要在同一個語句中運行它們?使用SqlTransaction,在最後一個語句執行後提交事務。 – Igor

+0

我需要所有人都在一個,因爲那不是我生成腳本的人,有沒有辦法像Microsoft SQL Server Management Studio那樣執行它? –

回答

1

如果您訂閱StatementCompleted事件,您可以獲取所需的行數。

var rowCounts = new List<int>(); 
var resultSets = new List<DataTable>(); 

using (SqlConnection cn = new SqlConnection(connectionString)) 
using (SqlCommand cmd = new SqlCommand(myScript, cn)) 
{ 
    cmd.StatementCompleted += (sender, eventArgs) => 
    { 
     rowCounts.Add(eventArgs.RecordCount); 
    }; 
    cn.Open(); 

    using (var rd = cmd.ExecuteReader()) 
    { 
     do 
     { 
      var table = new DataTable(); 
      table.Load(rd); 
      resultSets.Add(table); 
     } while (rd.NextResult()); 
    } 
} 

//rowCounts now holds all of the reported rowcounts 
//resultSets now holds all of the result sets returned. 

重要提示,如果有人在他們的劇本做SET NOCOUNT ON事件StatementCompleted將不火,讓rowcounts在這種情況下,你必須在腳本中使用@@rowcount,並明確地返回它作爲一個SELECT結果集。

1

我假設它使得t他整個事情失敗或成功?爲什麼不使用相同的連接和事務,然後在最後提交事務。這就是交易的目的。有關更多示例和詳細信息,請參閱SqlTransaction documentation

private static void Demo1() 
{ 
    SqlConnection db = new SqlConnection("connstringhere"); 
    SqlTransaction transaction; 

    db.Open(); 
    transaction = db.BeginTransaction(); 
    try 
    { 
     var updateResultNums = new SqlCommand("UPDATE", db, transaction).ExecuteNonQuery(); 
     var deleteResultNums = new SqlCommand("DELETE", db, transaction).ExecuteNonQuery(); 
     var reader = new SqlCommand("SELECT", db, transaction).ExecuteReader(); 
     while (reader.Read()) 
     { 
      // read 
      // alternatively see http://stackoverflow.com/a/13870892/1260204 if you really want a data table from the SqlCommand 
     } 
     transaction.Commit(); 
    } 
    catch (SqlException sqlError) 
    { 
     transaction.Rollback(); 
     // do something to handle error 
    } 
    finally 
    { 
     db.Close(); //close connection 
     db.Dispose(); //dispose connection 
     transaction.Dispose(); 
    } 
} 
+0

而不是使用catch並最終阻止你真的應該使用'using'語句並將連接和事務包裝在它們中。 –

+0

@ScottChamberlain - 我不同意。 「使用」轉化爲IL中的「try/finally」塊,因此,IMO,它可以滿足某人的個人偏好,因爲它在所得的IL代碼中沒有區別。如果我只處理1個「IDisposable」對象,我喜歡'使用'塊。如果有很多,我討厭嵌套的外觀,如果需要有一個catch塊,也是如此。對我來說,通過一個'try/catch/finally'代碼更具可讀性,所有一次性代碼都在'finally'中處理。 – Igor

+0

你不需要將它們嵌套在一起,看看我發佈的答案,以便使用沒有縮進嵌套的塊的示例。另外,你真的應該按照創建的oppisate順序來處理,'transaction'應該放在db之前。在這種情況下,這並不重要(我認爲),但其他類型可能不會寬容,如果您將它們亂序處理。 –