You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL Server中CLR Grapheme簇计数函数失效问题排查

问题描述

现有一段C#方法可正确统计包含组合字符的Grapheme Clusters(grapheme簇)数量,代码如下:

public static class StringExtensions
{
    public static SqlInt32 GetStrLength(this string input)
    {
        if (string.IsNullOrEmpty(input))
            return 0;

        return StringInfo.ParseCombiningCharacters(input).Length;
    }
}

将其封装为SQL Server可用的CLR函数后,代码如下:

public static class UserDefinedFunctions
{
    [SqlFunction(IsDeterministic = true, IsPrecise = true)]
    public static SqlInt32 GetStrLength(SqlString input)
    {
        if (input.IsNull)
            return 0;

        return StringInfo.ParseCombiningCharacters(input.Value).Length;
    }
}

该C#方法在非SQLCLR环境运行正常,但在SQL Server中使用CLR函数时计数结果错误,示例如下:

SQLCLR版本(错误)非SQLCLR版本(正确)
'👩🏻' -> 2'👩🏻' -> 1
'👨🏻‍❤️‍💋‍👩🏼' -> 9'👨🏻‍❤️‍💋‍👩🏼' -> 1

调用该CLR函数的SQL代码:

SELECT dbo.GetStringLength(body) FROM notes;

注册CLR的SQL代码:

EXEC sp_configure 'show advanced options' , 1;
RECONFIGURE;

EXEC sp_configure 'clr enable' ,1;
RECONFIGURE;

EXEC sp_configure 'clr strict security', 0;
RECONFIGURE;

CREATE ASSEMBLY StringUtils FROM 'C:\GraphemeClusters.dll' WITH PERMISSION_SET = SAFE;

CREATE FUNCTION dbo.GetStringLength(@input NVARCHAR(MAX))
RETURNS INT
AS EXTERNAL NAME StringUtils.UserDefinedFunctions.GetStrLength;
错误原因分析
  • .NET Runtime版本的Unicode支持差异:
    SQL Server的CLR集成默认使用.NET Framework(即使是SQL Server 2019及以后版本,默认仍采用.NET Framework),而.NET Framework的StringInfo.ParseCombiningCharacters基于较旧的Unicode标准(例如.NET Framework 4.8对应Unicode 11.0),无法识别零宽连接符(U+200D)连接的复杂emoji序列(如👨🏻‍❤️‍💋‍👩🏼),也无法正确处理部分新的组合字符簇。而非SQLCLR测试版本大概率使用的是.NET Core/.NET 5+,这些版本的StringInfo实现更新到了更高版本的Unicode标准,能正确识别这类复杂grapheme簇。

  • 组合字符的识别逻辑差异:
    对于带肤色修饰符的单个emoji(如👩🏻),.NET Framework的StringInfo未将基础emoji字符与肤色修饰符视为一个完整的grapheme簇,这是因为旧版本的Unicode分类规则未被StringInfo正确适配,而新版本的.NET Runtime修复了该问题。


内容的提问来源于stack exchange,提问作者MJDevelops

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 15:58:18