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

时间:2010-10-13 09:42:37

标签: .net ado.net odbc datareader dataadapter

我执行一个调用SP的查询,该SP返回数据......但是当我用DataAdapter调用它时,我没有得到结果数据,如果使用DataReader,那么我得到数据。数据库是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

我可以调用这个代码数百次,我总是在数据读取器中得到一个数据适配器中的值,我可以在第二个参数中有任何内容,它不会改变SP结果中的任何内容。我可以在两次调用之间交换参数值,或者改变顺序......结果仍然是相同的:(

我不明白为什么会这样。

有没有人知道可能出现什么问题?

干杯。

UPDATE :如果我填写DataSet而不是DataTable,我会得到结果:

    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();
                }
        }
    }

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

1 个答案:

答案 0 :(得分:2)

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

DataAdapter.Fill(DataTable)只获取第一个结果集并将其放在DataTable上,因为结果为空,您将得到一个空的DataTable。您无法获得“null”,因为DataTable已经创建,适配器只是填充了DataTable。

DataReader遍历所有结果集,因此你得到了结果,但这样做是错误的。因为第一个结果集是null,所以现在没有问题,但是如果存储过程或即席查询返回多个结果集,则可以获得两个或更多个不同的表,设置不同的列并在一个DataTable中弄乱所有内容。

DataAdapter.Fill(DataSet)获取每个结果集的DataTable,因为第一个是null,并且第二个中只有数据,只有一个DataTable得到一个DataSet。

解决此问题的正确且无痛的方法是修复存储过程并返回一个结果集,可能有一些东西在SP中返回一个空变量或类似的东西。如果要支持多个结果集,则必须使用DataAdapter.Fill(DataSet)并处理可能在填充的DataSet中存在多个DataTable的想法。

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