SQL Server 是否在查询时自动修剪 nvarchar 字段?

问题描述 投票:0回答:3

我有这个疑问:

select '[' + p.Firstname + ']' from Person p
where p.Firstname = 'Johanne'

在表中,我有多个人有这个名字,有些人的值上有尾随空格(值插入错误,将被纠正)。

为什么这个查询会给我带来这个结果(我插入了括号来可视化空格):

[Johanne]
[Johanne ]
[Johanne ]
[Johanne]

这是一个配置问题吗?真正的查询来自实体框架 6,但本示例也这样做。我该如何预防?

谢谢!

编辑:我可以使用 EF6 和

System.Data.Entity.SqlServer.SqlFunctions.DataLength
方法使其工作,如下所示:

ctx.Person.FirstOrDefault(p => p.FirstName == "Johanne" && SqlFunctions.DataLength(p.FirstName) == "Johanne".Length);
t-sql entity-framework-6
3个回答
6
投票

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 规范的部分。

请参阅:https://learn.microsoft.com/en-us/sql/t-sql/language-elements/string-comparison-assignment?view=sql-server-ver16

(最初供参考:https://support.microsoft.com/en-us/topic/inf-how-sql-server-compares-strings-with-trailing-spaces-b62b1a2d-27d3-4260-216d-a605719003b0


2
投票

我不确定在 EF 中,但在 TSQL 中我使用 DataLength

数据长度

DataLength 将返回包括尾随空格的长度
Len 将返回不包括尾随空格的长度

and DataLength(p.Firstname) = Len('Johanne')  

2
投票

您可以在 Sql 中创建一个新视图并将该视图映射回 EF 对象。视图可以包含字段的长度,在使用 DataLength 的选择中,您知道要匹配,然后在使用 EF 时可以在 where 子句中对其进行过滤。 或者,您可以创建一个 Sql 存储过程,使用不带通配符的 LIKE 进行比较(这会产生所需的结果),并将其映射回您的代码,并在 EF 的Where 语句中调用它。


使用视图

Create View MyCustomView
AS
SELECT [column1,column2,etc], DATALENGTH(FirstName) AS FirstNameLength
FROM Person
GO

那么你的 EF 将是:

Persons.Where(p => p.FirstNameLength == "Johanne".Length && p.FirstName == "Johanne");

使用存储过程

CREATE PROCEDURE [dbo].[GetPersons]
firstName int = null
AS
BEGIN
SET NOCOUNT ON;
select [your fields here]
from persons
where FirstName like @firstName
END

在 C# 中确保您的映射正确,然后

this.Database.SqlQuery<Person>("GetPersons","Johanne");

EF6还支持在执行之前直接编辑DbContext中的sql。您可以开发一些自定义代码,在特定情况下用 like 替换 =,但在执行此操作之前先尝试上述内容可能更容易。

© www.soinside.com 2019 - 2024. All rights reserved.