2016-03-01 50 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之前。在这种情况下,这并不重要(我认为),但其他类型可能不会宽容,如果您将它们乱序处理。 –

相关问题