SQLDataReader с пустым чтением после ExecuteReader

1

Пожалуйста, помогите исправить мое мышление, я подозреваю, что это либо очевидная ошибка, либо непонимание в том, как читать из хранимой процедуры.

Я пытаюсь получить С# для вызова хранимой процедуры и возврата нескольких строк. Он отлично работает для идентификаторов с одним экземпляром, если я удалю читателя и использую

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

Ключ, который я ему даю (ArchiveID), возвращает два отдельных значения, когда я запрашиваю SQL непосредственно без хранимой процедуры. Если я удалю читателя, я получу одно значение без проблем. Теперь мне нужно сделать так, чтобы он повторялся, потому что в базе данных будет много значений для каждого идентификатора.

Никакая ошибка не бросается, она просто не возвращает никаких данных. Мое понимание - читатель должен перебирать каждую строку, почему нет? Как это исправить?

Теги:
stored-procedures
sqldatareader

3 ответа

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();
  • 0
    Вопрос в том, как правильно читать выходные параметры ...
  • 0
    @ st4hoo Он прав, правда? В текущей настройке out параметров возвращается только одно значение на параметр. OP хочет прочитать несколько строк, возвращенных из SP, что требует другой настройки, такой как эта, где параметры становятся столбцами
Показать ещё 7 комментариев
2

Вы делаете это неправильно, вы не читаете данные у reader:

В цикле while должно быть что-то подобное:

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

ОБНОВЛЕНИЕ:

Я не заметил параметр OUT в процедуре сохранения.

Вот ссылка MSDN на Использование DataReader для обработки значений RETURN и OUTPUT.

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 = "";
  • 0
    Ты уверен? Он пытается получить значение выходного параметра ...
  • 0
    Нет, я не заметил параметр OUT в SP.
1

Вы не можете получить значение выходных параметров перед закрытием SqlDataReader. Вот соответствующий КБ.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню