c# - 将TSQL代码转换为C#数据类型问题

标签 c# t-sql sqlclr

我试图回答这个问题SO question ..

给出以下 TSQL 代码

DECLARE @input1 INT = 100000
DECLARE @input2 INT = 40
DECLARE @input3 INT = 106833

DECLARE @X decimal(22,6) = 0
DECLARE @Y decimal(22,6) = 0.001 
DECLARE @Z decimal(22,6)
DECLARE @r decimal(22,6)
DECLARE @v decimal(22,6) 

SET @v = POWER(1/(1+ (@Y/12)), @input2)
    SET @r = ((@Y/@input2) * @input1) / (1-@v) 
    IF (@r < @input3)
        SET @Z = @Y + ABS((@X - @Y)/2)
    ELSE
        SET @Z = @Y - ABS((@X - @Y) /2)

    SET @X = @Y
    SET @Y = @Z 


WHILE (ABS(@r - @input3) > 0.001)
BEGIN
SET @v = POWER(1/(1+ (@Y/12)), @input2)
    SET @r = ((@Y/@input2) * @input1) / (1-@v) 
    IF (@r < @input3)
         SET @Z = @Y + ABS((@X - @Y)/2)
    ELSE
         SET @Z = @Y - ABS((@X - @Y) /2)
    SET @X = @Y
    IF @Y = @Z
    BREAK
    SET @Y = @Z
END

SELECT (CAST(@Y AS decimal(22,6)) * 100)

我尝试将其转换为 C#

            decimal input1 = 100000m;
            decimal input2 = 40m;
            decimal input3 = 106833m;

            decimal x = 0m;
            decimal y = 0.001m;
            decimal z;
            decimal r;
            decimal v;

            v = (decimal)(Math.Pow(Convert.ToDouble(1m / (1m + (y / 12m))), Convert.ToDouble(input2)));

            r = ((y / input2) * input1) / (1 - v);

            if (r<input3)
            {
                z = y + Math.Abs((x - y) / 2);
            }
            else
            {
                z = y - Math.Abs((x - y) / 2);
            }

            x = y;
            y = z;

            while (Math.Abs(r - input3) > 0.001m)
            {
                v = (decimal)(Math.Pow(Convert.ToDouble(1 / (1 + (y / 12))), Convert.ToDouble(input2)));

                r = ((y / input2) * input1) / (1 - v);

                if (r<input3)
                {
                    z = y + Math.Abs((x - y) / 2);
                }
                else
                {
                    z = y - Math.Abs((x - y) / 2);
                }
                x = y;
                if (y==z) break;
                y = z;
            }

            Console.WriteLine(y*100);

但结果却不同。

TSQL 返回 4273.320000,而 C# 代码返回 0,1999999999999999999999998900。 此外,如果我通过

将完全相同的 C# 代码放入 SqlFunction(CLR 函数)中
[Microsoft.SqlServer.Server.SqlFunction]
public static decimal CalcFinancialSpreading(decimal input1 = 100000, decimal input2 = 40, decimal input3 = 106833)

返回0

有人发现错误了吗?

最佳答案

这就是您的解决方案。所以答案是 C# 小数精度与 SQL 不同,在 SQL 中你使用 6 精度数字。因此,请始终将您的号码设置为与此相同(示例),您可以编写自己的帮助器转换器类。 :

public static decimal ConvertTo6(double d)
    {
        return Math.Round(Convert.ToDecimal(d), 6, MidpointRounding.AwayFromZero);
    }

    public static decimal ConvertTo6(decimal d)
    {
        return Math.Round(d, 6, MidpointRounding.AwayFromZero);
    }

    static void Main(string[] args)
    {
        int input1 = 100000;
        int input2 = 40;
        int input3 = 106833;


        decimal x = 0.000000m;
        decimal y = 0.001000m;
        decimal z;
        decimal r;
        decimal v;

        v = ConvertTo6(Pow(1 / (1 + (Convert.ToDouble(y) / 12d)), input2));

        r = ConvertTo6(((y / input2) * input1) / (1 - v));


        if (r < input3)
        {
            z = y + Math.Abs((x - y) / 2);
            z = ConvertTo6(z);
        }
        else
        {
            z = y - Math.Abs((x - y) / 2);
            z = ConvertTo6(z);
        }

        x = y;
        y = z;

        while (Math.Abs(r - input3) > 0.001m)
        {
            v = ConvertTo6((Math.Pow(Convert.ToDouble(1 / (1 + (y / 12))), Convert.ToDouble(input2))));

            r = ((y / input2) * input1) / (1 - v);
            r = ConvertTo6(r);

            if (r < input3)
            {
                z = y + Math.Abs((x - y) / 2);
                z = ConvertTo6(z);
            }
            else
            {
                z = y - Math.Abs((x - y) / 2);
                z = ConvertTo6(z);
            }
            x = y;
            if (y == z) break;
            y = z;
        }

        Console.WriteLine(y * 100);

        Console.Read();
    }

关于c# - 将TSQL代码转换为C#数据类型问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58729607/

相关文章:

sql - 索引 View 及其自己的 Azure 搜索索引器行版本

sql - 在 SQL Server 2008 中从 CLR 程序集(具有 pinvoke 方法来加载非托管程序集)调用函数

c# - 生成用于在 Visual Studio 2012 中创建 XmlSerializers.dll 的脚本

c# - COM 服务器发送空字符串,该字符串被转换为 NULL 指针

c# - 如何从 txt 文件中正确读取瑞典语字符

c# - BinarySearch 没有预期的结果

sql-server - 将用户定义的 CLR 函数的执行限制为 sysadmin 而不是 dbowner

C# 测试堆栈.White : sometimes unable to find button

sql - 是否可以在 Sql Server 中的 View 内设置变量?

sql - Xquery 将 XML 标签解析为列