Sql server SQL concat/+;操作员行为异常?

Sql server SQL concat/+;操作员行为异常?,sql-server,tsql,Sql Server,Tsql,基本上,为了解释我的情况,我有一个程序,用户可以选择字母数字的代码。这些代码作为数据类型char存储在我的SQL数据库中 当他们选择所有想要的代码时,程序会发送一些参数(代码就是其中之一)。代码串在一起,看起来像这样: “、01、1、A3”等,用逗号分隔代码。我前面有逗号,但将逗号改为后面不会改变任何东西 @reasonCode变量是串在一起的原因代码 在我的where条款中,我有一个声明: (@reasonCode = 'ALL') OR ((@reasonCode <> 'AL

基本上,为了解释我的情况,我有一个程序,用户可以选择字母数字的代码。这些代码作为数据类型char存储在我的SQL数据库中

当他们选择所有想要的代码时,程序会发送一些参数(代码就是其中之一)。代码串在一起,看起来像这样:

“、01、1、A3”等,用逗号分隔代码。我前面有逗号,但将逗号改为后面不会改变任何东西

@reasonCode变量是串在一起的原因代码

在我的where条款中,我有一个声明:

(@reasonCode = 'ALL') OR 
((@reasonCode <> 'ALL' AND (charindex(',' +     ro_reason_code, @reasonCode) > 0)))
这是我的问题

当我将1放在01前面时,它不会拾取1原因码。但如果我把它翻个底朝天,效果会很好

你知道为什么会这样吗? (我也尝试过使用concat函数,得到了相同的结果,还尝试过将所有内容强制为char数据类型。)


最后,我希望得到相同的结果,不管它是,01,1还是,1,01。

我很确定这是因为您说您使用的是
char
类型,而不是
varchar
。尝试用以下内容替换您的
charindex
表达式:

charindex(',' + rtrim(ro_reason_code), @reasonCode)
当我在表中使用一种类型的
char(2)
,在
@reasonCode
中使用
char(16)
时,我可以重现您的结果,我发现添加
rtrim
解决了问题。但不幸的是,我无法准确地解释这里发生了什么,为什么在字符串末尾有',1'应该在没有修剪的情况下工作,而在开始时没有。希望有人能提供一个更深入的答案来解释“为什么”,但我想我还是暂时发布这篇文章,让你跑起来

复制:

-- Forgive the "hackish" way of populating this table. I'm assuming sysobjects has >=1015 records.
declare @Code table (ro_reason_code char(2));
insert @Code select top 625 '1' from sysobjects;
insert @Code select top 1015 '01' from sysobjects;

declare @reasonCode char(16); 

set @reasonCode = ',1,01';
select count(1) from @Code where @reasonCode = 'ALL' or charindex(',' + ro_reason_code, @reasonCode) > 0;        -- Result: 1015
select count(1) from @Code where @reasonCode = 'ALL' or charindex(',' + rtrim(ro_reason_code), @reasonCode) > 0; -- Result: 1640

set @reasonCode = ',01,1';
select count(1) from @Code where @reasonCode = 'ALL' or charindex(',' + ro_reason_code, @reasonCode) > 0;        -- Result: 1640
select count(1) from @Code where @reasonCode = 'ALL' or charindex(',' + rtrim(ro_reason_code), @reasonCode) > 0; -- Result: 1640

因为您使用的是char,这是一个固定长度的字段,所以存储的数据会填充到字段的长度。所以
'1'
存储为
'1'

DECLARE @Code CHAR(2)
SET @Code = '1'

SELECT '''' + @Code + ''''
-- Printes '1 '
因此,在值中添加“,”时,现在有了
”,1'
(注意后面的空格)

现在,如果比较另一个char字段,如果字符数据小于字段的长度,那么也会有填充的空白。所以看起来是
',11,1'
的东西实际上是类似
',11,1'
的东西,它与
',1'
的模式匹配

DECLARE @Code CHAR(2)
SET @Code = '1'

SELECT '''' + @Code + ''''
-- Printes '1 '
但是,当您颠倒顺序时,
',1,11'
变为
',1,11'
,这与
',1'
的模式不匹配

DECLARE @Code CHAR(2)
SET @Code = '1'

SELECT '''' + @Code + ''''
-- Printes '1 '
无关的 我只想指出,实现中存在一个微妙的问题。如果只在前面加逗号,根据数据的不同,可能会出现误报。例如,
,2
将匹配模式
,25

,2
不匹配
1,11,25,A01

您必须在求值的每一侧的两侧附加逗号

CHARINDEX( ',' + RTRIM(ro_reason_code) + ',',
           ',' + RTRIM(@reasonCode)    + ',') > 0
为了说明它的不同之处


,2,
不匹配
,1,11,25,A01,
mysql
sql server
<代码>+在后者中是串联的,但我不是前者。Sql Server 2014您可以创建一个脚本来重现该问题吗?我对原因有怀疑,但这取决于你的问题有一点不准确,我不愿意假设。只有当OP在描述问题时不完全准确时,这才可能是真的。如果出现
char
问题,则使用
',1'
的测试不应返回正确的结果。“不过,这也是我的第一个想法。”塔巴勒曼补充道。我实际上能够重现这个问题,所以我对答案很有信心,但我不明白为什么有必要。事实上,我想我会用我的复制再次更新。我明白了,我假设OP对
@ReasonCode
变量使用
varchar
,但是如果他使用
char
,那么是的,你会复制他的结果,这就是答案。先生,你是一个救生员!我不太清楚为什么修剪正在修复它。。。但我做到了,我试着把一切都强制为varChar和char,但这也不起作用。实际上,将其强制为varchar根本不起作用。+1用于获取我丢失的部分:仅当表字段和局部变量都是
char
字段时,才会出现OP中观察到的行为。如果我将局部变量更改为
varchar
,并将表字段保留在
char
,那么输入
'01,1'
'1,01'
都会生成1015,因为变量内容的末尾不再有任何填充。现在你指出这一点似乎很明显回答得好。