我有存储过程,我必须传递参数,但问题是我不确定有多少参数要到,它可以是1,在下次运行时它可以是5.带有可变数量参数的存储过程
cmd.Parameters.Add(new SqlParameter("@id", id)
任何人都可以帮助我如何在存储过程中传递这些可变数量的参数? 谢谢
我有存储过程,我必须传递参数,但问题是我不确定有多少参数要到,它可以是1,在下次运行时它可以是5.带有可变数量参数的存储过程
cmd.Parameters.Add(new SqlParameter("@id", id)
任何人都可以帮助我如何在存储过程中传递这些可变数量的参数? 谢谢
您可以将它作为以逗号分隔的列表传递,然后使用拆分函数并结合结果。
CREATE FUNCTION dbo.SplitInts
(
@List VARCHAR(MAX),
@Delimiter CHAR(1)
)
RETURNS TABLE
AS
RETURN
(
SELECT Item = CONVERT(INT, Item)
FROM
(
SELECT Item = x.i.value('(./text())[1]', 'INT')
FROM
(
SELECT [XML] = CONVERT(XML, '<i>'
+ REPLACE(@List, @Delimiter, '</i><i>')
+ '</i>').query('.')
) AS a
CROSS APPLY
[XML].nodes('i') AS x(i)
) AS y
WHERE Item IS NOT NULL
);
现在你的存储过程:
CREATE PROCEDURE dbo.doStuff
@List VARCHAR(MAX)
AS
BEGIN
SET NOCOUNT ON;
SELECT cols FROM dbo.table AS t
INNER JOIN dbo.SplitInts(@List, ',') AS list
ON t.ID = list.Item;
END
GO
然后调用它:
EXEC dbo.doStuff @List = '1, 2, 3, ...';
你可以看到一些背景,其他选项,性能比较这里:
当然,如果你使用SQL Server 2008或更好的,你可以在更有效地使用表值参数(台湾居民入境许可证)通过这些。在这里看到一个快速的介绍:
SQLServer允许您将TABLE
参数传递给存储过程。所以你可以定义表类型CREATE TYPE LIST_OF_IDS AS TABLE (id int not null primary key)
,改变你的过程来接受这种类型的变量(它应该是只读的)。
您是否考虑过使用dictionary用于此目的? 它将允许您传递任意数量的参数作为键值对。 然后,您只需要浏览字典并将这些参数添加到cmd。
void DoStuff(Dictionary<string, object> parameters)
{
// some code
foreach(var param in parameters)
{
cmd.Parameters.Add(new SqlParameter(param.Key, param.Value);
}
// some code
}
在存储过程本身中,您需要指定参数的默认值。
CREATE PROCEDURE DoStuff(
@id INT = NULL,
@value INT = NULL,
-- the list of parameters with their default values goes here
)
AS
-- procedure body
存储过程支持可选参数。像C#4一样,您可以使用=
指定默认值。例如:
create procedure dbo.doStuff(
@stuffId int = null,
@stuffSubId int = null,
...)
as
...
对于你不想传递参数,或者将其设置为null
或不将它们添加到cmd.Parameters
可言。他们将在存储过程中使用它们的默认值
要传递不同数量的参数,你就只需要条件逻辑在客户端代码添加所需的参数,但你的意思是你想知道如何将不同数量的'id'传递给存储过程? –
是的......它将数组传递给存储过程......但这个数组的长度可能会有所不同。 – CPDS
RDBMS这是什么(包括版本)? –