如何从存储过程中返回十进制值

时间:2015-02-26 10:21:39

标签: c# sql-server sql-server-2008 stored-procedures

我有一个没有返回正确值的存储过程,例如。它应该返回33.30,但它返回33.00,这不是期望的结果。 这是我的存储过程,我使用的是SQL Server 2008

ALTER PROCEDURE [dbo].[sp_UpdateStockForSale]
@prodName varchar(40), 
@stqty numeric(9,2),
@batchno varchar(40),
@IsSample varchar(5)
AS
BEGIN
SET NOCOUNT ON; 
DECLARE @S_en int;
DECLARE @ttavail numeric(9,0);
DECLARE @ttsold numeric(9,0);
DECLARE @Nr decimal(9,2);
DECLARE @NetRate decimal(9,2)
SET @NetRate=0.0;
While (@stqty > 0) BEGIN

    Select @S_en=S_en,@ttavail=S_P_ttavail, @ttsold=S_P_ttsold,@Nr=NetRate From STOCK WHERE S_P_ttavail>0 AND S_P_name = @prodName  AND S_P_batchno=@batchno And IsSample=@IsSample Order By S_en DESC;

    --If Sale Qty is more than Stock
    IF (@ttavail <= @stqty) BEGIN
        SET @stqty = @stqty - @ttavail;
        SET @ttsold=@ttsold + @ttavail;
        SET @NetRate=@NetRate+(@Nr*@ttavail);
        Print (@NetRate);
        SET @ttavail = 0;
    END
    --If Sale Qty is less than STOCK
    ELSE IF(@stqty < @ttavail) BEGIN
        SET @ttsold = @ttsold + @stqty      
        SET @ttavail = @ttavail - @stqty;   
        SET @NetRate=@NetRate+(@Nr*@stqty);
        Print (@NetRate);
        SET @stqty = 0;
    END 
    Update STOCK Set S_P_ttavail = @ttavail, S_P_ttsold=@ttsold Where S_en=@S_en And IsSample=@IsSample
END
print @NetRate
return @NetRate  
END

当我在SSMS中执行它时,我得到了结果

enter image description here

和显示我打印的值的消息,显示获取n次计算的数据正在给出正确的结果[参见最后打印的值]。 enter image description here

我需要将此值保存在另一个表中,因此这是C#代码

cmd = new SqlCommand("sp_UpdateStockForSale ", conn);
                                cmd.CommandType = CommandType.StoredProcedure;
                                cmd.Parameters.AddWithValue("@prodName", dataGridView1.Rows[i].Cells["P_name"].Value);
                                cmd.Parameters.AddWithValue("@stqty", dataGridView1.Rows[i].Cells["P_otabs"].Value); //total tabs
                                cmd.Parameters.AddWithValue("@batchno ", dataGridView1.Rows[i].Cells["P_batch_no"].Value);
                                cmd.Parameters.AddWithValue("@IsSample ", dataGridView1.Rows[i].Cells["IsSample"].Value);

                                var returnParameter = cmd.Parameters.Add("@NetRate", SqlDbType.Decimal);
                                returnParameter.Direction = ParameterDirection.ReturnValue;
                                cmd.ExecuteNonQuery();
                                var result = returnParameter.Value;

请帮助我。谢谢。

3 个答案:

答案 0 :(得分:6)

返回值只能是整数。

使用输出参数从过程中获取结果:

ALTER PROCEDURE [dbo].[sp_UpdateStockForSale]
  @prodName varchar(40), 
  @stqty numeric(9,2),
  @batchno varchar(40),
  @IsSample varchar(5),
  @NetRate decimal(9,2) output
AS
...

使用以下方式调用:

declare @Result decimal(9,2)

exec
  [dbo].[sp_UpdateStockForSale]
  @prodName = N'vicks',
  @stqty = 30,
  @batchno = N'v7',
  @IsSample = N'false',
  @NetRate = @Result output

在C#中,您将创建一个输出参数并在调用之前添加参数:

SqlParameter result = new SqlParameter("@NetRate", SqlDbType.Decimal);
result.Direction = ParameterDirection.Output;
command.Parameters.Add(result);

调用之后(如果有结果集,则读取结果集),您可以从参数中获取值:

Decimal netRate = (Decimal)result.Value;

答案 1 :(得分:2)

我知道,回答已经太晚了。由于Guffa已经提出了一个很好的解决方案,它会根据您的需要返回正确的结果。

但是,还有另一种解决方案,我想与你分享。

在存储过程结束时使用select语句而不是return语句。

NOTE: The infile LINEIN is:
      Filename=\\VBOXSVR\win_7\SAS\DATA\INPUT\linepointer.txt,
      RECFM=V,LRECL=256,File Size (bytes)=105,
      Last Modified=30Jun2015:00:45:47,
      Create Time=30Jun2015:00:32:31

NOTE: LOST CARD.
Lname=JOYCE Fname=BENEFIT Address=MENLO PARK  CA 94025 City=  State=  zip=  _ERROR_=1 _N_=2
NOTE: 6 records were read from the infile LINEIN.
      The minimum record length was 10.
      The maximum record length was 20.
NOTE: SAS went to a new line when INPUT statement reached past the end of a line.
NOTE: The data set WORK.LINEINPUT has 1 observations and 6 variables.
NOTE: DATA statement used (Total process time):
      real time           0.02 seconds
      cpu time            0.01 seconds

并使用 Update STOCK Set S_P_ttavail = @ttavail, S_P_ttsold=@ttsold Where S_en=@S_en And IsSample=@IsSample END Select @NetRate As NetRate END 方法执行存储过程。如何在存储过程中避免不必要的参数声明。

ExecuteScalar()

但是,如果您在存储过程中创建另一个参数没有问题,我仍然建议您使用输出参数,否则您可以坚持使用此解决方案。

答案 2 :(得分:0)

我还必须在SqlParameter类中指定精度和小数位数

var output = new SqlParameter("output", SqlDbType.Decimal)
{
     Direction = ParameterDirection.Output,
     Precision = 18,
     Scale = 2
};

var sql = "exec dbo.SomeOperation @output OUT";

var result = this.Database.ExecuteSqlCommand(sql, output);

return (decimal)output.Value;

否则,即使数据类型为十进制,我也总是得到不带小数点的值。