次のようなデータを含む nvarchar(4000) フィールドがあります。
D0B6D181D0B5D0B4D0BA35D0BC (cyrillic string)
E59EA0E78999E79B98E99499 (chinese string)
...
各文字は、データ シーケンス内の 2 バイトで表されます。T-SQLを使用してこのデータを文字列に変換する方法は?
次のようなデータを含む nvarchar(4000) フィールドがあります。
D0B6D181D0B5D0B4D0BA35D0BC (cyrillic string)
E59EA0E78999E79B98E99499 (chinese string)
...
各文字は、データ シーケンス内の 2 バイトで表されます。T-SQLを使用してこのデータを文字列に変換する方法は?
最初の例は、16 進数の文字列に変換され、SQL Server の nvarchar(4000) フィールドに格納された UTF8 でエンコードされたキリル文字テキストです。なんとも微妙な組み合わせです。奇妙なことに、SQL Server には、TSQL で UTF8 を nvarchar に変換するためのネイティブ サポートがありません。独自の DecodeUTF8 関数をロールすることも、以下の私のものを使用することもできます。
あなたの例:
select
Cyrillic = dbo.DecodeUTF8(convert(varbinary(max), '0x'+ 'D0B6D181D0B5D0B4D0BA35D0BC', 1))
, Chinese = dbo.DecodeUTF8(convert(varbinary(max), '0x'+ 'E59EA0E78999E79B98E99499', 1))
出力:
Cyrillic Chinese
жседк5м 垠牙盘错
TSQL用の私のUTF8デコーダー:
create function [dbo].[DecodeUTF8](@utf8 varchar(max)) returns nvarchar(max)
as
begin
declare @xml xml;
with e2(n) as (select top(16) 0 from (values(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) e(n))
, e3(n) as (select top(256) 0 from e2, e2 e)
, e4(n) as (select top(65536) 0 from e3, e3 e)
, e5(n) as (select top(power(2.,31)-1) row_number() over (order by(select 0)) from e4, e4 e)
, numbers(i) as (select top(datalength(@utf8)) row_number() over (order by(select 0)) from e5)
, x as (
select *
from numbers
cross apply (select byte = convert(tinyint, convert(binary(1), substring(@utf8, i, 1)))) c
cross apply (select n = floor(log(~(byte) * 2 + 1, 2)) - 1) d
cross apply (select bytes = case when n in (5,4,3) then 7 - n else 1 end) e
cross apply (select data = byte % power(2, n)) f
)
select @xml =
(
select nchar(case x.bytes
when 1 then x.data
when 2 then power(2, 6) * x.data + x2.data
when 3 then power(2, 6*2) * x.data + power(2, 6) * x2.data + x3.data
when 4 then power(2, 6*3) * x.data + power(2, 6*2) * x2.data + power(2, 6) * x3.data + x4.data
end)
from x
left join x x2 on x2.i = x.i + 1 and x.bytes > 1
left join x x3 on x3.i = x.i + 2 and x.bytes > 2
left join x x4 on x4.i = x.i + 3 and x.bytes > 3
where x.n <> 6
order by x.i
for xml path('')
);
return @xml.value('.', 'nvarchar(max)');
end
これを見てください
彼らはシングルバイトのコードポイントを実行しているように見えるので、少し変更する必要があるかもしれません