使用无限数量的参数创建存储过程

时间:2018-06-03 18:03:28

标签: sql sql-server tsql stored-procedures

我必须制作一个插入过程,该过程需要无限数量的参数,例如

USER_ID, First_Name, Last_Name, Fav film, 'Fav Book', Fav Music

EXEC dbo.sp_whatever 'ID999', 'Tommy', 'Soprano', 'Jack', 'Forest Gump', 'Book_name', 'Music_Name'

OR

USER_ID, First_Name, Last_Name, Fav film

EXEC dbo.sp_whatever 'ID999', 'Ashley', 'Collins', 'Cujo'

然后根据给定的参数,它应该失败或继续在几个表中创建新条目,具体取决于提供的参数(自解释)。

现在我完全不知道如何处理这个问题,我如何处理无限数量的参数,或者什么是正确的,正确的方法来解决这个问题?

编辑:

基本上。这将是情景。我写了一个商店程序,称之为“InsertNewUser' 我有一个人想要注册,所以我做了EXEC InsertNewUser ...' 我将有关此人的所有相关信息插入正确的表格中。 这基本上就是我想要实现的目标。 (我知道场景很愚蠢,不用担心。)

3 个答案:

答案 0 :(得分:2)

您可以将类型创建为表并传递该类型的变量。像:

CREATE TYPE your_sp_args
            AS TABLE (n integer
                      v varchar(MAX));

CREATE PROCEDURE your_sp @args your_sp_args
...;

DECLARE @args your_sp_args;

INSERT INTO @args
            (n,
             v)
            VALUES (1,
                    'FOO');

EXECUTE your_sp @args;

INSERT INTO @args
            (n,
             v)
            VALUES (2,
                    'BAR');

EXECUTE your_sp @args;

答案 1 :(得分:2)

有多种方法可以使用存储过程传递多个参数值。使用以下方法,您只需根据项目要求创建单个参数。

方法#1 - 将CSV:作为参数的字符串列表传递给(N)VARCHAR数据类型参数,然后在SP或UDF内拆分/解析它。

方法#2 - 将XML:string作为XML数据类型参数传递。我们需要解析SP中的XML。

方法#3 - 使用临时表:在执行之前在外部创建的SP内部。这里不需要使用SP传递任何参数。

方法#4 - 使用TVP:使用SQL Server 2008及更高版本,您可以创建TVP或表值参数,并使用用户定义的表类型声明它们。然后,可以使用这些TVP将多行数据发送到SP或UDF,而无需创建临时表或多个参数。

方法#5 - 传递JSON字符串:作为NVARCHAR数据类型参数。我们需要在SP中解析JSON。

Reference

答案 2 :(得分:0)

以下代码演示了处理存储过程中可选参数的方法。所有可能的参数必须事先知道,但可以使用参数子集调用SP。

create procedure AddUser
  @UserId Int Output,
  @FirstName NVarChar(64),
  @LastName NVarChar(64),
  @FavoriteHandbag NVarChar(64) = NULL,
  @FavoriteShoe NVarChar(64) = NULL,
  @FavoriteWeapon NVarChar(64) = NULL
as
  -- Validate the inputs.
  if ( @FavoriteHandbag is NULL ) and ( @FavoriteShoe is NULL ) and ( @FavoriteWeapon is NULL )
    begin
    RaIsError( 'New users must have at least one favorite specified.', 13, 0 );
    return;
    end
  -- tbd: Check for missing or duplicate name, ... .

  -- Store the data.
  insert into Users ( FirstName, LastName, FavoriteHandbag, FavoriteShoe, FavoriteWeapon )
    values ( @FirstName, @LastName, @FavoriteHandbag, @FavoriteShoe, @FavoriteWeapon );

  -- Return the new user's   UserId .
  set @UserId = Scope_Identity();
go

-- Test the SP.
declare @UserId as Int;

-- Without any favorites it ought to fail.
exec AddUser @UserId = @UserId output, @FirstName = 'William', @LastName = 'Shakespeare';

-- With any combination of favorites it ought to succeed.
exec AddUser @UserId = @UserId output, @FirstName = 'William', @LastName = 'Shakespeare',
  @FavoriteWeapon = 'pen';

exec AddUser @UserId = @UserId output, @FirstName = 'William', @LastName = 'Shakespeare',
  @FavoriteShoe = 'moccasin', @FavoriteWeapon = 'pen';

如果Real Problem™是参数可能包含任意名称/值对列表,例如{ 'Topping', 'Whipped Cream' },事先未知,必须使用不同的方法。如果对的数量有限,则可以使用参数,例如, @Name1@Value1@Name2@Value2,.... TVP或XML参数将提供对列表的更整洁的表示。