【问题标题】:Pass decimal less than 0.1 from C# to SQL - SQL Profiler Interpretation Issue将小于 0.1 的小数从 C# 传递到 SQL - SQL Profiler 解释问题
【发布时间】:2019-08-23 09:18:05
【问题描述】:

我无法将小于 0.1 的十进制值正确地从 C# 传递到 SQL 当我从 C# 传递值时,例如十进制值 0.0033M 我在 SQL Profiler 中得到 33

db.Insert(0.0033M);//SP Called from EDMX context `db` C#

当我签入 SQL Profiler 我得到

exec [dbo].[Insert] @Value=33 --Shouldn't it be 0.0033

但是当我传递任何大于等于0.1 的值时,该值被正确传递

如何正确地将十进制值从 C# 传递到存储过程的十进制?


这是我们的 SP 没关系,只是为了让事情更清楚 实际值是我们在前面提到的 Profiler 中收到的值

CREATE PROCEDURE [dbo].[Insert]  
 @Value[decimal](18, 6) NULL
AS            
BEGIN            
        Select @Value  -- this would give `33` when passed `0.0033M` From C#      
END

修改

非常感谢 David Browne - Microsoft 的回答。正如他所提到的,它没有问题,是的,传递价值没有问题。但在我们的进一步调查中,我们确实发现它的 SQL Profiler 解释错误,而 SQL 和 C# 工作正常。在这里我会提到我们使用 ADO.net 和 Entity Framework 进行了测试,发现问题出在 SQL Profiler 解释的内容上,即当传递小于 0.1 时 SQL Profiler 显示值错误,它显示 0.0110.07777。我非常感谢参与其中的每一个人,但我也想在此提及这是 SQL Profiler 未按预期提供结果的异常行为,因为对于许多调试场景,我们使用 SQL Profiler。

【问题讨论】:

  • 你的字段在 SQL 中是如何定义的?是十进制(18,0)吗?如果您需要更多小数,只需将其更改为 DECIMAL(18,NUM_OF_DECIMAL_PLACES)。
  • @viveknuna 值 0.0033 在 C# 中以小数表示。
  • 我们使用 DECIMAL(18,6) @Matt
  • 而你实际上 明确decimal 属于0.0033M,而不是decimal.Parse("0.0033") 或将字符串值传递给该参数?
  • @AliJamal 但是您如何处理从db.Insert(value) 返回的值?

标签: c# sql sql-server entity-framework stored-procedures


【解决方案1】:

什么版本的 EF?我无法使用简单的基于 EF6 EDMX 的数据库优先模型来重现这一点。

添加了这个过程:

CREATE PROCEDURE [dbo].[Insert]  
 @Value[decimal](18, 6) NULL
AS            
BEGIN            
        Select @Value  -- this would give `33` when passed `0.0033M` From C#      
END

添加了一个数据库优先模型,它生成

public virtual ObjectResult<Nullable<decimal>> Insert(Nullable<decimal> value)
{
    var valueParameter = value.HasValue ?
        new ObjectParameter("Value", value) :
        new ObjectParameter("Value", typeof(decimal));

    return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<Nullable<decimal>>("Insert", valueParameter);
}

然后跑了:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp24
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var db = new aEntities())
            {
                var result = db.Insert(0.0033M);
                Console.WriteLine(result.First().Value);
                Console.ReadKey();
            }
        }
    }
}

输出是

0.003300

【讨论】:

  • 非常感谢 David Browne - Microsoft 的回答。正如他所提到的,它没有问题,是的,传递价值没有问题。但在我们的进一步调查中,我们确实发现它的 SQL Profiler 解释错误,而 SQL 和 C# 工作正常。
  • 在这里我会提到我们使用 ADO.net 和 Entity Framework 进行了测试,发现问题出在 SQL Profiler 正在解释的内容上,即当传递小于 0.1 时 SQL Profiler 显示值错误,它显示0.0110.07777。我非常感谢参与其中的每一个人,但我也想在此提及这是 SQL Profiler 未按预期提供结果的异常行为,因为对于许多调试场景,我们使用 SQL Profiler。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-11-01
  • 1970-01-01
  • 2012-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多