代码之家  ›  专栏  ›  技术社区  ›  vtortola

DataAdapter返回空行集,但DataReader返回数据

  •  1
  • vtortola  · 技术社区  · 16 年前

    我执行一个调用SP的查询,该SP返回数据。。。但是当我用一个数据适配器调用它时,如果改用一个数据读取器,就不会得到结果数据。。。然后我得到数据。数据库是SQL Server,代码正在使用OleDb,原因是我无法更改。

    这两个调用返回不同的内容:

        String commandText = "Declare @return_value int;  exec dbo.copyTemplate ? , ? , ? , ? , ? ,  ? ,   ?, Null , 0 , @return_value;";
    
        Console.WriteLine("Data Adapter");
        using (OleDbConnection con = new OleDbConnection(connectionString))
        {
            using (OleDbDataAdapter da = new OleDbDataAdapter(commandText, con))
            using (DataTable table = new DataTable("table"))
            {
                da.SelectCommand.Parameters.AddWithValue("?",9).DbType = DbType.Int32;
                da.SelectCommand.Parameters.AddWithValue("?", "AAAAB").DbType = DbType.String;
                da.SelectCommand.Parameters.AddWithValue("?", 1).DbType = DbType.Int32;
                da.SelectCommand.Parameters.AddWithValue("?", 1).DbType = DbType.Int32;
                da.SelectCommand.Parameters.AddWithValue("?", 2).DbType = DbType.Int32;
                da.SelectCommand.Parameters.AddWithValue("?", true).DbType = DbType.Boolean;
                da.SelectCommand.Parameters.AddWithValue("?", DateTime.Now.Date).DbType = DbType.DateTime;
    
                da.Fill(table);
    
                foreach (DataRow dr in table.Rows)
                {
                    foreach (DataColumn dc in table.Columns)
                    {
                        Console.Write(dr[dc].ToString());
                        Console.Write(" ");
                    }
                    Console.WriteLine();
                }
            }
        }
        Console.WriteLine("Data Reader");
        using (OleDbConnection con = new OleDbConnection(connectionString))
        {
            using (OleDbCommand cmd = new OleDbCommand(commandText, con))
            {
                cmd.Parameters.AddWithValue("?", 9).DbType = DbType.Int32;
                cmd.Parameters.AddWithValue("?", "AAAAC").DbType = DbType.String;
                cmd.Parameters.AddWithValue("?", 1).DbType = DbType.Int32;
                cmd.Parameters.AddWithValue("?", 1).DbType = DbType.Int32;
                cmd.Parameters.AddWithValue("?", 2).DbType = DbType.Int32;
                cmd.Parameters.AddWithValue("?", true).DbType = DbType.Boolean;
                cmd.Parameters.AddWithValue("?", DateTime.Now.Date).DbType = DbType.DateTime;
    
                con.Open();
    
                using (OleDbDataReader reader = cmd.ExecuteReader())
                    while (reader.Read())
                    {
                        for (int i = 0; i < reader.FieldCount; i++)
                        {
                            Console.Write(reader.GetValue(i) ?? "null");
                            Console.Write(" ");
                        }
                        Console.WriteLine();
                    }
            }
        }
    
        Console.ReadKey(true);
    

    此代码返回:

    Data Adapter
    Data Reader
    1057
    

    我不明白为什么会这样。

    有人知道会有什么问题吗?

    干杯。

    :如果我填充数据集而不是数据表,则会得到结果:

        Console.WriteLine("Data Adapter with DataSet");
        using (OleDbConnection con = new OleDbConnection(connectionString))
        {
            using (OleDbDataAdapter da = new OleDbDataAdapter(commandText, con))
            using (DataSet ds = new DataSet("table"))
            {
                da.SelectCommand.Parameters.AddWithValue("?",9).DbType = DbType.Int32;
                da.SelectCommand.Parameters.AddWithValue("?", "AAAAB").DbType = DbType.String;
                da.SelectCommand.Parameters.AddWithValue("?", 1).DbType = DbType.Int32;
                da.SelectCommand.Parameters.AddWithValue("?", 1).DbType = DbType.Int32;
                da.SelectCommand.Parameters.AddWithValue("?", 2).DbType = DbType.Int32;
                da.SelectCommand.Parameters.AddWithValue("?", true).DbType = DbType.Boolean;
                da.SelectCommand.Parameters.AddWithValue("?", DateTime.Now.Date).DbType = DbType.DateTime;
    
                da.Fill(ds);
    
                foreach (DataTable table in ds.Tables)
                    foreach (DataRow dr in table.Rows)
                    {
                        foreach (DataColumn dc in table.Columns)
                        {
                            Console.Write(dr[dc].ToString());
                            Console.Write(" ");
                        }
                        Console.WriteLine();
                    }
            }
        }
    

    但是数据集只包含一个表,所以我仍然不明白为什么DataAdapter.Fill(DataTable)不工作。

    1 回复  |  直到 16 年前
        1
  •  2
  •   vtortola    16 年前

    问题是存储过程(正如@leppie指出的那样)返回几个结果集,第一个是空的,第二个包含实际结果。

    Fill(DataTable)只获取第一个结果集并将其放在DataTable上,因为该结果为空,所以会得到一个空的DataTable。无法获取空值,因为数据表已创建,适配器仅填充数据表。

    DataReader遍历所有的结果集,因此您在这里得到了结果,但是这样使用它是错误的。因为第一个结果集为空,所以现在没有问题,但是如果存储过程或特殊查询返回多个结果集,则可以得到两个或多个不同的表,其中设置了不同的列,并在一个数据表中搞乱了所有内容。

    Fill(data set)为每个结果集获取一个DataTable,因为第一个结果集为空,而第二个结果集中只有数据,所以只能获取一个DataTable的数据集。

    http://social.msdn.microsoft.com/Forums/en-US/adodotnetdataproviders/thread/8fdbaa2d-1f1e-461f-8505-b80ea0c415f2

    推荐文章