我们可以阻止 SQL Server 除了忽略值中的尾随空格吗

Posted

技术标签:

【中文标题】我们可以阻止 SQL Server 除了忽略值中的尾随空格吗【英文标题】:Can we stop SQL Server EXCEPT from ignoring trailing spaces in values 【发布时间】:2019-04-15 14:51:32 【问题描述】:

我正在审核 2 个相同结构表中的值。 T-SQL EXCEPT 语句忽略了一个表中值的尾随空格,因此这些值不匹配,但也不会出现在我们的审核中。

我尝试寻找改变 SQL 比较列的方式的方法。我做了类似的事情来确保它区分大小写,但找不到可以让它在字段值中包含空格/填充的东西。

示例数据将MyTable 中的值作为“产品名称”,而RemoteTable 的值将是“产品名称”。

为了快速重现,这里是我现在正在做的一个精简版:

DECLARE @SampleLocal TABLE(ProductName varchar(50))
DECLARE @RemoteTable TABLE(ProductName varchar(50))

INSERT INTO @SampleLocal (ProductName) VALUES ('Product Name')
INSERT INTO @RemoteTable (ProductName) VALUES ('Product Name ')

SELECT ProductName COLLATE SQL_Latin1_General_CP1_CS_AS ProductName  
FROM @SampleLocal

EXCEPT

SELECT ProductName COLLATE SQL_Latin1_General_CP1_CS_AS ProductName  
FROM @RemoteTable

这目前没有返回任何结果,表明值是相同的。但是第二个表中的值最后有一个空格。

我希望得到一个包含“产品名称”的结果

当我需要比较区分大小写的东西时,我可以添加

COLLATE SQL_Latin1_General_CP1_CS_AS

是否有类似的东西会因为空格而显示值不同?

【问题讨论】:

【参考方案1】:

根据这篇文章(https://support.microsoft.com/en-us/help/316626/inf-how-sql-server-compares-strings-with-trailing-spaces):

ANSI 标准要求对比较中使用的字符串进行填充,以便它们的长度在比较之前匹配。填充直接影响 WHERE 和 HAVING 子句谓词的语义以及其他 Transact-SQL 字符串比较。例如,对于大多数比较操作,Transact-SQL 认为字符串 'abc' 和 'abc' 是等效的。

这种行为是有意的。

您可以使用较慢的方法来实现您想要的:

SELECT innerItems.ProductName
FROM
(
    SELECT DATALENGTH(ProductName) as realLength, ProductName  COLLATE SQL_Latin1_General_CP1_CS_AS as ProductName 
    FROM @SampleLocal
    EXCEPT
    SELECT DATALENGTH(ProductName) as realLength, ProductName  COLLATE SQL_Latin1_General_CP1_CS_AS as ProductName
    FROM @RemoteTable
) innerItems

将值和实际长度进行比较可以发挥作用。 (在这种情况下,len 方法会给出“错误”的结果)

【讨论】:

感谢@akos.pinter,这有助于取得差异。这并不像我希望的那么容易,如果我有 80 个字段,我需要有 80 个数据长度列,但它确实解决了我的问题。

以上是关于我们可以阻止 SQL Server 除了忽略值中的尾随空格吗的主要内容,如果未能解决你的问题,请参考以下文章

将图像上传到 sql server 上的 varbinary 字段时,file_get_contents 值中的“附近语法不正确”

SQL Server阻止保存修改表结构的解决方法

SQL Server统计信息简介

如何在SQL Server中选择特定日期的行,忽略时间。

获取 Sql-Server 中逗号分隔值中未分组列的详细信息

SQL Server 数据库项目比较架构忽略同一表中的字段序列