2011-11-30 55 views
2

当我尝试此查询它的工作原理:传递一个列表存储过程不起作用

SELECT * 
FROM tbl_Users 
WHERE UserId IN (555, 3695, 8787)) 

但是,当我把它在存储过程中它得到的值只有当我通过一个ID。如果我传递更多ID的

我什么都没有从数据库返回:

CREATE PROCEDURE myStoredProcedure 
    @m_UserIdList varchar(500) 
AS  
    SELECT u.*, p.* 
    FROM tbl_Users u 
    INNER JOIN tbl_Bunker b 
    ON u.BunkerId = b.Bunker 
    WHERE u.UserId IN (@m_UserIdList) 
+1

两个downvotes?为什么?因为OP不知道这个问题的答案?如果每个人都已经知道不会犯这样的错误,那么SO就不会存在。请删除你的提议或写评论,以解释你为什么downvoted? (至少OP可以做些什么...) – MatBailie

+0

SQL Server 2008还允许表值参数。这使您可以将数据集作为参数提供给存储过程。 – MatBailie

回答

1

是的,它将@m_UserIdList视为一个单一值并将其与u.UserId进行比较。您需要拆分这些值并分别进行测试。 Oded击败了我,但他是对的 - 你应该使用一个表值参数。下面是从俄德链接:

http://www.sommarskog.se/arrays-in-sql-2008.html

该网站提供了这个问题一堆不同的方法:

http://vyaskn.tripod.com/passing_arrays_to_stored_procedures.htm

的方法之一是使用动态SQL,但是你应该意识到这样做的危险。首先阅读:

http://www.sommarskog.se/dynamic_sql.html

如果你决定走这条路,这样的事情可能工作:

DECLARE @SQL varchar(600) 

SET @SQL = 
'SELECT u.*, p.* 
FROM tbl_Users u 
    INNER JOIN tbl_Bunker b ON u.BunkerId = b.Bunker 
WHERE u.UserId IN (' + @m_UserIdList+ ')' 

EXEC(@SQL) 
+0

而不是动态的SQL文章,我会发布这个,由同一个作者:http://www.sommarskog.se/arrays-in-sql-2008.html – Oded

+0

伟大的一点,我刚刚添加它(你已经得到我的赞成,希望我可以给另一个)。 – JohnD

1

@m_UserIdListVARCHAR(500),不是值的列表,所以这是不行的。您可以尝试将传入的字符串解析为表格(并且有很多方法可以实现 - 只需搜索此网站)。

但是,由于您使用的是SQL Server 2008,因此您应该看看table valued parameters - 这些允许您将值表传递给存储过程。

4

那是因为你的select语句是等价的:

SELECT u.*, p.* 
FROM tbl_Users u 
INNER JOIN tbl_Bunker b ON u.BunkerId = b.Bunker 
WHERE u.UserId IN ('555, 3695, 8787') 

你基本上搜索是否UserId是字面上匹配'555, 3695, 8787',这不是你想要的。

2

鲨鱼比我打算解释得更好。如果我没有记错,你可以做到这一点,但是我已经很长时间了,因为我不得不做你以后的事情,所以我可能会犯错。

EXEC('SELECT u.*, p.* 
     FROM tbl_Users u 
     INNER JOIN tbl_Bunker b ON u.BunkerId = b.Bunker 
     WHERE u.UserId IN (' + @m_UserIdList + ')') 
1

因为它没有提到,您可以使用XML数据类型。

BEGIN 
DECLARE @xml XML 
SELECT @xml = '<n>1</n><n>2</n><n>3</n>' 

SELECT t.n.value('.','int') FROM @xml.nodes('*') as t(n) 
IF 1 IN (SELECT t.n.value('.','int') FROM @xml.nodes('*') as t(n)) 
    PRINT('Yep') 
IF 4 NOT IN (SELECT t.n.value('.','int') FROM @xml.nodes('*') as t(n)) 
    PRINT('It Works') 
END 

它不像表值列那样高效,但它更容易设置/使用“调用者”。

如果呼叫者已经有元素的数组或列表将它们转换到XML他只是做了的string.join与“</N > <ñ>”作为分隔符,然后,如果得到的字符串不为空prepend“<n>”并附加“</n >”

相关问题