如果列数据以数字开头,Like 操作在 nvarchar 列过滤器上不返回任何行

Posted

技术标签:

【中文标题】如果列数据以数字开头,Like 操作在 nvarchar 列过滤器上不返回任何行【英文标题】:Like operation returns no rows on nvarchar column filter if the column data start with numeric 【发布时间】:2012-04-17 22:27:27 【问题描述】:

我在 SQL Server 表中有nvarchar(50) 列,数据如下:

123abc
234abc
456abc

我的查询:

select * 
from table 
where col like '%abc'

预期结果:应返回所有行 实际结果:不返回任何行

如果列是 varchar,则工作正常,但如果类型是 nvarchar,则不返回任何行。

有什么想法吗?

【问题讨论】:

【参考方案1】:

您的数据末尾可能有空格。看看这个例子。

Declare @Temp Table(col nvarchar(50))

Insert Into @Temp(col) Values(N'123abc')
Insert Into @Temp(col) Values(N'456abc ')

Select * From @Temp Where Col Like '%abc'

当你运行上面的代码时,你只会得到 123 行,因为 456 行的末尾有一个空格。

当你运行下面显示的代码时,你会得到你期望的数据。

Declare @Temp Table(col nvarchar(50))

Insert Into @Temp(col) Values(N'123abc')
Insert Into @Temp(col) Values(N'456abc ')

Select * From @Temp Where rtrim(Col) Like '%abc'

根据在线书籍中有关 LIKE 的文档(强调我的): http://msdn.microsoft.com/en-us/library/ms179859.aspx

使用 LIKE 进行模式匹配

LIKE 支持 ASCII 模式匹配和 Unicode 模式匹配。当所有参数(match_expression、pattern 和 escape_character,如果存在)都是 ASCII 字符数据类型时,将执行 ASCII 模式匹配。如果任何一个参数是 Unicode 数据类型,则所有参数都将转换为 Unicode 并执行 Unicode 模式匹配。 当您将 Unicode 数据(nchar 或 nvarchar 数据类型)与 LIKE 一起使用时,尾随空格很重要;但是,对于非 Unicode 数据,尾随空格并不重要。 Unicode LIKE 与 ISO 标准兼容。 ASCII LIKE 与早期版本的 SQL Server 兼容。

【讨论】:

【参考方案2】:

对于nvarchar 类型,您可以像这样使用选择:-

select * from Table where ColumnName like N'%abc%'

【讨论】:

出于某种原因,这仅对我在 DELETE 查询中有效,将 N 放在 LIKE 之后,而不是其他没有 N 的答案。同样的额外空间情况。【参考方案3】:

您确定值的末尾没有空格吗?您可以这样做来删除空白:

select *
from yourTable
where rtrim(yourcolumn) like '%abc'

如果您不想同时使用RTRIMLIKE,您也可以使用:

Select * 
From yourTable 
Where charindex('abc', col) > 0

来自微软关于使用LIKE:

SQL Server 遵循 ANSI/ISO SQL-92 规范(第 8.2 节, , 一般规则 #3) 关于如何比较字符串 带空格。 ANSI 标准要求对字符进行填充 比较中使用的字符串,以便它们的长度在之前匹配 比较它们。填充直接影响 WHERE 的语义 和 HAVING 子句谓词和其他 Transact-SQL 字符串 比较。例如,Transact-SQL 考虑字符串 'abc' 和 'abc' 对于大多数比较操作来说是等价的。

此规则的唯一例外是 LIKE 谓词。当对 LIKE 谓词表达式的一侧具有一个带有尾随的值 空格,SQL Server 不会将两个值填充到相同的长度 在比较发生之前。因为LIKE的目的 根据定义,谓词是为了促进模式搜索而不是 比简单的字符串相等测试,这不违反该部分 前面提到的 ANSI SQL-92 规范。

如果你知道'abc'字符串的起始位置,那么你可以使用SUBSTRING:

Select *
From yourTable 
Where substring(Col, 4, 3) = 'abc'

但是你可以同时使用 charindex 和 substring 并且你不必担心空格:

select *
from yourTable
where substring(col, charindex('abc', col), 3) = 'abc'

【讨论】:

同意,但是如果类型是 varchar 就可以了。不使用 rtrim。有什么想法吗? 您可以使用 charindex,查看更新的答案至于使用 LIKE 看到链接support.microsoft.com/kb/316626 +1 根据反馈包含更多信息。您的 charindex 建议不等同于 rtrim 查询,因为如果搜索字符串位于数据中的任何位置,而不只是其末尾,charindex 将返回该行。【参考方案4】:

您的查询应该可以正常工作,但您也可以尝试。

SELECT * FROM TABLE WHERE (COL LIKE '%abc%')

如果'abc'部分后面有你看不到的字符。

【讨论】:

欢迎使用 ***:如果您发布代码、XML 或数据示例,在文本编辑器中突出显示这些行并单击“代码示例”按钮 ( ) 在编辑器工具栏上很好地格式化和语法突出显示它!【参考方案5】:

只是为了记录一些 ASCII 与 Unicode 的怪异之处:

-- ascii like
if 'Non rational ' like 'Non[ --]rational%'  print 'like' else  print 'not like'

-- unicode like
if N'Non rational ' like N'Non[ --]rational%' print 'like' else  print 'not like'

-- unicode like, trailing space removed
if N'Non rational' like N'Non[ --]rational%' print 'like' else  print 'not like'

-- unicode like, different wildcard
 if N'Non rational ' like N'Non_rational%' print 'like' else  print 'not like'

产生以下内容:

like
not like
not like
like

【讨论】:

【参考方案6】:

这会很好。你可以试试。

SELECT * 
FROM "table"
WHERE CAST("col" AS VARCHAR) LIKE '%abc'

【讨论】:

以上是关于如果列数据以数字开头,Like 操作在 nvarchar 列过滤器上不返回任何行的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 搜索列以给定单词开头

mysql查询语句中like 的用法

database 如何查询某个字段以某个字母开头的数据

like的模糊匹配

sql 字符串 排序

MySQL索引优化系列:索引失效