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

时间:2013-04-23 13:53:52

标签: sql sql-server-2008

我们有一个奇怪的问题。我们正在升级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记录了一个电话,但据我所知他们没有看到这个,他们也不能复制它(但我们不知道他们在什么情况下试图这样做),以及它的事实发生在我们的其他数据库/服务器上让我想知道它是不是一个模糊的设置,某处。

2 个答案:

答案 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个空格。所以你最后一个角色   是一个空间。