在ExecuteReader之后使用空读取的SQLDataReader

时间:2014-05-26 11:44:45

标签: c# sql stored-procedures sqldatareader

请帮助纠正我的想法,我怀疑这是一个明显的错误或对如何从存储过程中读取的误解。

我试图让c#调用存储过程并返回多行。如果我删除阅读器并使用

,它适用于具有单个实例的ID
res = cmd.ExecuteNonQuery();

但是在下面的代码中,while部分刚刚被跳过,我看不出原因。我已经玩了一段时间的代码而没有任何运气。字段计数为零,但表中有数据?

using (SqlConnection conn = new SqlConnection(connectionString))
{
    conn.Open();

    try
    {
        using (SqlCommand cmd = new SqlCommand("dbo.ReadFromArchive", conn))
        {
            cmd.CommandTimeout = 1000; //This should be the max timeout.
            cmd.CommandType = System.Data.CommandType.StoredProcedure;

            cmd.Parameters.Add("@ArchiveID", SqlDbType.Char).Value = AD.ArchiveID;

            cmd.Parameters.Add("@DocsKEY", SqlDbType.Char, 36).Direction = ParameterDirection.Output;
            cmd.Parameters.Add("@DocsDateKey", SqlDbType.DateTime).Direction = ParameterDirection.Output;
            cmd.Parameters.Add("@DocumentType", SqlDbType.VarChar, 100).Direction = ParameterDirection.Output;                  
            cmd.Parameters.Add("@OperationType", SqlDbType.VarChar, 30).Direction = ParameterDirection.Output;                   

            try
            {                                                        
                SqlDataReader reader = cmd.ExecuteReader();
                while (reader.Read())
                {
                    AD.AddDocKey((string)cmd.Parameters["@DocsKEY"].Value);
                    AD.AddDateKey((DateTime)cmd.Parameters["@DocsDateKey"].Value);
                    AD.AddDocument((string)cmd.Parameters["@DocumentType"].Value);
                    AD.AddOpType((string)cmd.Parameters["@OperationType"].Value);
                }

                AD.RTKD = res;
                AD.RTMSG = "";
            }
            catch (Exception ex)
            {
                AD.RTMSG = ex.ToString();
                Logger.LogError("1. Error with executing dbo.ReadFromArchive Stored Procedure", ex);
            }
        }
        conn.Close();
    }

    catch (Exception ex)
    {
        AD.RTMSG = ex.ToString();
        Logger.LogError("Error setting up dbo.ReadFromArchive Stored Procedure :", ex);
    }
}

return AD;

存储过程

ALTER PROCEDURE [dbo].[ReadFromArchive]
(

@ArchiveID      CHAR(36)        ,
@DocsKEY        CHAR(36)        OUT,
@DocsDateKey    DATETIME        OUT,
@DocumentType   VARCHAR(100)    OUT,
@OperationType  VARCHAR(30)     OUT

)
AS
BEGIN

Select @DocsKEY         = DocsKEY       from     dbo.ArchiveData where  ArchiveID = @ArchiveID          
Select @DocsDateKey     = DocsDateKey   from     dbo.ArchiveData where  ArchiveID = @ArchiveID              
Select @DocumentType    = DocumentType  from     dbo.ArchiveData where  ArchiveID = @ArchiveID 
Select @OperationType   = OperationType from     dbo.ArchiveData where  ArchiveID = @ArchiveID 

END

当我在没有存储过程的情况下直接查询SQL时,我给它的键(ArchiveID)返回两个单独的值。如果我删除阅读器读取,我会得到一个没有问题的值。现在我需要进行迭代,因为数据库每个ID都有很多值。

不会抛出任何错误,只是不提供任何数据。我的理解是读者应该遍历每一行,为什么不呢?我该如何解决?

3 个答案:

答案 0 :(得分:2)

你做错了,你没有从reader

中读取数据

在while循环中应该是类似的东西:

AD.AddDocKey(reader["DocsKEY"].ToString());

<强>更新

我在商店程序中没有注意到OUT参数。

以下是Using a DataReader to Process the RETURN Value and OUTPUT Parameters上的MSDN参考。

SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
reader.Close();

AD.AddDocKey((string)cmd.Parameters["@DocsKEY"].Value);
AD.AddDateKey((DateTime)cmd.Parameters["@DocsDateKey"].Value);
AD.AddDocument((string)cmd.Parameters["@DocumentType"].Value);
AD.AddOpType((string)cmd.Parameters["@OperationType"].Value);
AD.RTKD = res;
AD.RTMSG = "";

答案 1 :(得分:1)

修改你的SP

ALTER PROCEDURE [dbo].[ReadFromArchive]
(

@ArchiveID      CHAR(36)   

)
AS
BEGIN

Select DocsKEY, DocsDateKey,DocumentType   ,OperationType  from     dbo.ArchiveData where  ArchiveID = @ArchiveID   

END

然后你可以按如下方式获取while循环中的列

reader["reader"].ToString();

答案 2 :(得分:1)

在关闭SqlDataReader之前,您无法获取输出参数值。这是相应的KB