我们有一个奇怪的问题。我们正在升级JDE,数据库模式正在发生变化 - 一些char列正在更改为nchar类型。但是,我们发现某些搜索不再有效,并且我们发现这在我们的SQL Server 2008数据库中是一致的:
在我测试的数据库中,ItemNumber列是一个char(25)并且具有不同的长度内容。
SELECT * FROM TableName WHERE ItemNumber LIKE '%S'
返回一堆行。但是,如果我们将列更改为nchar(25),那么查询现在只返回那些具有以“S”结尾的ItemNumber值的行且是25个字符长,所以似乎尾随空格是现在(可能正确地)考虑 - 如果您将通配符值更改为'%S',它会找到以“S”结尾的24个字符项目编号。
显然,这对我们来说是个问题,因为* S搜索不再适用于JDE,因为底层数据库调用现在需要修剪每个nchar列。这是一个已知问题,还是我们需要改变的地方?
其他信息 我们无法控制所使用的列类型,也无法更改生成的基础SQL,因为这是我们的ERP系统及其升级的一部分。我们已经与Oracle记录了一个电话,但据我所知他们没有看到这个,他们也不能复制它(但我们不知道他们在什么情况下试图这样做),以及它的事实发生在我们的其他数据库/服务器上让我想知道它是不是一个模糊的设置,某处。
答案 0 :(得分:6)
来自LIKE (Transact-SQL)的文档:
当您对LIKE使用Unicode数据(nchar或nvarchar数据类型)时,尾随空白很重要;但是,对于非Unicode数据,尾随空白并不重要。
我使用下表重现了您的问题:
DECLARE @t TABLE(x NCHAR(25));
INSERT @t SELECT N'nanaS';
SELECT x FROM @t WHERE x LIKE N'%S';
结果:
(0 row(s) affected)
但是,如果您使用NVARCHAR
,则不会出现此问题:
DECLARE @t TABLE(x NVARCHAR(25));
INSERT @t SELECT N'nanaS';
SELECT x FROM @t WHERE x LIKE N'%S';
结果:
x
-----
nanaS
然而,即使转换为NVARCHAR
子句中的WHERE
,原始表也未产生预期结果:
DECLARE @t TABLE(x NCHAR(25));
INSERT @t SELECT N'nanaS';
SELECT x FROM @t WHERE CONVERT(NVARCHAR(25),x) LIKE N'%S';
结果:
(0 row(s) affected)
因此,一个可能的解决方法是首先使用正确的数据类型(并且始终使用Unicode字符串N'properly'
作为前缀。如果无法使数据类型正确,则可以使用{{1 Aushin发布的解决方法,但也记住了HLGEM的评论。
答案 1 :(得分:3)
编辑:我在下面的解释是基于对您的问题的误读。虽然RTRIM可以工作,但我没有意识到你没有使用nvarchar而是使用char。亚伦和戈登提供了更好的见解。
SELECT * FROM TableName WHERE RTRIM(ItemNumber) LIKE N'%S'
这是因为对于nvarchar(25),它的最后一个字符 'S'是S.
对于nchar(25),'S'实际上是'S'+ 24个空格。所以你最后一个角色 是一个空间。