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


83

データベースをmysqlからSQLServer(politics)に移行しました。これは、UTF8を使用した元のmysqlデータベースです。

今、私は/dba/7346/sql-server-2005-2008-utf-8-collat​​ion-charsetを読みました。SQLServer2008はutf8をサポートしていませんが、これは冗談ですか?

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


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

1
Java、JavaScript、DotNet、およびWindowsはすべて内部でUTF-16を使用しているため、Webサイトをこれらのいずれかでコーディングする場合は、UTF16への変換を保存していることに注意してください。
ベン

1
それが役立つ場合は、SQLServerが内部的にテキストをUTF-8として格納しているように見せかけることができます。取得すると、ドライバーはそれをUTF-16に変換し直します。SQLServerがテキストをUCS-32として格納しているように見せかけることもできます。内部ストレージ形式は、実装の詳細とは無関係です。重要なのは、データベースがユニコード文字データをUTF-16として返すことです(プログラミング環境に一致します)。
イアンボイド2016年

回答:


25

番号!冗談じゃありません。

ここを見てください:http//msdn.microsoft.com/en-us/library/ms186939.aspx

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

そしてここにも:http//en.wikipedia.org/wiki/UTF-16

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


OK。mssql-clientは外部のUTF8-worldに変換できますか?
Teson 2012

mssql-clientすべてになることができます。Java、.NET、C、PHPなど...クライアントとはどういう意味ですか?
edze 2012

1
クライアント:phpの下のsqlsrv拡張。ロバートは、ここにクリアテキストを置きます: social.msdn.microsoft.com/Forums/en/sqldriverforphp/thread/…、結果を評価して投稿します。
Teson 2012

2
こんにちは、遅れて申し訳ありませんが、担当者に感謝します。sqlsrv_connect(、array( "CharacterSet" => "UTF-8")..を使用して接続文字列を正常に動作させます。PDOは正常に機能しますか?
Teson

29

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

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

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


入力ありがとうございます。たとえばstackoverflow.com/questions/3951722/…を
Teson 2015

私はこれについて頭を悩ませることができません。「UTF8の文字セットはUnicodeです」?? utf8はUnicodeよりもはるかに広いわけではありません。UTF8 VS Unicodeで保存Dauðalognは異なる結果を与える:(EF BB BF)44 61 75 C3 B0 61 6C 6F 67 6E VS \ u0044 \ u0061 \ u0075 \ u00f0 \ u0061 \ u006c \ u006f \ u0067 \ u006e
Teson

2
@ user247245:UTF-8はエンコーディングであり、Unicodeは文字セットです。UTF-8は、Unicodeを保存する1つの方法です。Unicodeを表すために使用したのは、文字列リテラルで使用されるエスケープコードです。これは、通常、Unicodeをファイルとして表す方法ではありません。UTF-32は、Uncodeからファイル形式への直接の最も近い変換であり、各文字コードは32ビットの数値として保存されます。
グッファ2015

上記の例の3番目の文字がUTF8でC3B0として表され、Unicodeで単にF0として表される理由を説明してください。ご協力いただきありがとうございます。
Teson 2015

4
@ user247245:8〜11ビットの文字コード110xxxxx 10xxxxxxはUTF-8(xデータビットを表す)のようにエンコードされるため、文字コードF00001111000011ビット)は11000011 1011000000011最初のバイトと1100002番目のバイトの文字コードから)としてエンコードされます。)これはC3 B0
グッファ2015

24

これはSQLServer 2019でようやくサポートされるようです! SQL Server 2019-何が新しいのですか?

BOLから:

UTF-8サポート

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

例えば、LATIN1_GENERAL_100_CI_AS_SCLATIN1_GENERAL_100_CI_AS_SC_UTF8。UTF-8は、SQL Server 2012で導入された補助文字をサポートするWindows照合順序でのみ使用でき、UTF-16エンコードのみNCHARNVARCHAR許可し、変更されません。

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

2019-05-14更新:

ドキュメントは現在更新されているようで、MSSQL2019の「照合とUnicodeのサポート」セクションでオプションについて説明しています。

2019-07-24更新:

PedroLopesによる記事-AzureSQLデータベースのUTF-8サポートの導入に関するMicrosoftのシニアプログラムマネージャー


4

Microsoft SQL Serverの2016年のように、UTF-8がでサポートされていることに注意してくださいbcpBULK_INSERTOPENROWSET

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


しかし、OPENQUERYではありませんか?これが、OPENQUERYを使用してOracleからCLOBデータを移行する際に問題が発生する理由ではないかと思います。
GeoffDawdy19年

4

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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.