在 C# 中的 SQL CLR 函数中设置小数精度

Set decimal precision in SQL CLR function in C#

我有一个用 C# 编写的 SQL CLR 函数,类似于:

public partial class UserDefinedFunctions
{
    [Microsoft.SqlServer.Server.SqlFunction]
    public static SqlString Decimal(decimal sum)
    {
        return sum.ToString();
    }
}

和SQL服务器假定'sum'是numeric(18,0)类型。

有没有办法在 C# 中更改输入参数的精度和小数位数?

可以使用 SQLFacet 属性指定精度和小数位数。例如,[Microsoft.SqlServer.Server.SqlFacet(Precision = ..., Scale = ...)] ...

虽然关于 SqlFacet 的 allmhuran 是正确的,但请理解 SqlFacet,至少对于 PrecisionScale 属性(至少一些,但也许not all, other properties) 被 Visual Studio / SSDT 用来自动生成用于发布的 DLL。也就是说,如果您编写自己的 CREATE 语句,则无需依赖 SqlFacet。使用 SSDT 执行此操作非常适合初始开发/测试,但 SqlFacet 不支持您可能想要设置的所有选项,例如参数默认值 and/or 类似 WITH RETURNS NULL ON NULL INPUT 的东西(使用对于标量 UDF)。例如:

  • CREATE FUNCTION [schema_name].[function_name]
    (
      @param1 NVARCHAR(MAX),
      @param2 DECIMAL(17, 9)
    )
    RETURNS NVARCHAR(MAX)
    WITH EXECUTE AS CALLER,
         RETURNS NULL ON NULL INPUT
    AS EXTERNAL NAME [assembly].[class].[method];
    
  • CREATE PROCEDURE [schema_name].[proc_name]
        @param1 NVARCHAR(4000) = N'default value',
        @param2 DECIMAL(17, 9) = 123.456789
    WITH EXECUTE AS CALLER
    AS EXTERNAL NAME [assembly].[class].[method];
    

另外:

  • 如果您手动创建对象,您仍然需要 CREATE ASSEMBLY 语句的 DLL 的 VARBINARY 文字表示(假设 Visual Studio 用于编译程序集但不使用它/SSDT 生成发布 SQL 脚本)。为此,您可以使用我写的一个简单的开源命令行实用程序:BinaryFormatter

  • 您应该使用 SqlDecimal 作为输入类型而不是 decimal。然后使用 Value 属性:

    从参数中获取实际的 decimal
    public static SqlString Decimal([SqlFacet(Precision = ..., Scale = ..)] 
    SqlDecimal sum)
    {
       decimal theValue = sum.Value;
    }
    

有关使用 SQLCLR 的更多信息,请访问:SQLCLR Info