2017-05-05 2 views
3

を絵文字に変換を:T-SQL Unicodeは私はこのようなユニコードの配列を有し

\ U0001F468 \ U0000200D \ U0001F466

対応する絵文字にT-SQLでそれを変換し、絵文字を挿入する方法nvchar型の列では?

+0

は、この実際のUnicode文字、またはUnicodeコードのASCII表現ですか?どのバージョンのSQL Server? – alroc

+0

また、シーケンスは他のテキスト内に保持されているのか、それとも独自の列のスタンドアロン値として保持されていますか? – iamdave

+0

最終的に私はC#でそれをすることを選んだが、うまくいきました。 – XIII

答えて

2

私はこのタイプのものについてほとんど何も知りませんが、これは仕事からの楽しい気晴らしでした。

あなたのユニコード参照からわかるように、その絵文字は、実際には3つの文字がすべて一緒にマッシュされています。最初はMANであり、2番目はZERO WIDTH JOINERであり、3番目はBOYです。ゼロ幅結合ツールの効果は、ページの周りを移動したりテキストを選択したりするときに、他の2つの文字を1つのものとして動作させることです。これは、カーソルがMANとBOY文字の間で1つの方向キーの押下の間に「失速」するような、サポートしていないテキストエディタ(SSMSなど)で落ちることがわかります。

あなたの質問に答えるために、私はすべてのユニコード値が3つのシーケンスであり、中間のものがジョイナーであると仮定しています。そうでない場合は、作業することができますここからあなた自身で

this very informative Stack Overflow answerから始めると、SQL Serverに補完文字の不完全な処理が少しあることがわかります。その結果、データベースの照合順序を変更するか、またはユニコード文字を2つの文字に分解する必要があるかどうかを知らせることに役立ちます(nchar)。私はあなたのシーケンスがすべてEmoji-Joiner-Emojiであると仮定しているので、これは私にはあまり問題ではありませんが、あなたのためかもしれません。

はまず、私たちは私がJeff Moden'sに基づいて集計テーブルの文字列分割機能を使用していたためにその構成部分、にあなたの文字列を分割する必要があります。この機能を使用して

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 

、我々はUnicodeシーケンスを分割することができます3つの部分にデータを手動でピボットして3つの列にします。 (下記のスクリプトのconvert(int,(convert(varbinary(max),replace('<Your Uxxxxxxxxx unicode value>','U','0x'),1)))一部を使用して計算)2つの絵文字のCodePoint値は、我々は上位サロゲートとサロゲート低を見つける必要があり65536間と1114111あるので、SO上記のリンクの回答で説明に続いて、我々は終わる、一緒にすべてのこれらのnchar値を連結することにより

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; 

:しかし、これはゼロ幅ジョイナーのために必要がないので、私たちはただnchar機能(intへの変換の欠如に注意してください)に渡すバイナリ表現を必要とします正しいキャラクターであなたの絵文字のイオン:

出力

Emoji 
----- 
‍ 
関連する問題