web-dev-qa-db-ja.com

SQL ServerデータベースでUTF-8照合を使用する方法は?

データベースをmysqlからSQL Server(politics)に移行しました。元のmysqlデータベースはUTF8を使用しています。

今私は読みます https://dba.stackexchange.com/questions/7346/sql-server-2005-2008-utf-8-collat​​ion-charset SQL Server 2008はutf8をサポートしていませんこれは冗談?

SQL Serverは、主にラテンエンコードされた複数のデータベースをホストします。移行されたデータベースはWeb公開を目的としているため、utf8エンコードを保持したいと思います。何かを見落としていたり​​、アプリケーションレベルでenc/decする必要がありますか?

71
Teson

番号!冗談ではありません。

こちらをご覧ください: http://msdn.Microsoft.com/en-us/library/ms186939.aspx

固定長、nchar、または可変長、nvarchar、Unicodeデータのいずれかであり、UNICODE UCS-2文字セットを使用する文字データ型。

また、こちら: http://en.wikipedia.org/wiki/UTF-16

古いUCS-2(2バイトのユニバーサル文字セット)は、1996年7月にUnicode標準のバージョン2.0でUTF-16に置き換えられた同様の文字エンコードです。

19
edze

UTF-8は文字セットではなく、エンコードです。 UTF-8の文字セットはUnicodeです。 Unicodeテキストを保存する場合は、nvarcharデータ型を使用します。

データベースがテキストを格納するためにUTF-8を使用する場合、エンコードされたUTF-8データとしてテキストを取得できず、デコードされたテキストとして取得します。

UTF-8でエンコードされたテキストをデータベースに簡単に保存できますが、テキストとして保存するのではなく、バイナリデータ(varbinary)として保存します。

21
Guffa

これは最終的にSQL Server 2019でサポートされるようです! SQL Server 2019-新着情報

BOLから:

UTF-8サポート

インポートまたはエクスポートエンコーディングとして、またはテキストレベルのデータベースレベルまたは列レベルの照合として広く使用されているUTF-8文字エンコーディングを完全にサポートします。 UTF-8はCHARおよびVARCHARデータ型で許可され、オブジェクトの照合をUTF8接尾辞を持つ照合に作成または変更するときに有効になります。

たとえば、LATIN1_GENERAL_100_CI_AS_SCからLATIN1_GENERAL_100_CI_AS_SC_UTF8。 UTF-8は、SQL Server 2012で導入された補助文字をサポートするWindows照合でのみ使用できます。NCHARおよびNVARCHARはUTF-16エンコードのみを許可し、変更されません。

この機能は、使用中の文字セットに応じて、ストレージを大幅に節約できます。たとえば、UTF-8対応照合を使用して、ASCII文字列を含む既存の列データ型をNCHAR(10)からCHAR(10)に変更すると、ストレージ要件がほぼ50%削減されます。これは、NCHAR(10)がストレージに22バイトを必要とするのに対し、CHAR(10)は同じUnicode文字列に12バイトを必要とするためです。

2019-05-14更新:

ドキュメントは現在更新されているようであり、セクション「 照合およびユニコードのサポート 」でMSSQL 2019で見られるオプションについて説明しています。

2019年7月24日更新:

Pedro Lopesによる記事 -Azure SQL DatabaseのUTF-8サポートの導入に関するマイクロソフトのシニアプログラムマネージャー

14
Bartosz X

Microsoft SQL Server 2016以降、UTF-8は bcpBULK_INSERT 、および OPENROWSET でサポートされていることに注意してください。

補遺2016-12-21:SQL Server 2016 SP1は、StandardおよびExpressを含むMS SQLのすべてのバージョンでUnicode圧縮(および以前のエンタープライズ専用機能のほとんど)を有効にするようになりました。これはUTF-8サポートと同じではありませんが、欧米のアルファベットのディスクスペースの削減を目標とする場合、同様の利点が得られます。

4
Charles Burns

T-SQLでUTF-8を処理する2つのUDF:

CREATE Function UcsToUtf8(@src nvarchar(MAX)) returns varchar(MAX) as
begin
    declare @res varchar(MAX)='', @pi char(8)='%[^'+char(0)+'-'+char(127)+']%', @i int, @j int
    select @i=patindex(@pi,@src collate Latin1_General_BIN)
    while @i>0
    begin
        select @j=unicode(substring(@src,@i,1))
        if @j<0x800     select @res=@res+left(@src,@i-1)+char((@j&1984)/64+192)+char((@j&63)+128)
        else            select @res=@res+left(@src,@i-1)+char((@j&61440)/4096+224)+char((@j&4032)/64+128)+char((@j&63)+128)
        select @src=substring(@src,@i+1,datalength(@src)-1), @i=patindex(@pi,@src collate Latin1_General_BIN)
    end
    select @res=@res+@src
    return @res
end

CREATE Function Utf8ToUcs(@src varchar(MAX)) returns nvarchar(MAX) as
begin
    declare @i int, @res nvarchar(MAX)=@src, @pi varchar(18)
    select @pi='%[à-ï][€-¿][€-¿]%',@i=patindex(@pi,@src collate Latin1_General_BIN)
    while @i>0 select @res=stuff(@res,@i,3,nchar(((ascii(substring(@src,@i,1))&31)*4096)+((ascii(substring(@src,@i+1,1))&63)*64)+(ascii(substring(@src,@i+2,1))&63))), @src=stuff(@src,@i,3,'.'), @i=patindex(@pi,@src collate Latin1_General_BIN)
    select @pi='%[Â-ß][€-¿]%',@i=patindex(@pi,@src collate Latin1_General_BIN)
    while @i>0 select @res=stuff(@res,@i,2,nchar(((ascii(substring(@src,@i,1))&31)*64)+(ascii(substring(@src,@i+1,1))&63))), @src=stuff(@src,@i,2,'.'),@i=patindex(@pi,@src collate Latin1_General_BIN)
    return @res
end
2
Xabi

実際、SQLCLR UDFを作成することでUTF8を使用しても問題はなく、Microsoftからコードをダウンロードできます。このリンクを確認してください: http://technet.Microsoft.com/en-us/library/ms160893(v = sql.90).aspx

1
Ronen Ariely
0
arnav