2016-08-24 7 views
1

私は、GoogleまたはSOに何も見つからなかったため、問題が整理されています。SQL Server UDF SQLCLRコールで文字が疑問符に変換される

SQL Serverでは、私はスカラー関数(dbo.MySqlStringFunctionと呼ぶ)を持っています。 この関数の機能は、C#で記述されたユーティリティを呼び出してASP.Netビューを呼び出し、そのHTMLをSqlStringとして返します。

SQL Server内の関数定義がされています。単純化C#のコードがある

RETURNS [nvarchar](max) WITH EXECUTE AS CALLER 
AS EXTERNAL NAME [Utils.UserDefinedFunctions].[MySqlStringFunction] 

var request = (HttpWebRequest)WebRequest.Create("www.mydomain.com"); 

using (var response = (HttpWebResponse)request.GetResponse()) 
using (var stream = response.GetResponseStream()) 
{ 
    using (var streamReader = new StreamReader(stream, Encoding.UTF8) 
    { 
     return new SqlString(streamReader.ReadToEnd()); 
    } 
} 

私はコンソールアプリにC#のコードを入れて、それを実行すると、私は正確にすべてを取得それがあるべきであるように。

ブラウザで直接URLにアクセスすると、ブラウザのURLに正確に表示されます。

ただし、SELECT MySqlStringFunction()を実行すると、™、§、¤などの文字はそれぞれ2〜3個の疑問符で表示されます。

return new SqlString(..)とSQL関数の間に、何かがうまくいくという値を返すように見えます。しかし、私はそれが何であるかについて迷っています。

答えて

2

問題がreturnの場所だったようです。現在のコード(質問に表示されています)は、3つのブロックのうちの1つで返されます。その1つは読み込まれるUTF-8ストリームです。これはおそらく、SQLCLRがメインのSQL Serverメモリから分離されたメモリであり、通常はストリームを経由して返すことができないため、混乱します。最初に開いているストリームを閉じ、usingブロックをDispose()と呼ぶことをお勧めします。したがって:

  1. は、最も内側のusingインサイド最初using(すなわちstring _TempReturn = String.Empty;
  2. 上記の文字列を作成してreturnを置き換える:最後using閉じ括弧の下_TempReturn = streamReader.ReadToEnd();
  3. 、追加:return new SqlString(_TempReturn);

古い回答、nで削除されます耳の未来

問題は、WebページとSQL Serverのエンコードの違いです。 WebページにはEncoding.UTF8が使用されています(これは、UTF-8が最も一般的なエンコーディングです)、SQL Server(一般的に.NETとWindows)はUTF-16 Little Endianです。 UTF-8は1バイトあたり1,2,3バイトのマルチバイトエンコーディングですが、UTF-16は常に2バイトです(つまり、よく、補助文字は4バイトですが、これは2バイト値のペアであるためです)。

ストリームを戻す前に、またはストリームを戻すときに、エンコーディングをUTF-16リトルエンディアンに変換する必要があります。また、UTF-16リトルエンディアンは.NETでUnicodeエンコーディング、Big Endian Unicodeは「UTF-16ビッグエンディアン」を参照しています。したがって、Unicodeエンコーディングに変換します。

または、逆の場合があります。ウェブページがUTF-8でない場合は、StreamReaderで間違って宣言している可能性があります。これが当てはまる場合は、StreamReaderコンストラクタで正しいエンコーディングを指定する必要があります。

+0

ビューで '@ Response.Charset'呼び出しを使用して、実際にutf-8であることを確認しました。 StreamReaderを呼び出した後にブレークポイントを置くと、文字が正しく表示されます。また、テキストはデータベース内の別の場所に正しく格納されます。また、Unicodeエンコーディングに変換することによって、どういう意味ですか?アプリケーションでも、このCLRアセンブリでのみ使用できますか? – Bardicer

+0

あなたが今何を言っているのか分かりません。私はStreamReaderの 'Encoding.Unicode'と' Encoding.BigEndianUnicode'オプションを持っていますが、 "Encoding.Unicode"を使うべきです。 "Little Endian Unicode"の.Net用語です。 – Bardicer

+0

@Bardicerなぜ私たちは ' SqlString'が問題になるのを防ぎます(サーバーの設定がSQL Serverと異なる場合)。 'return'のすぐ上に、' throw new Exception(streamReader.ReadToEnd()); 'を入れて、エラーメッセージに表示される文字を確認できますか?別のテストでは 'SqlChars'を代わりに返すことになります。その場合、新しいSqlChars(streamReader.ReadToEnd()。ToCharArray()); ' –

関連する問題