.net - 为什么函数在作为 SQL Server CLR UDF 执行时会输出不同的结果?

标签 .net sql-server sqlclr

我正在使用 .Net DLL 来散列字符串,以便稍后我可以比较它们。

我已将对该函数的调用包装在 SQL Server CLR UDF 中并发布在服务器上。

现在,当我执行函数时,输出与运行控制台应用程序时得到的输出不同。

函数签名如下:

[Microsoft.SqlServer.Server.SqlFunction]
public static SqlInt32 CalculateHash(SqlString input)
{
    string unwrappedValue = input.Value.Normalize();
    int hash = HashCalculator.Calculate(unwrappedValue);
    return new SqlInt32(hash);
}

如您所见,我在计算哈希值之前解包并规范化字符串。因此,无论我从何处调用该代码,我都希望结果是相同的。

给定字符串 Test 123 我得到:

-387939562 - When running from a Console Application
137570918  - When calling from SQL Server

SQL Server UDF 不允许Debug.Print(或类似的)调用。

并且出于某种原因,Visual Studio 在调试 UDF 时不会在 *.cs 文件断点处停止(但这是我仍在尝试解决的另一个问题)。

我的问题是:为什么同一个函数会给出两个不同的结果?可能导致此问题的 UDF 有什么问题?我什至尝试更改数据库中的排序规则,但这不会影响函数的结果。

编辑:我在运行 sql 查询时管理了进入代码的步骤,发现方法 String.GetHashCode() 在 SQL Server 中运行时返回不同的值。无论如何,我假设任何类似字符集的问题都会消失,因为我在使用它之前对字符串进行了规范化。

编辑 2:鉴于 GetHashCode 似乎是问题所在,我在这里检查了它的代码:

How is GetHashCode() of C# string implemented?

并发现 .net 实现不同于运行 32 位 x 64 位。当我让我的控制台以 64 位模式运行时,输出结果与我在 SQL Server 中得到的结果相同。

最佳答案

一旦我设法调试了在 SQL Server 上运行的 UDF,我终于能够弄清楚我用来散列给定字符串的算法依赖于 .net 的 GetHashCode 方法。

至少对于 String 类,根据 this question , 原始实现在 32 位和 64 位平台上给出了不同的结果。

因此,当我在控制台应用程序上运行以测试功能时,它最终作为 32 位应用程序运行。但是安装的 SQL Server 是 64 位的,强制运行 GetHashCode 的其他实现。

通过强制控制台应用程序作为 64 位应用程序运行,我能够复制 SQL Server 的结果。

然后,只需调整参数即可使 32 位和 64 位平台给出相似(但不相等)的结果。

关于.net - 为什么函数在作为 SQL Server CLR UDF 执行时会输出不同的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40049790/

相关文章:

c# - 如何用Linq SqlQuery 构造MySqlParamter?

c# - 正则表达式分割线(csv 文件)

.net - Visual Studio 监 window 口查看对象的大小/内存占用

sql - 删除重复行

sql-server - SQL 71501 有未解析的程序集引用

c# - 如何避免在 EF .net 核心中多次查询一个复杂对象

c# - Azure Kubernetes .NET Core 应用程序到 Azure SQL 数据库间歇性错误 258

sql - 在 SQL Server 中将钱四舍五入到小数

linq - 如何在 SQL CLR 中添加 Linq 支持

c# - 如何在不升级到 MSDTC 的情况下在 SQLCLR 中使用 TransactionScope