Asp.net 在SQL语句中将参数传递给

Asp.net 在SQL语句中将参数传递给,asp.net,sql,sql-server-2008,Asp.net,Sql,Sql Server 2008,我收集了一些要从字符串变量内的DB列中查找的值,并试图将其作为参数传递到SQL StoredProcess中 ALTER PROCEDURE [dbo].[InkDB] ( @ser nvarchar(255), @svt nvarchar(255) ) AS SELECT DISTINCT Details from tbData WHERE (Name IN @svt AND Address=@ser) 这在试图运行查询时,在@svt附近出现语法错误 在我的网页中,参数的值类似于正在传递的(

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

ALTER PROCEDURE [dbo].[InkDB]
(
@ser nvarchar(255),
@svt nvarchar(255)
)
AS
SELECT DISTINCT Details from tbData WHERE (Name IN @svt AND Address=@ser)
这在试图运行查询时,在@svt附近出现
语法错误


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

。。。在(@param1,@param2,…)

因此,你应该:

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

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

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

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

下面是您代码的正确语法,但它无法解决传递包含逗号分隔的值列表的字符串的第二个方面

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

创建表TbData( 名称nvarchar(255), 详细信息nvarchar(255), 地址nvarchar(255) ))

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

创建过程测试 ( @纳瓦查爵士(255), @svt nvarchar(255) ) 作为 开始 从tbData中选择不同的详细信息,其中Name IN(@ser)和Address=@svt 结束

最后,执行您询问的alter存储过程语句:

变更程序试验 ( @纳瓦查爵士(255), @svt nvarchar(255) ) 作为 开始 从tbData中选择不同的详细信息,其中Name IN(@ser)和Address=@svt
END

这是一个常见的错误-您将字符串类型的单个值(表达式)传递给运算符中的
,但
中的
需要逗号分隔的值(表达式)列表,而不是单个字符串变量

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

SELECT DISTINCT Details from tbData WHERE Name IN (SELECT Val FROM dbo.efn_Split(@svt, ',')) AND Address=@ser
其中,
efn\u Split
是一个表值函数,它将逗号分隔的值拆分为一个表。有关此函数的实现,请参见以下各种SO问题:

另一种选择是构造SQL语句并使用
sp_executesql
执行

动态查询


我会用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>'
exec-InkDB','PersonAPersonB'

Linked的可能重复:将查询语句的where部分更改为
where(Name IN(@svt)和Address=@ser)
给出了
附近的错误语法)“
错误。我认为您误解了这个问题。
@ser
包含一个逗号分隔的值字符串,如
PersonA、PersonB、PersonC
,OP希望与任何值匹配的行。您的查询将只返回名称与整个字符串完全匹配的值。请不要否决synta的答案CTI是正确的,并且修复了
不正确的语法
错误。我提供了其他信息,这些信息将引导您解决第二个问题,即逗号分隔值。我不是说这是最佳实践,这是有争议的。我不推荐这种方法,因为它可能容易受到SQL注入的影响(当然,除非调用代码是为了确保@svt参数的健全性)!不,这不会导致SQL注入。原因是-这是一个带有参数的存储过程。因此,SQL参数肯定会从语言(c#或VB.Net)中使用.Right?@PankajGarg,如果
@svt
或@ser参数是由串联用户输入组成的,则恶意用户可以在查询中插入任何SQL!这是内联SQL的情况,而不是参数化查询。@PankajGarg-您错了。由于SP使用参数动态生成和执行查询,因此它是为SQL Inj打开的节。如果您使用
“”)选择@@version--
作为
@svt
的参数,您将获得SQL Server版本的第二个结果集。当然,您可以做比这更离谱的事情。T.N.value在这里意味着什么?是否提供包含其详细说明的链接?+1这是使用“表值函数”。@PankajGarg-
.nodes
.value
用于在SQL Server中解析和分解XML。您可以在此处阅读更多信息。
exec InkDB '', '<N>PersonA</N><N>PersonB</N>'