2011-09-18 209 views
13

我有存储过程,我必须传递参数,但问题是我不确定有多少参数要到,它可以是1,在下次运行时它可以是5.带有可变数量参数的存储过程

cmd.Parameters.Add(new SqlParameter("@id", id) 

任何人都可以帮助我如何在存储过程中传递这些可变数量的参数? 谢谢

+1

要传递不同数量的参数,你就只需要条件逻辑在客户端代码添加所需的参数,但你的意思是你想知道如何将不同数量的'id'传递给存储过程? –

+0

是的......它将数组传递给存储过程......但这个数组的长度可能会有所不同。 – CPDS

+0

RDBMS这是什么(包括版本)? –

回答

13

您可以将它作为以逗号分隔的列表传递,然后使用拆分函数并结合结果。

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或更好的,你可以在更有效地使用表值参数(台湾居民入境许可证)通过这些。在这里看到一个快速的介绍:

5

SQLServer允许您将TABLE参数传递给存储过程。所以你可以定义表类型CREATE TYPE LIST_OF_IDS AS TABLE (id int not null primary key),改变你的过程来接受这种类型的变量(它应该是只读的)。

2

您是否考虑过使用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 
+0

这是C#身边...我如何读这在SQL Server端...怎么我会创建过程? – CPDS

+0

你可以检查Andomar对程序样本响应。只是加入了类似片段有在同一个地方的一切。 – Li0liQ

6

存储过程支持可选参数。像C#4一样,您可以使用=指定默认值。例如:

create procedure dbo.doStuff(
    @stuffId int = null, 
    @stuffSubId int = null, 
    ...) 
as 
... 

对于你不想传递参数,或者将其设置为null或不将它们添加到cmd.Parameters可言。他们将在存储过程中使用它们的默认值