SQL Server char和nchar列的搜索方式不同



我们遇到一个奇怪的问题。我们正在升级JDE,数据库模式也在改变——一些char列变成了nchar类型。然而,我们发现一些搜索不再工作,我们发现这在我们的SQL Server 2008数据库中是一致的:

在我测试的DB中,ItemNumber列是一个字符(25),并且具有不同长度的内容。

SELECT * FROM TableName WHERE ItemNumber LIKE '%S'

返回一串行。但是,如果我们将列更改为nchar(25),则查询现在只返回那些具有以"S"结尾的ItemNumber值的行是25个字符长,因此似乎现在(可能正确地)考虑到尾随空格-如果您将通配符值更改为'%S '它会发现以"S"结尾的24个字符项号。

显然,这对我们来说是一个相当大的问题,因为*S搜索在JDE中不再工作,因为底层数据库调用现在需要修剪每个nchar列。这是一个已知的问题,还是我们需要改变的设置?

附加信息我们无法控制所使用的列类型,也无法更改生成的底层SQL,因为这是ERP系统及其升级的一部分。我们已经记录了一个与Oracle的呼叫,但据我所知,他们还没有看到这个,也不能复制它(但我们不知道在什么情况下他们试图这样做),加上它发生在我们其他数据库/服务器上的事实,使我怀疑这是不是一个模糊的设置,在某个地方。

来自LIKE (Transact-SQL)的文档:

当您使用Unicode数据(nchar或nvarchar数据类型)与LIKE时,尾随空格是重要的;但是,对于非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

然而,即使在WHERE子句中转换为NVARCHAR,原始表也没有产生期望的结果:

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')。如果你不能使数据类型正确,你可以使用由Aushin发布的RTRIM()解决方案,但也要记住HLGEM的评论。

编辑:我下面的解释是基于对你问题的误读。虽然RTRIM可以工作,但我没有意识到您使用的不是nvarchar而是char。Aaron和Gordon提供了更好的见解。

SELECT * FROM TableName WHERE RTRIM(ItemNumber) LIKE N'%S'  

这是因为对于nvarchar(25),的最后一个字符"S"是S

对于nchar(25), 'S'实际上是'S' + 24个空格。最后一个角色是空格

最新更新