Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.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
Tsql SQL Server varchar不等式-撇号产生奇怪的结果_Tsql_Sql Server 2012 - Fatal编程技术网

Tsql SQL Server varchar不等式-撇号产生奇怪的结果

Tsql SQL Server varchar不等式-撇号产生奇怪的结果,tsql,sql-server-2012,Tsql,Sql Server 2012,使用SQL Server 2012 下面的查询与我公司代码中使用的查询类似。“名称”列为nvarchar100类型: select * from foo where name >= 'papa d''s' and name < 'papa d''szzzzzz' 这会产生一些意想不到的结果。除了返回name='papa d's pizza inc'的任何记录外,它还返回name='papa ds pizza inc'的记录。注意第二个结果中缺少的撇号 现在来看这两个查询

使用SQL Server 2012

下面的查询与我公司代码中使用的查询类似。“名称”列为nvarchar100类型:

select * 
from foo
where name >= 'papa d''s' 
    and name < 'papa d''szzzzzz'
这会产生一些意想不到的结果。除了返回name='papa d's pizza inc'的任何记录外,它还返回name='papa ds pizza inc'的记录。注意第二个结果中缺少的撇号

现在来看这两个查询:

select 1 where 'papa ds pizza inc' >= 'papa d''s'
GO
select 1 where 'papa ds pizza inc' < 'papa d''szzzzzz'
只有第一个查询返回1,这意味着第一个查询中的AND条件应该失败

有人能告诉我这里发生了什么事吗


如果您可以描述为什么任何人都会以这种方式进行查询,而不是使用带有通配符的LIKE子句,那么您将获得额外的积分,假设注入受到其他验证的阻碍。

问题与您的名称列是双字节字符串nvarchar,而字符串文本是单字节字符串char/varchar有关。类似“foobar”的SQL字符串文字是单字节字符串char/varchar。要使其成为双字节字符串nchar/nvarchar,需要在其前面加上N:N'foobar'是双字节字符串

我认为您发现了一个SQL Server错误。您可以通过Microsoft Connect在上报告,但我不会对他们修复它屏住呼吸

我使用的是一个普通的SQL Server 2012安装,它的默认排序规则是SQL\u Latin1\u General\u CP1\u CI\u AS

使用单字节varchar字符串执行此查询:

将数据类型更改为双字节nvarchar

如果我们采用正确工作的单字节版本,并将文本转换为双字节文本:

declare @name varchar(100) = 'papa ds pizza inc'
select 'gt' where @name >= N'papa d''s'
UNION
select 'lt' where @name <  N'papa d''szzzzzz'

您确定WHERE子句中没有其他部分导致返回意外的行吗?如果您发布完整的查询可能会有所帮助。这就是完整的查询-我只更改了表/列名。编辑:对于上下文,名称“papa ds”通常由搜索字段提供。C为查询追加zz。但在我对这个问题的测试中,我直接在SSMS中运行了查询,如图所示。不确定,但您可以尝试对整个字符串使用双引号。
gt
declare @name nvarchar(100) = N'papa ds pizza inc'
select 'gt' where @name >= 'papa d''s'
UNION
select 'lt' where @name <  'papa d''szzzzzz'
gt
lt
declare @name varchar(100) = 'papa ds pizza inc'
select 'gt' where @name >= N'papa d''s'
UNION
select 'lt' where @name <  N'papa d''szzzzzz'
gt
lt