简体   繁体   中英

Creating a stored procedure with an indefinite number of parameters

I have to make a insert procedure that takes indefinite number of arguments so for example

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'

Then depending on the arguments given it should either fail or go ahead and create new entries in several tables depending on the arguments provided (self explanatory).

Now I have absolutely no idea how to approach this, how can I work on indefinite number of parameters, or what would be the right, proper way to approach this?

EDIT:

Basically. This would be the scenario. I write a store procedure call it 'InsertNewUser' I have a person that I want to register, so i do 'EXEC InsertNewUser ...' and I INSERT all the relevant information about this person into the right tables. This is basically what I'm trying to achieve. (I know scenario is stupid, don't worry is made up.)

You could create a type as a table and pass a variable of that type. Like:

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;

There are multiple ways where you can pass multiple parameter values with a Stored procedure. With the below methods you need to just create a single parameter according to your project requirement.

Method #1 – Passing a CSV: list of strings as a parameter to a (N)VARCHAR datatype parameter, then splitting/parsing it inside the SP or UDF.

Method #2 – Passing an XML: string as an XML datatype parameter. We will need to parse the XML inside the SP.

Method #3 – Using a temp table: inside an SP which is created outside just before its execution. Here there is no need to pass any parameter with the SP.

Method #4 – Using TVPs: With SQL Server 2008 and above you can create TVPs or Table Valued Parameters and declare them by using user-defined table types. These TVPs can then be used to send multiple rows of data to SPs or UDFs, without creating a temp table or multiple parameters.

Method #5 – Passing a JSON string: as a NVARCHAR datatype parameter. We will need to parse the JSON inside the SP.

Reference

The following code demonstrates a means of handling optional parameters in a stored procedure. All of the possible parameters must be known in advance, but the SP can be called with a subset of parameters.

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';

If the Real Problem™ is that the parameters may contain an arbitrary list of name/value pairs, eg { 'Topping', 'Whipped Cream' } , that are unknown in advance then a different method must be used. If the number of pairs is limited then parameters could be used, eg @Name1 , @Value1 , @Name2 , @Value2 , ... . A TVP or XML parameter would provide a tidier representation of a list of pairs.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM