我们可以阻止 SQL 服务器忽略值中的尾随空格吗?
Can we stop SQL Server EXCEPT from ignoring trailing spaces in values
我正在审核 2 个相同结构 table 中的值。 T-SQL EXCEPT
语句忽略了一个 table 中值的尾随 space,因此这些值不匹配,但也不会出现在我们的审核。
我已经尝试寻找方法来改变 SQL 比较列的方式。我做了类似的事情以确保它区分大小写,但找不到可以使其在字段值中包含白色 space/padding 的内容。
示例数据在 MyTable
中的值为 "Product Name ",而 RemoteTable
中的值为 "Product Name".
为了快速重现,这里是我现在所做的精简版:
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
这个目前returns没有结果,说明数值是一样的。但是第二个table中的值最后有一个space。
我希望得到 "Product Name"
的结果
当我需要比较区分大小写的东西时,我可以添加
COLLATE SQL_Latin1_General_CP1_CS_AS
是否有类似的东西会因为空白 space 而显示不同的值?
The ANSI standard requires padding for the character strings used in comparisons so that their lengths match before comparing them. The padding directly affects the semantics of WHERE and HAVING clause predicates and other Transact-SQL string comparisons. For example, Transact-SQL considers the strings 'abc' and 'abc ' to be equivalent for most comparison operations.
此行为是有意的。
您可以使用较慢的方法来实现您想要的:
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
方法会给出 'wrong' 结果)
这是旧的,已经回答了,但由于在 JOIN 条件下进行比较,我也在努力解决这个问题。虽然 SQL 服务器确实会忽略尾随 space,但它不会忽略前导 space。因此,对于我的 JOIN 条件,我比较了向前和向后(使用反向函数),这给了我一组更准确的结果。
在下面的示例中,我希望一个 table 中尾随 space 的行仅匹配 JOINed table 中尾随 space 的行。 REVERSE 函数对此有所帮助。
DECLARE @DbData AS TABLE (
Id INT,
StartDate DATETIME,
OrgName VARCHAR(100)
)
DECLARE @IncomingData AS TABLE (
Id INT,
StartDate DATETIME,
OrgName VARCHAR(100)
)
INSERT INTO @DbData (Id, StartDate, OrgName)
SELECT 1, CAST('1 Jan 2022' AS DATE), 'Test ' UNION ALL
SELECT 2, CAST('1 Jan 2022' AS DATE), 'Test' UNION ALL
SELECT 3, CAST('1 Jan 2022' AS DATE), 'Other Test' UNION ALL
SELECT 4, CAST('1 Jan 2022' AS DATE), 'Other Test '
INSERT INTO @IncomingData (Id, StartDate, OrgName)
SELECT 1, CAST('1 Jan 2022' AS DATE), 'Test ' UNION ALL
SELECT 2, CAST('1 Jan 2022' AS DATE), 'Test' UNION ALL
SELECT 3, CAST('1 Jan 2022' AS DATE), 'Other Test'
SELECT '~' + dd.OrgName + '~', '~' + id.OrgName + '~', *
FROM @DbData dd
JOIN @IncomingData id ON id.StartDate = dd.StartDate
AND dd.OrgName = id.OrgName
AND REVERSE(dd.OrgName) = REVERSE(id.OrgName) -- Try the query with and without this line to see the difference it makes
我正在审核 2 个相同结构 table 中的值。 T-SQL EXCEPT
语句忽略了一个 table 中值的尾随 space,因此这些值不匹配,但也不会出现在我们的审核。
我已经尝试寻找方法来改变 SQL 比较列的方式。我做了类似的事情以确保它区分大小写,但找不到可以使其在字段值中包含白色 space/padding 的内容。
示例数据在 MyTable
中的值为 "Product Name ",而 RemoteTable
中的值为 "Product Name".
为了快速重现,这里是我现在所做的精简版:
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
这个目前returns没有结果,说明数值是一样的。但是第二个table中的值最后有一个space。
我希望得到 "Product Name"
的结果当我需要比较区分大小写的东西时,我可以添加
COLLATE SQL_Latin1_General_CP1_CS_AS
是否有类似的东西会因为空白 space 而显示不同的值?
The ANSI standard requires padding for the character strings used in comparisons so that their lengths match before comparing them. The padding directly affects the semantics of WHERE and HAVING clause predicates and other Transact-SQL string comparisons. For example, Transact-SQL considers the strings 'abc' and 'abc ' to be equivalent for most comparison operations.
此行为是有意的。
您可以使用较慢的方法来实现您想要的:
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
方法会给出 'wrong' 结果)
这是旧的,已经回答了,但由于在 JOIN 条件下进行比较,我也在努力解决这个问题。虽然 SQL 服务器确实会忽略尾随 space,但它不会忽略前导 space。因此,对于我的 JOIN 条件,我比较了向前和向后(使用反向函数),这给了我一组更准确的结果。
在下面的示例中,我希望一个 table 中尾随 space 的行仅匹配 JOINed table 中尾随 space 的行。 REVERSE 函数对此有所帮助。
DECLARE @DbData AS TABLE (
Id INT,
StartDate DATETIME,
OrgName VARCHAR(100)
)
DECLARE @IncomingData AS TABLE (
Id INT,
StartDate DATETIME,
OrgName VARCHAR(100)
)
INSERT INTO @DbData (Id, StartDate, OrgName)
SELECT 1, CAST('1 Jan 2022' AS DATE), 'Test ' UNION ALL
SELECT 2, CAST('1 Jan 2022' AS DATE), 'Test' UNION ALL
SELECT 3, CAST('1 Jan 2022' AS DATE), 'Other Test' UNION ALL
SELECT 4, CAST('1 Jan 2022' AS DATE), 'Other Test '
INSERT INTO @IncomingData (Id, StartDate, OrgName)
SELECT 1, CAST('1 Jan 2022' AS DATE), 'Test ' UNION ALL
SELECT 2, CAST('1 Jan 2022' AS DATE), 'Test' UNION ALL
SELECT 3, CAST('1 Jan 2022' AS DATE), 'Other Test'
SELECT '~' + dd.OrgName + '~', '~' + id.OrgName + '~', *
FROM @DbData dd
JOIN @IncomingData id ON id.StartDate = dd.StartDate
AND dd.OrgName = id.OrgName
AND REVERSE(dd.OrgName) = REVERSE(id.OrgName) -- Try the query with and without this line to see the difference it makes