Tsql T-SQL将unicode转换为表情符号

Tsql T-SQL将unicode转换为表情符号,tsql,unicode,emoji,Tsql,Unicode,Emoji,我有一个unicode序列,如下所示: \U0001F468\U0000200D\U0001F466 如何将T-SQL中的表情转换为相应的表情,所以我对这类事情几乎一无所知,但这是一种有趣的工作消遣,我希望能帮助你达到你需要的程度 正如您从unicode引用中看到的,该表情符号实际上是三个字符混合在一起的。第一个用于,第二个用于,第三个用于。零宽度连接符的作用是使其他两个字符在页面周围移动或选择文本时充当一个字符。您可以在任何不支持的文本编辑器(如SSMS)中看到这一点,在该编辑器中,您的光标将

我有一个unicode序列,如下所示:

\U0001F468\U0000200D\U0001F466


如何将T-SQL中的表情转换为相应的表情,所以我对这类事情几乎一无所知,但这是一种有趣的工作消遣,我希望能帮助你达到你需要的程度

正如您从unicode引用中看到的,该表情符号实际上是三个字符混合在一起的。第一个用于,第二个用于,第三个用于。零宽度连接符的作用是使其他两个字符在页面周围移动或选择文本时充当一个字符。您可以在任何不支持的文本编辑器(如SSMS)中看到这一点,在该编辑器中,您的光标将在男子和男孩字符之间“暂停”,以便按一次方向键

因此,为了回答您的问题,我假设您的所有unicode值都是三个序列,中间的一个是一个连接符,或者,如果不是这样,您可以从这里自己解决问题

从开始,您将看到SQL Server对补充字符的处理有点不完整。因此,您需要更改数据库排序规则或帮助它,即让它知道是否需要将unicode字符分解为两个
nchar
字符。因为我假设你的序列都是
Emoji-Joiner-Emoji
,这对我来说不是太大问题,但对你来说可能是

首先,我们需要将字符序列拆分为其组成部分,为此,我使用了一个基于以下内容的计数表字符串拆分函数:

使用此函数,我们可以将unicode序列拆分为3个部分,并手动将数据透视到3列中。按照上面链接的SO答案中的解释,因为两个emoji的
CodePoint
值(使用
convert(int,(convert(varbinary(max),replace(“”,'U','0x'),1))计算)
以下脚本的一部分)介于
65536
1114111
之间,我们需要找到高代理项和低代理项,但由于这对于零宽度合并器不是必需的,我们只需要二进制表示来传递到
nchar
函数(请注意,缺少到
int
的转换):

通过将所有这些
nchar
值连接在一起,我们最终得到了您表情符号的正确字符表示:

输出

表情符号
-----

这是实际的Unicode字符,还是Unicode代码的ASCII表示?SQL Server的哪个版本?还有,序列是保存在其他文本中还是作为单独的值保存在自己的列中?最终我选择用C#来完成,结果很好。
create function [dbo].[StringSplit]
(
    @str nvarchar(4000) = ' '               -- String to split.
    ,@delimiter as nvarchar(1) = ','        -- Delimiting value to split on.
    ,@num as int = null                     -- Which value to return.
)
returns @results table(ItemNumber int, Item nvarchar(4000))
as
begin
    declare @return nvarchar(4000);
    -- Handle null @str values
    select @str = case when len(isnull(@str,'')) = 0 then '' else @str end;
                    -- Start tally table with 10 rows.
    with n(n)   as (select n from (values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) n(n))
                    -- Select the same number of rows as characters in @str as incremental row numbers.
                    -- Cross joins increase exponentially to a max possible 10,000 rows to cover largest @str length.
        ,t(t)   as (select top (select len(@str) a) row_number() over (order by (select null)) from n n1,n n2,n n3,n n4)
                    -- Return the position of every value that follows the specified delimiter.
        ,s(s)   as (select 1 union all select t+1 from t where substring(@str,t,1) = @delimiter)
                    -- Return the start and length of every value, to use in the SUBSTRING function.
                    -- ISNULL/NULLIF combo handles the last value where there is no delimiter at the end of the string.
        ,l(s,l) as (select s,isnull(nullif(charindex(@delimiter,@str,s),0)-s,4000) from s)
    insert into @results
    select rn as ItemNumber
            ,Item
    from(select row_number() over(order by s) as rn
                ,substring(@str,s,l) as item
        from l
        ) a
    where rn = @num
        or @num is null;
    return;
end
declare @s nvarchar(50) = '\U0001F468\U0000200D\U0001F466';

select nchar(55232+(i1/1024)) + nchar(56320+(i1%1024))  -- MAN emoji
      +nchar(b2)                                        -- JOINER
      +nchar(55232+(i3/1024)) + nchar(56320+(i3%1024))  -- BOY emoji
      as Emoji
from(select convert(int,(convert(varbinary(max),replace(s1.Item,'U','0x'),1))) as i1
           ,convert(varbinary(max),replace(s2.Item,'U','0x'),1) as b2
           ,convert(int,(convert(varbinary(max),replace(s3.Item,'U','0x'),1))) as i3
     from stringsplit(@s,'\',2) as s1
         ,stringsplit(@s,'\',3) as s2
         ,stringsplit(@s,'\',4) as s3
    ) as a;