1

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

我尝试寻找改变 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

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

4

1 回答 1

4

根据这篇文章(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在这种情况下,该方法会给出“错误”的结果)

于 2019-04-15T16:25:53.180 回答