最近遇到一个需求,大致是这样:执行.sql脚本,返回数据集到csv文件,然后把它作为邮件附件发送到若干邮箱。
执行sql语句返回纪录集比较常用的方法,是创建一个SqlDataAdapter对象,一个DataSet对象,然后用SqlDataAdapter对象的fill方法,把结果集fill到DataSet对象中。
但是如果执行的sql语句比较复杂,而且基于某种特定情况下,你无法干预要执行的sql语句的内容。
比如:
Insert into ...
Select ...
Update xxx ...
Select ...
Select ...
用上面的方法没有办法使用事务,一旦出错,无法整体回滚。这是个很讨厌的事情。
可以使用如下方法实现:
- SqlCommand cmd = new SqlCommand();
- SqlTransaction trans = DataBaseConnection.conn.BeginTransaction();
- cmd.CommandText = contentText;
- cmd.Connection = DataBaseConnection.conn;
- cmd.Transaction = trans;
- DataSet ds = new DataSet();
- try
- {
- SqlDataReader sr = cmd.ExecuteReader();
- do
- {
- DataTable dtrd = ConvertDrToDt(sr);//把sqldatareader转换成datatable
- ds.Tables.Add(dtrd);
- }
- while (sr.NextResult());
- sr.Close();
- trans.Commit();
- Console.WriteLine("事务提交成功!");
- }
- catch (SqlException ex)
- {
- trans.Rollback();
- }
-
- /// <summary>
- /// Convert sqldatareader to datatable
- /// </summary>
- /// <param name="dataReader"></param>
- /// <returns></returns>
- public static DataTable ConvertDrToDt(SqlDataReader dataReader)
- {
- int num;
- DataTable table = new DataTable();
- for (num = 0; num < dataReader.FieldCount; num++)
- {
- DataColumn column = new DataColumn();
- column.DataType = dataReader.GetFieldType(num);
- column.ColumnName = dataReader.GetName(num);
- table.Columns.Add(column);
- }
- while (dataReader.Read())
- {
- DataRow row = table.NewRow();
- for (num = 0; num < dataReader.FieldCount; num++)
- {
- row[num] = dataReader[num];
- }
- table.Rows.Add(row);
- row = null;
- }
- return table;
- }