Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带通配符的类SQL在某些字母上返回错误结果_Sql_Sql Server_Tsql_Wildcard_Sql Like - Fatal编程技术网

带通配符的类SQL在某些字母上返回错误结果

带通配符的类SQL在某些字母上返回错误结果,sql,sql-server,tsql,wildcard,sql-like,Sql,Sql Server,Tsql,Wildcard,Sql Like,我不明白为什么在使用带有通配符的like关键字时会得到错误的结果。 为了便于讨论,我举了一个小例子来说明我的问题。 假设我们有一些桌子 CREATE TABLE TestingLike( [Name] VARCHAR(50) ) INSERT INTO TestingLike VALUES ('A'), ('AB'), ('L') ,('LJ') 现在当我使用这个搜索条件时 SELECT [Name] FROM TestingLike WHERE [Name] LIKE 'A%' SE

我不明白为什么在使用带有通配符的like关键字时会得到错误的结果。 为了便于讨论,我举了一个小例子来说明我的问题。 假设我们有一些桌子

CREATE TABLE TestingLike(
[Name] VARCHAR(50)  
)

INSERT INTO TestingLike VALUES ('A'), ('AB'), ('L') ,('LJ')
现在当我使用这个搜索条件时

SELECT [Name] FROM TestingLike WHERE [Name] LIKE 'A%'

SELECT [Name] FROM TestingLike WHERE [Name] LIKE 'L%'
第一个查询返回A,AB,而第二个查询只返回L。 奇怪的是,当使用临时表时,这种情况并没有发生

看在上帝的份上,有人能解释一下为什么会这样吗, 我做了一些研究,但没有找到答案,我正在使用SQL SERVER RC1 2017以及SQL SMS

谢谢你抽出时间

下面是执行计划的图片


我不能用拉丁语排序法复制,但如果我用克罗地亚语排序法,我可以复制,因为在克罗地亚语和其他一些斯拉夫语中,Lj是由两个字符组成的一个独立字母,而不是L后跟j。维基百科上讨论了这一点

如果tempdb的排序规则与显示问题的特定数据库的默认排序规则不同,则temp表/表变量不会遇到相同的问题

为在家玩的玩家提供完整/独立的复制脚本:

declare @TestingLike table(
[Name] VARCHAR(50) collate Croatian_CI_AI
)

INSERT INTO @TestingLike VALUES ('A'), ('AB'), ('L') ,('LJ')

SELECT [Name] FROM @TestingLike WHERE [Name] LIKE 'A%'

SELECT [Name] FROM @TestingLike WHERE [Name] LIKE 'L%'
你如何着手解决这个问题取决于你的总体目标。如果您的代码是按照克罗地亚的规则运行的,那么它工作正常。否则,您可能需要更改数据库的默认排序规则。但是,默认排序规则仅在创建列时适用。因此,您还必须更改每个现有列,以根据需要更改排序规则


1我在整个回答中使用克罗地亚语,但我的意思当然是指Lj是有向图的任何排序。

我打赌您的实际数据中有一个前导空格。。。正如您应该看到的那样,示例数据在这个例外情况下按预期工作。使用临时表时不发生这种情况是什么意思?你能在你的问题中提供一个例子吗?在创建临时表tablename、表变量@tablename或…,您的字面意思是不是不。。。?如果可能,希望复制此操作。请尝试在所有查询之间放置联合。我怀疑这是因为只有第一个查询正在运行。@GordonLinoff我的意思是,如果我使用temp table TestingLike执行相同的查询,我将得到预期的结果A、AB和L,LJ@Yollo您正在使用ASCII字符串。不要使用ASCII字符串,除非您完全确定只在英语区域设置中存储英语文本。将N前缀添加到字符串以将其转换为Unicode字符串,并使用*NAVRCHAR字段一个好的解决方案是使用nvarchar和Unicode字符串。也许您可以在查询中使用COLLATE的唯一无障碍解决方案是,在阅读您的评论后,我使用以下查询从TestingLike中选择[Name],其中[Name]如“L%”COLLATE Croatian_CI_AI@PanagiotisKanavos——我在回答中加入了一个完整的复制脚本。即使您将所有类型/文字都更改为nvarchar,也不会改变这样一个事实,即在此排序规则下,两个字符Lj被视为一个字母。@Yollo-需要修复什么?Lj不是L,后面跟着另一个字母。LIKE返回的结果是正确的-字符串后面不是L,后面是其他任何一组字母。@Yollo-如果您想要以Lj或L开头的字符串,那么我认为您应该使用像“Lj%”这样的[Name]或像“L%”这样的名称