How to pass nvarchar (non-English) to CLR (C#) stored procedure?

喜夏-厌秋 提交于 2019-12-08 06:51:42

问题


Working in Visual Studio, I'm trying to pass an entire row to a CLR stored procedure using FOR XML RAW and a parameter of type SqlXml in C# code (with the intent of processing the row using XmlReader). The row contains nvarchar fields.

Everything works correctly when the nvarchar fields contain English/numeric/simple punctuation text, but when any of them contain Hebrew or Russian characters, these characters are turned into question marks. (The same for Russian-only text so not an RTL issue)

From prints in SQL code I've found that the xml created by XML RAW preserves the non-English characters - they are printed just fine. But when printing sqlXmlParameter.Value (or putting it in output string and printing that in sql) question marks are printed instead of the non-English characters. I've tried using an SqlString parameter and got the same result - the parameter looks fine in SQL, but changes when passed to CLR procedure.

I've also found that both T-SQL and C# use UTF-16 as default encoding, so this is really weird.

How can I preserve non-English characters when passing parameters to CLR, or attach encoding information to them?

Edit: This Question relates to the following: How to make SqlContext.Pipe.Send in SQLCLR stored proc work with unicode? As it turns out, the solution to the other question solved this issue as well. I'm not sure why, since the C# code in this case contained no non-English characters, but it did use string formatting with strings that could be non-English, so maybe some mix of encodings was caused because of how the constants in the string format were saved. Just my guess though. So in case someone runs into a related problem (despite my vague definition of it) you might want to try that.


回答1:


No example code has been provided (the C# or even the T-SQL to call the Stored Procedure) so it is hard to say for certain, but you are probably making a mistake in how you are calling the Stored Procedure. Most likely you are not prefixing the Unicode and XML literals with an N to keep them as Unicode. The following C# code and T-SQL show that SQLCLR does properly accept and display Unicode characters across all three datatypes: SqlString, SqlChars, and SqlXml (sample Hebrew and Russian text taken from your related Question):

C#

using System;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;

public class UnicodeTesting
{
    [Microsoft.SqlServer.Server.SqlProcedure]
    public static void PrintTest(SqlString StringParam, SqlChars CharsParam,
                                 SqlXml XmlParam)
    {
        SqlContext.Pipe.Send("Unicode test: blip");
        SqlContext.Pipe.Send("Unicode test: בליפ");
        SqlContext.Pipe.Send("Unicode test: Блип");

        SqlContext.Pipe.Send("StringParam: " + StringParam.Value);
        SqlContext.Pipe.Send("CharsParam: " + new String(CharsParam.Value));
        SqlContext.Pipe.Send("XmlParam: " + XmlParam.Value);
    }
}

T-SQL

EXEC dbo.PrintTest N'בליפ a',
                   N'בליפ b',
                   N'<test>בליפ c</test><test>Блип</test>';

Output (in "Messages" tab)

Unicode test: blip
Unicode test: בליפ
Unicode test: Блип
StringParam: בליפ a
CharsParam: בליפ b
XmlParam: <test>בליפ c</test><test>Блип</test>


来源:https://stackoverflow.com/questions/36915616/how-to-pass-nvarchar-non-english-to-clr-c-stored-procedure

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!