C# C语言中的字符编码与SQL

C# C语言中的字符编码与SQL,c#,sql-server,character-encoding,collation,C#,Sql Server,Character Encoding,Collation,我有一个sql: 从productcode=@code的产品中选择productid @code是一个参数,它的值是ABCÊ,但它与在visualstudio中调试它的ABC相匹配� 在快速手表里。该数据库具有Latin1_General_CI_作为排序规则。数据库中的字段类型为nvarchar50 那么,当我将包含productcode='ABC'的数据行与ABCÊ进行比较时,为什么会返回该数据行? 我在我的smss select 1中输入了这个,其中'ABC'='ABCÊ',但它没有返回1,

我有一个sql:

从productcode=@code的产品中选择productid

@code是一个参数,它的值是ABCÊ,但它与在visualstudio中调试它的ABC相匹配� 在快速手表里。该数据库具有Latin1_General_CI_作为排序规则。数据库中的字段类型为nvarchar50

那么,当我将包含productcode='ABC'的数据行与ABCÊ进行比较时,为什么会返回该数据行? 我在我的smss select 1中输入了这个,其中'ABC'='ABCÊ',但它没有返回1,而是:选择1,其中'ABC'='ABC' 那么它在我的代码中吗?使用utf或编码的东西

编辑c代码:

2015年6月15日编辑

正如@Oskar Sjöberg所建议的那样,缩小了问题的范围。它与数据库无关!因为它返回true:

test.csv包含:D1103SLÊ

记事本++:

因此,我仍然不明白它是如何相等的。

使用

COLLATE DATABASE_DEFAULT
如下

select productid from products where productcode COLLATE DATABASE_DEFAULT = @code

尝试使用SQL拉丁语通用语CP1通用语而不是对照拉丁语通用语

如果使用LINQ,可以使用文化比较

var result = from a in collection.Products
             select a.Productid
             where string.Equals(a.ProductCode, 'ABCÊ', StringComparison.Ordinal);

我尝试使用相同的排序规则、表和示例数据设置相同的场景,并运行以下代码:

var connection = new SqlConnection("connectionstringgoeshere");
connection.Open();
var command = new SqlCommand(@"SELECT ProductID FROM PRODUCTS WHERE (ProductCode = @name)", connection);
command.Parameters.AddWithValue("name", "ABCÊ");
var dataTable = new DataTable();
dataTable.Load(command.ExecuteReader());
Console.WriteLine(dataTable.Rows);  
它按预期返回零行,将代码中的ABCÊ更改为ABC将返回一行正确的数据

我认为这里还有另一个问题,但是您需要包含一个更完整但仍然是最小的代码、数据库模式和数据库数据示例

显然,\xCA在Mac上是一个不间断的空格,与Windows上的\xA0、ISO-Latin-1和HTML中的\xA0相同

因此,当使用UTF-8编码时,它只知道这是一个无意义的字符,可以跳过,因此字符串是相等的

using (StreamReader sr = new StreamReader("test.csv", ASCIIEncoding.UTF8))
{
    while (!sr.EndOfStream)
    {
        Console.WriteLine("D1103SL".Equals(sr.ReadLine()));
    }
}

当使用ascii时,它“看到”了Ê,当进行比较时,它返回false。

但它与在visual studio中调试它的ABC相匹配� 在快速手表里。这是什么意思?@code参数是nvarchar吗?对于Unicode文本,您需要指定N前缀以防止转换为varchar:N'ABCÊ'`请显示代码。这个当您尝试将文本从一个ASCII代码页转换为另一个ASCII代码页时出现,而不使用Unicode文本。很可能,参数的类型是varchar。还要确保在到达数据库命令之前不会发生损坏,例如使用错误的代码页读取ASCII输入我使用了comGetProd.Parameters.AddWithValuecode,ABCÊ;所以我没有指定sql类型。comGetProd是SQLCommands。请显示插入值的代码。此时会发生转换错误。还要注意,“ABCÊ”是一个varchar,而不是Unicode,必须进行转换。您需要输入N'ABCÊ'来输入nvarchar值。你的选择1。。。语句还比较了varchar,而不是nvarchar值,尽管这不会改变任何东西。您能否解释一下COLLATE DATABASE\u DEFAULT将如何/为什么解决这个问题?为什么这对Unicode nvarchar字段有帮助?您链接的文章实际上提到了nvarchar数据排序/比较的规则似乎是相同的,但实际上警告不要将排序规则混用。。。可能会严重影响您的性能或导致排序冲突错误。。。尤其是如果您使用的是较旧的SQL排序规则,OP对转换而不是比较有争议。无论如何,这与LINQ无关,而是与SQL有关。LINQ to EF可能会拒绝执行此查询,而L2S将在内存中加载整个表,然后尝试查找匹配的行抱歉,我不使用LINQ感谢您的时间和努力,我将看看是否可以在单独的小项目中复制它我已经做了一个类似的测试项目,但是当我像您一样硬编码字符串时,我没有吵架。当我从csv文件复制粘贴中读取完全相同的字符串时,我得到了1行,没有任何线索
var connection = new SqlConnection("connectionstringgoeshere");
connection.Open();
var command = new SqlCommand(@"SELECT ProductID FROM PRODUCTS WHERE (ProductCode = @name)", connection);
command.Parameters.AddWithValue("name", "ABCÊ");
var dataTable = new DataTable();
dataTable.Load(command.ExecuteReader());
Console.WriteLine(dataTable.Rows);  
using (StreamReader sr = new StreamReader("test.csv", ASCIIEncoding.UTF8))
{
    while (!sr.EndOfStream)
    {
        Console.WriteLine("D1103SL".Equals(sr.ReadLine()));
    }
}