【问题标题】:SqlCommand with more than one result table具有多个结果表的 SqlCommand
【发布时间】:2018-10-16 12:18:03
【问题描述】:

我正在使用 Visual Studio 2010 开发 ASP.NET Web 应用程序。我的目标框架是“.NET Framework 4”,我正在向 SQL Server 2008 数据库发送查询,该数据库版本是“Microsoft SQL Server 2008 R2 (SP2)"。

我正在使用以下连接字符串 "Data Source=XXXX;Initial Catalog=XXXX;Integrated Security=False;User Id=XXXX;Password= XXXX;MultipleActiveResultSets=True" 进行连接,并使用以下代码发送查询:

public static List<DataTable> getData(String query)
{
    var results = new List<DataTable>();

    try
    {
        using (SqlConnection connection = new SqlConnection(ConnectionString))
        {
            using (SqlCommand command = new SqlCommand(query, connection))
            {
                connection.Open();
                command.CommandTimeout = 0;

                using (SqlDataReader reader = command.executeReader())
                {
                    do
                    {
                        while (reader.Read()) ;
                        var dataTable = new DataTable();
                        dataTable.Load(reader);
                        results.Add(dataTable);
                    } while (reader.NextResult());
                }

                connection.Close();
            }
        }
    }
}

我发送的查询是一个存储过程,它返回两个表,起初它有一个循环,根据一些内部条件调用另一个存储过程,创建和插入 tempdb..#table 和两个 SELECT 语句。

但现在它只包含:

SELECT 1,2,3,4,5

SELECT 6,7,8,9,0

我不知道为什么,但 reader.NextResult() 总是错误的,所以我从来没有得到第二个表格结果。

有谁知道我做错了什么?我应该怎么做才能接收和读取查询的两个结果?

【问题讨论】:

  • 如果您想要DataTable,为什么不使用SqlDataAdapter 来为您填充数据表?
  • 我不想要 DataTable 我想要未知数量的 DataTablesSqlCommand 一起作为命令的结果。
  • 这是一个非常糟糕的接口,可以提供给代码的其他部分。 a) 避免格式问题和 b) 避免 SQL 注入的最安全方法是使用 parameters 将数据与您询问的任何代码分开 传递到数据库系统跑步。但在你接受一个string 的情况下,这是不可能的。
  • a DataSet 是表示多个DataTables 的自然方式,据我所知,它的Load 方法已经设计为使用多个结果集。
  • @Damien_The_Unbeliever 输入字符串只是一个示例(它是对过程的参数化调用,经过消毒以避免注入)但(目前)安全不是我面临的问题。跨度>

标签: c# asp.net sql-server-2008 visual-studio-2010


【解决方案1】:

如果这是使用存储过程,你需要这样的东西:注意命令类型

using (System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection(myConnString))
{
    using (System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand())
    {
        cmd.CommandText = "myMultipleTablesSP";
        cmd.Connection = conn;
        cmd.CommandType = CommandType.StoredProcedure;

        conn.Open();

        System.Data.SqlClient.SqlDataAdapter adapter = new System.Data.SqlClient.SqlDataAdapter(cmd);

        DataSet ds = new DataSet();
        adapter.Fill(ds);

        conn.Close();
    }
}

例如,如果您在 SP 中返回 2 个表,例如:

SELECT * FROM [TableA];
SELECT * FROM [TableB];

您可以通过以下方式访问这些表:

DataTable tableA = ds.Tables[0];
DataTable tableB = ds.Tables[1];

【讨论】:

  • 这就像一个魅力。我仍然不知道为什么它不适用于我的第一种方法,有什么线索吗?
【解决方案2】:

好的,我进行了一些测试,发现问题出在dataTable.Load(reader);,我不知道为什么以及该方法背后究竟发生了什么。 但是如果你使用

do {
   while(reader.Read()) {
      ...
   }
} while (reader.NextResult());

一切都按预期进行。

【讨论】:

    猜你喜欢
    • 2016-06-14
    • 2013-12-13
    • 1970-01-01
    • 2013-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多