Пожалуйста, помогите исправить мое мышление, я подозреваю, что это либо очевидная ошибка, либо непонимание в том, как читать из хранимой процедуры.
Я пытаюсь получить С# для вызова хранимой процедуры и возврата нескольких строк. Он отлично работает для идентификаторов с одним экземпляром, если я удалю читателя и использую
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 непосредственно без хранимой процедуры. Если я удалю читателя, я получу одно значение без проблем. Теперь мне нужно сделать так, чтобы он повторялся, потому что в базе данных будет много значений для каждого идентификатора.
Никакая ошибка не бросается, она просто не возвращает никаких данных. Мое понимание - читатель должен перебирать каждую строку, почему нет? Как это исправить?
Изменить 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();
Вы делаете это неправильно, вы не читаете данные у 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 = "";
OUT
в SP.
Вы не можете получить значение выходных параметров перед закрытием SqlDataReader
. Вот соответствующий КБ.
out
параметров возвращается только одно значение на параметр. OP хочет прочитать несколько строк, возвращенных из SP, что требует другой настройки, такой как эта, где параметры становятся столбцами