代码之家  ›  专栏  ›  技术社区  ›  bbsimonbb

什么是舍入十进制列中的值?

  •  1
  • bbsimonbb  · 技术社区  · 7 年前

    我有一个SQL更新请求。我希望它只修改在更新模型中为其提供值的列,因此我使用常规表单 myCol = ISNULL(@myParam, myCol) . 这是完整的SQL。。。

    update Justif set 
    DateTransaction = ISNULL(@dateTransaction,DateTransaction),
    Cif = ISNULL(@cif,Cif),
    NomFournisseur = ISNULL(@nomFournisseur,NomFournisseur),
    MontantHT = ISNULL(@montantHT,MontantHT),
    MontantTtc = ISNULL(@montantTtc,MontantTtc),
    TauxTva = ISNULL(@tauxTva,TauxTva),
    MontantTva = ISNULL(@montantTva,MontantTva),
    ReceptionNumber = ISNULL(@receptionNumber,ReceptionNumber),
    Locked = IIF(@locked > 0,GETDATE(),null),
    Used = IIF(@used is not null, @used, Used),
    NatureOcr = ISNULL(@natureOcr, NatureOcr)
    where JustifID = @justifId
    

    现在,最奇怪的是,有一次应用程序使用这个请求只是为了设置列 Used .

    这个 montantTtc 与所有其他参数一样,参数初始化为 DBNull.Value int

    ISNULL() ?

    enter image description here

    1 回复  |  直到 7 年前
        1
  •  2
  •   Jeroen Mostert    7 年前

    参数类型推断再次出现。A. Decimal SQL参数 NULL DECIMAL(29,0) ISNULL

    using (var connection = new SqlConnection(@"Data Source=(localdb)\MSSQLLocalDB")) {
        connection.Open();
        using (var command = new SqlCommand(@"
            DECLARE @v DECIMAL(4,1) = 123.4; 
            SELECT 
                ISNULL(@p, @v),
                SQL_VARIANT_PROPERTY(ISNULL(@p, @v), 'Precision'), 
                SQL_VARIANT_PROPERTY(ISNULL(@p, @v), 'Scale')"
        )) {
            command.Connection = connection;
            command.Parameters.Add(new SqlParameter("@p", SqlDbType.Decimal)).Value = DBNull.Value;
            using (var reader = command.ExecuteReader()) {
                reader.Read();
                Console.WriteLine($@"
                    Munged value: {reader.GetValue(0)}
                    Precision: {reader.GetValue(1)}
                    Scale: {reader.GetValue(2)}
                ");
            }
        }
    }
    

    最大值:123
    精度:29

    这个 适当的 解决办法是提供 Precision 和 Scale 根据列设置参数的值。另一种选择是使用

    COALESCE(@p, @v)
    

    这相当于形式的表达式

    CASE WHEN @p IS NOT NULL THEN @p ELSE @v END
    

    DECIMAL DECIMAL(30,1) ). 请注意,这是 如果源类型具有很高的精度:使用 DECLARE @v DECIMAL(17,10) = 123.0123456789 将给出一个四舍五入的结果 DECIMAL(38,9) 属于 123.012345679 . 唯一真正通用的修复方法是使用柱的确切类型。