将参数传递给IN SQL语句

时间:2012-02-29 06:14:29

标签: asp.net sql sql-server-2008

我收集了一些要从字符串变量中的DB列中查找的值,并尝试将其作为SQL StoredProcedure中的参数传递。

ALTER PROCEDURE [dbo].[InkDB]
(
@ser nvarchar(255),
@svt nvarchar(255)
)
AS
SELECT DISTINCT Details from tbData WHERE (Name IN @svt AND Address=@ser)

在尝试运行查询时,这会给我一条syntax error near @svt消息。

在我的网页中,参数的值类似于('PersonA', 'Person B', 'Person C')正在传递的值。在这种情况下如何使用IN语句?

4 个答案:

答案 0 :(得分:2)

我会用XML来做。无法在重复的问题中找到此解决方案,因此我将其添加到此处。

您的SP可能如下所示:

alter procedure InkDB
  @ser nvarchar(255),
  @svt xml
as

declare @T table
(
  Name nvarchar(50)
)

insert into @T
select T.N.value('.', 'nvarchar(50)')
from @svt.nodes('/N') as T(N)

select distinct Details
from tbData 
where Name in (select Name from @T) and
      Address=@ser

你会这样称呼它。

exec InkDB '', '<N>PersonA</N><N>PersonB</N>'

答案 1 :(得分:1)

  

动态查询

Alter procedure test
(
    @ser nvarchar(255),
    @svt nvarchar(255)
)
AS
BEGIN
   declare @sql nvarchar(Max)

   Set @sql='SELECT DISTINCT semester_code from mst_paper WHERE course_code IN ('+@svt+') AND branch_code='+@ser+''

   exec sp_executesql @sql
END

答案 2 :(得分:0)

它是一个常见错误 - 您将类型为string的单个值(表达式)传递给IN运算符,但IN期望以逗号分隔的值(表达式)列表而不是单个字符串变量。

这里需要做的是有一个函数可以根据给定的分隔符将给定参数拆分为多个值,然后将该列表与IN关键字一起使用。例如,

SELECT DISTINCT Details from tbData WHERE Name IN (SELECT Val FROM dbo.efn_Split(@svt, ',')) AND Address=@ser

其中efn_Split是一个表值函数,它将逗号分隔值拆分为一个表。请参阅以下各种SO问题以实现此类功能:
Split function equivalent in T-SQL?
How to split string using delimiter char using T-SQL?

另一种方法是构造SQL语句并使用sp_executesql执行。

答案 3 :(得分:-1)

IN需要如下:

... IN(@ param1,@ param2,...)

所以,你应该这样做:

SELECT DISTINCT Details from tbData WHERE Name IN (@svt) AND Address=@ser

<强>更新

您在问题中提供的alter procedure语句在语法上是不正确的。我的回答提供了编写语句的正确语法并编译。

再次阅读你的问题,我发现你实际上有两个问题。第一个是语法错误,第二个是在单个参数中传入逗号分隔列表。

答案是,您根本无法在运行时将逗号分隔的值列表提供给IN (...)子句中使用的单个字符串类型参数。现在,关于第二点,我认为这不是一个好的设计/编程方法来解决问题,但可以使用动态SQL或解析出字符串参数中的每个值,将它们存储到临时表中然后修改您的查询要加入,或使用(或使用表值函数并将解析后的项目存储在那里,可以从中查询。

下面是您的代码的更正语法,但它不会解决传递包含以逗号分隔的值列表的字符串的第二个方面。如上所述,这可以解决。

对于语法错误,首先,您可以创建一个虚拟表来测试您的代码。注意,典型的数据库表应该有一个主键。这严格来说是一个虚拟表来测试语句:

CREATE TABLE TbData(         名称nvarchar(255),         详情nvarchar(255),         地址nvarchar(255)     );

然后,您可以创建初始存储过程:

CREATE PROCEDURE测试     (         @ser nvarchar(255),         @svt nvarchar(255)     )     如     开始     SELECT DISTINCT Details FROM tbData WHERE Name IN(@ser)AND Address = @svt     END

最后,执行您询问过的alter stored procedure语句:

ALTER PROCEDURE测试     (         @ser nvarchar(255),         @svt nvarchar(255)     )     如     开始     SELECT DISTINCT Details FROM tbData WHERE Name IN(@ser)AND Address = @svt     END