【问题标题】:Select statement returns nothing when column collation SQL_Latin1_General_CP1_CI_AS in T-sql当 T-sql 中的列排序 SQL_Latin1_General_CP1_CI_AS 时,Select 语句不返回任何内容
【发布时间】:2015-03-17 04:10:59
【问题描述】:

我有一个选择语句如下:

SELECT Veri from tblTest 
where  CAST(Veri COLLATE SQL_Latin1_General_CP1_CI_AS as varchar(10))=
 CAST('БHО' COLLATE SQL_Latin1_General_CP1_CI_AS as varchar(10))

Veri 具有SQL_Latin1_General_CP1_CI_AS 类型的排序规则。 有一行Veri 等于БHО。但是,select 语句不返回任何内容。 表 tblTest 的排序规则也是SQL_Latin1_General_CP1_CI_AS。 我做错了什么?

编辑:Veri 列的列定义如下:

CONDENSED_TYPE: nvarchar(50) TABLE_SCHEMA:dbo TABLE_NAME:tblTest COLUMN_NAME:验证 ORDINAL_POSITION: 2 COLUMN_DEFAULT:空 IS_NULLABLE:否 DATA_TYPE:nvarchar CHARACTER_MAXIMUM_LENGTH:50 CHARACTER_OCTET_LENGTH:100 NUMERIC_PRECISION:NULL NUMERIC_PRECISION_RADIX:空 NUMERIC_SCALE:空 DATETIME_PRECISION:空 CHARACTER_SET_CATALOG:空 CHARACTER_SET_SCHEMA:空 COLLATION_NAME:SQL_Latin1_General_CP1_CI_AS CHARACTER_SET_NAME:UNICODE COLLATION_CATALOG:空 DOMAIN_SCHEMA:空 DOMAIN_NAME:空

【问题讨论】:

  • Latin1 不只包括英文字母 + 重音(德语、法语、瑞典语等)字母吗?
  • @user1365888,这个选择返回什么?选择 CAST(Veri COLLATE SQL_Latin1_General_CP1_CI_AS as varchar(10)) 作为 VeriCol,CAST('БHО' COLLATE SQL_Latin1_General_CP1_CI_AS as varchar(10)) 作为 SomeVal FROM tblTest
  • 有没有用问号代替的字符? (据我所知,这些字符(例如Б)实际上不是拉丁语)。
  • @EduardUta 此选择不返回任何行。

标签: sql-server collation string-comparison


【解决方案1】:

在 T/SQL 中,字符串常量 'БHО' 是一个 ANSI 字符串,并且 'Б' 不可用,因此您将得到 @EduardUta 查询的问号。您需要使用 Unicode 字符串,对字符串常量和 nvarchar 使用 N 前缀。试试这个;

SELECT Veri from tblTest 
where  CAST(Veri COLLATE SQL_Latin1_General_CP1_CI_AS as nvarchar(10)) =
CAST(N'БHО' COLLATE SQL_Latin1_General_CP1_CI_AS as nvarchar(10))

您可以删除 COLLATE 指令 - 取决于您的架构。

您可以做的另一件事是逐个字符地检查字符串以查看每个字符实际上是什么。例如,在您的字符串 'БHО' 中,它可能看起来像西里尔大写字母 Be 后面跟着英文字母 H 和 O,但事实并非如此,这就是您没有得到匹配的原因。

declare @s nvarchar(100) = N'БНО'
declare @i int = 0

while (@i <= len(@s))
begin
    print substring(@s, @i, 1) + N' - 0x' + convert(varchar(8), convert(varbinary(4), unicode(substring(@s, @i, 1))), 2)
    set @i = @i + 1
end

尝试在上面的字符串 N'БНО' 中输入 Н 和 О 并再次运行 - 您将分别看到 0x48 和 0x4F。

希望这会有所帮助,

里斯

【讨论】:

  • 我试过你的语句(有和没有 COLLATE),仍然没有返回行。
  • 如果我从表格单元格中复制 'БНО' 并粘贴到这个 sql 语句中,从 tblTest 中选择 Veri where CAST(Veri COLLATE SQL_Latin1_General_CP1_CI_AS as nvarchar(10)) = CAST(N'БНО' COLLATE SQL_Latin1_General_CP1_CI_AS as nvarchar(10)) 它工作并返回该行。但是在同一个 sql 语句中,如果我删除 H 然后自己键入那个 H 那么它不会返回任何行。
  • @user1365888 - 这是因为 Н 不是 H 并且 О 不是 O :) 请参阅上面的编辑以显示字符串中字符的 Unicode 代码。
  • 是的,你是对的。但是我仍然不知道如何构造一个 SQL 语句,以便我可以根据列“Veri”查询我的表。我有一个搜索表单,需要此查询来返回搜索结果。
  • @user1365888 - 现在这是一个非常不同的问题。根据您的应用程序层(WinForm、Web 应用程序等),您将需要调查输入 Unicode 字符以传递给 SQL 查询。如果我在您的 SQL 方面为您提供了帮助,如果您能接受我的回答,我将不胜感激。
猜你喜欢
  • 2016-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-10
  • 2011-05-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多