У меня есть хранимая процедура, которая принимает вход и возвращает несколько столбцов. Хранимая процедура работает, когда я выполняю ее из SSMS, а также внутри VS 2013. Однако, когда я пытаюсь выполнить ее с помощью SqlCommand.ExecuteReader, у читателя нет никаких строк. Если я удаляю выходные параметры из proc и из SqlCommand, сохраняя один входной параметр, я могу вернуть строку, которую я ищу.
Вот хранимая процедура
create Proc sp_ReturnSingleGame
@GameName varchar(100) output,
@PlatformName varchar(50) output,
@ConditionShortDescription varchar(30) output,
@RetailCost decimal(6,2) output,
@InStock bit output,
@GameID int
AS
select @GameName = GameName, @PlatformName = PlatformName,
@ConditionShortDescription = ConditionShortDescription, @RetailCost = RetailCost
from Games inner join Condition
on Games.ConditionID = Condition.ConditionID
inner join ConsolePlatform
on Games.PlatformID = ConsolePlatform.PlatformID
Where Games.GameID = @GameID
if exists (select GameID
From SaleItemized
Where GameID = @GameID)
Begin
set @InStock = 1;
end
else
Begin
set @InStock = 0;
end
Вот мой код на С#
public Game ReturnSingleGame(int gameId)
{
SqlConnection connection = new SqlConnection(@"server=mylaptop; integrated security=true; database=GameStoreDB;");
SqlCommand command = this.ReturnCommandForSp_ReturnSingleGame(connection, gameId);
try
{
connection.Open();
SqlDataReader reader = command.ExecuteReader();
if (reader.HasRows == true)
{
reader.Read();
game.GameId = gameId;
game.GameName = reader["GameName"].ToString();
game.PlatformName = reader["PlatformName"].ToString();
game.RetailCost = (decimal) reader["RetailCost"];
}
else
{
var exception = new ApplicationException("Game was not found");
throw exception;
}
}
catch (Exception)
{
throw;
}
finally
{
connection.Close();
}
return game;
}
private SqlCommand CommandForSp_ReturnSingleGame(SqlConnection connection, int gameId)
{
string storedProc = @"dbo.sp_ReturnSingleGame";
SqlCommand command = new SqlCommand(storedProc, connection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add("@GameName", SqlDbType.VarChar, 100, "GameName");
command.Parameters["@GameName"].Direction = ParameterDirection.Output;
command.Parameters.Add("@PlatformName", SqlDbType.VarChar, 50, "PlatformName");
command.Parameters["@PlatformName"].Direction = ParameterDirection.Output;
command.Parameters.Add("@ConditionShortDescription", SqlDbType.VarChar, 30, "ConditionShortDescription");
command.Parameters["@ConditionShortDescription"].Direction = ParameterDirection.Output;
command.Parameters.Add("@RetailCost", SqlDbType.Decimal);
command.Parameters["@RetailCost"].SourceColumn = "RetailCost";
command.Parameters["@RetailCost"].Precision = 6;
command.Parameters["@RetailCost"].Scale = 2;
command.Parameters["@RetailCost"].Direction = ParameterDirection.Output;
command.Parameters.Add("@InStock", SqlDbType.Bit);
command.Parameters["@InStock"].SourceColumn = "InStock";
command.Parameters["@InStock"].Direction = ParameterDirection.Output;
command.Parameters.Add("@GameID", SqlDbType.Int).Value = gameId;
command.Parameters["@GameID"].SourceColumn = "GameID";
command.Parameters["@GameID"].Direction = ParameterDirection.Input;
command.Prepare();
return command;
}
Сохраненная процедура, предоставленная вами, фактически не возвращает никаких строк данных.
Все, что он делает - это просто заданные выходные параметры.
Поэтому вам не нужен любой SqlDataReader
для извлечения там параметров.
Просто вызовите command.Parameters["@GameName"].Value
command.ExecuteNonQuery()
а затем получите значения параметров из команды. Параметр command.Parameters["@GameName"].Value
и т.д.
Согласитесь с Энди.
Для вашего фрагмента из одного из моих проектов:
DbCommand Cmd = null;
using (DataClient client = new DataClient())
{
SqlParameter[] parameters = new SqlParameter[2];
parameters[0] = new SqlParameter("@ID", SqlDbType.VarChar);
parameters[0].Size = 10;
parameters[0].Direction = ParameterDirection.Output;
parameters[1] = new SqlParameter("@YourParameterName", SqlDbType.VarChar);
parameters[1].Value = Class.PropertyName;
parameters[2] = new SqlParameter("@Year", SqlDbType.Int);
client.ExecuteNonQuery("ReturnCommandForSp_ReturnSingleGame", CommandType.StoredProcedure, parameters, ref Cmd);
Then retrieve it like this
int yourReturnValue= Convert.ToInt32(Cmd.Parameters["@ID"].Value);
}
Надеюсь, поможет.