国际字符不适用于 SQL 服务器位置语句

本文关键字:服务器 位置 语句 SQL 适用于 字符 不适用 | 更新日期: 2023-09-27 18:37:23

我在本地数据库(SQL Server 2012)和生产数据库(Azure SQL)上都遇到了国际符号的数据编码问题

最初它发生在实体框架 7 和 Asp5-rc1 中,但我设法通过下面的简单 SQL 查询重现了它。

select Source 
from tag 
where Source like '%dzie%'

返回正确显示ń的行

杰恩.txt

select Source 
from tag 
where Source like '%dzień%' // additional 'ń' character at the end

返回空表

SQL和实体框架都返回看起来合法的值(带有ń),但是当我where语句中使用ń时,数据库不返回任何结果。

但是,当我执行以下代码时,管理工作室

update tag 
set Source = 'dzień.txt'
where Id = 'my id'

比此查询(与之前相同)

select Source 
from tag 
where Source like '%dzień%' // additional 'ń' character at the end

此时间返回一行,ń显示正确

杰恩.txt

我需要每个字符都使用where语句。我应该怎么做才能让它工作,尤其是在 Azure 上。

国际字符不适用于 SQL 服务器位置语句

试试这个;

_context.Tags.Where(tag => tag.Source.Contains("dzień.txt")) 

这应该会给 SQL 查询增加N'。在执行 LINQ 时运行 SQL Server Profiler,并查看它如何将 LINQ 转换为 SQL。

另一个选项是Equals运算符。这等效于 SQL =运算符。如果您认为有可能出现混合大小写名称,则可以使用CurrentCultureIgnoreCase

_context.Tags.Where(tag => tag.Source.Equals("dzień.txt", StringComparison.CurrentCulture)) 

请注意StringComparison.CurrentCulture

确保您Source字段上有索引。它将显著提高性能。

已更新以显示如何查询项目集合

这是 EF 的缺点之一。不能将 LINQ to SQL 用于非 SQL 类型的集合。基本上,SQL Server 中不存在的任何项集合都被视为 EF 未知。

所以这是一个选择;

public IENumerable<Tag> SearchTags(IENumerable<string> toBeSearchedTags)
{
    List<Tag> availableTags = new List<Tag>();
    foreach(var stag in toBeSearchedTags)
    {
       var availableTag = _context.Tags.FirstOrdefault(tag => tag.Source.Equals(stag, StringComparison.CurrentCulture)) 
       if(availableTag != null)
       {
          availableTags.Add(availableTag);
       }
    }
    return availableTags;
}

该问题是由于 ń 是 Unicode 字符,并且字符串文本 '%dzień%' 未标记为 Unicode 字符串。Unicode 字符串由 N'' 前缀标记。

若要在管理工作室中对此进行测试,只需运行

select 'dzień'

这导致dzien.如果将字符串更改为 Unicode,

select N'dzień'

你得到dzień.

请注意,N''表示法是 T-SQL 的一项功能,无需在探查器或其他日志记录中区分。

将查询更改为

select Source 
from tag 
where Source like N'%dzień%'

您应该看到所需的结果。

相关文章: