首页新闻找找看学习计划

SQL 存储过程的复杂问题

0
悬赏园豆:10 [已解决问题] 解决于 2013-09-22 10:04

SQL 语句如下:

declare @ItemList varchar(300)
select @ItemList=ItemList from ManagerTb where UserId='8888'
print @ItemList

  declare @i int

select @i=(select count(1) from  ManagerTb where userId='''8888''' and  '''50''' in (@ItemList))
print @i

查询结果如图,为什么@i 是0 而不是1呢?

当然下面这句“select count(1) from  ManagerTb where userId='8888' and  '50' in(43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60)” 的结果是1

t101lian的主页 t101lian | 初学一级 | 园豆:18
提问于:2013-09-18 17:28
< >
分享
最佳答案
-2

第一句的userId='''888''',已经加了单引号,所以为0,然后第二句中userId='8888',所以为1。

收获园豆:5
幻天芒 | 高人七级 |园豆:36522 | 2013-09-18 20:38

select @i=(select count(1) from  ManagerTb where userId=8888 and  '50' in (@ItemList))
print @i

 

现在改成这样也同样是0,,大牛,该怎么破?

t101lian | 园豆:18 (初学一级) | 2013-09-20 09:55

@t101lian: in括号里面的数据,在参数化的时候,不能和 in(1,2,3)等同,而是会被解析了一个'1,2,3',这样的话,50 in ('1,2,3')也就不能匹配了。还有你这个单引号的使用,感觉是有点不对。


顺便纠正下我的第一个问答,'''888'''会引发

消息 245,级别 16,状态 1,第 2 行
在将 varchar 值 ''8888'' 转换成数据类型 int 时失败。

然后将userId='8888'时,由于in条件不满足,所以还是为0


接下来,附上测试:

1、用例准备:

--构造临时表,初始化测试数据
CREATE TABLE #ManagerTb
(
    UserId       INT,
    ItemList     VARCHAR(512)
)
INSERT INTO #ManagerTb
VALUES
  (
    8888,
    '43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60'
  ),
(
    9999,
    '43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60'
)

2、验证为0的代码代码:

DECLARE @ItemList VARCHAR(300)
SELECT @ItemList = ItemList
FROM   #ManagerTb
WHERE  UserId = '8888'

PRINT @ItemList
DECLARE @i INT
SELECT @i = (
           SELECT COUNT(1)
           FROM   #ManagerTb
           WHERE  userId = '8888'
                  AND '50' IN (@ItemList)--@ItemList被当成一个元素,
                                         --所以匹配'50'='43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60'
                                         --所以为false,结果为0
       )

PRINT @i

3、验证in(@param),参数化后只算一个元素:

DECLARE @ItemList VARCHAR(300)
SELECT @ItemList = ItemList
FROM   #ManagerTb
WHERE  UserId = '8888'

PRINT @ItemList
SET @ItemList='50'
DECLARE @i INT
SELECT @i = (
           SELECT COUNT(1)
           FROM   #ManagerTb
           WHERE  userId = '8888'
                  AND '50' IN (@ItemList)--@ItemList被当成一个元素,
                                         --所以匹配'50'='50'
                                         --然后结果为1,找到一个id=8888的。
       )

PRINT @i

 

幻天芒 | 园豆:36522 (高人七级) | 2013-09-20 12:02
其他回答(2)
1

试试改为下面的SQL:

EXEC('select @i=(select count(1) from  ManagerTb where userId=''8888'' and  ''50'' in (' + @ItemList + '))')
收获园豆:3
dudu | 园豆:39065 (高人七级) | 2013-09-18 17:41

执行出错啦,,,

支持(0) 反对(0) t101lian | 园豆:18 (初学一级) | 2013-09-20 09:51

@t101lian: 把@i与@ItemList的声明也要放在EXEC中

支持(0) 反对(0) dudu | 园豆:39065 (高人七级) | 2013-09-20 09:53
0

你的“50”是字符串类型;与后面in(43,44,.........50...)中的50类型不统一。

可以改成:and  '50' in (' + @ItemList + ')

            或  and  50  in ( @ItemList )

收获园豆:2
@举杯邀明月 | 园豆:216 (菜鸟二级) | 2013-09-18 17:55

select @i=(select count(1) from  ManagerTb where userId=8888 and  '50' in ('+@ItemList='))

 

结果同样是0

支持(0) 反对(0) t101lian | 园豆:18 (初学一级) | 2013-09-20 09:56

@t101lian: 看了你对问题的具体描述。你有两个问题:

1。Userid  是Int类型。你的查询语句中“where  Userid='8888'   ”就是错的,'8888'是字符串类型。应该是直接 Userid=8888。

2。你的   ItemList  是 VARCHAR(512)类型。这个 '43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60'就成了一个字符串,你用“in(‘50’)”是找不到的。如同   在这个字符串中“我是中国人”这个字符串里用找其中一个汉字,in这个语法是不支持的。可以用这个试试。

select @i=(select count(1) from  ManagerTb where userId=8888 and  @ItemList like '%50%'

3.不过上面的这个语句也会有问题,就是当有包含‘50’都会执行到,比如550,500。或者找方法把该字符串截取成单个的字符如这种(‘43’, '44’, ....)。具体方法你再研究下吧。

支持(0) 反对(0) @举杯邀明月 | 园豆:216 (菜鸟二级) | 2013-09-22 09:40
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册