Asp.net 在SQL语句中将参数传递给
我收集了一些要从字符串变量内的DB列中查找的值,并试图将其作为参数传递到SQL StoredProcess中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附近出现语法错误 在我的网页中,参数的值类似于正在传递的(
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>'