Reputation: 895
CREATE TABLE #MyTempTable
(
Name varchar(30)
)
CREATE PROC InsertData_To_TempTable(--Varying number of Names will go here)
AS
BEGIN
INSERT INTO #MyTempTable(Name)
VALUES (--Varying list of values as input parameters from procedure)
END
EXEC InsertData_To_TempTable ('A'),('B') -- one time I may want to insert TWO values
EXEC InsertData_To_TempTable ('A'),('B'),('C') -- other time I may want to insert THREE values
Is there any way that I can dynamically insert varying number of names into my temp table?
Upvotes: 1
Views: 82
Reputation: 28751
Rather than passing variable number of parameters , send a single comma seperated list of name and inside the stored proc, use a split function to retrieve name values and insert.
CREATE PROC InsertData_To_TempTable
@NameList VARCHAR(MAX)
AS
BEGIN
INSERT INTO #MyTempTable(Name)
SELECT Item
FROM dbo.SplitString(@NameList)
END
And then call
EXEC InsertData_To_TempTable 'A,B,C'
EXEC InsertData_To_TempTable 'A,B,C,D,E'
There is no inbuilt split function so here is one user defined function.
CREATE FUNCTION SplitString
(
@Input NVARCHAR(MAX),
@Character CHAR(1)
)
RETURNS @Output TABLE (
Item NVARCHAR(1000)
)
AS
BEGIN
DECLARE @StartIndex INT, @EndIndex INT
SET @StartIndex = 1
IF SUBSTRING(@Input, LEN(@Input) - 1, LEN(@Input)) <> @Character
BEGIN
SET @Input = @Input + @Character
END
WHILE CHARINDEX(@Character, @Input) > 0
BEGIN
SET @EndIndex = CHARINDEX(@Character, @Input)
INSERT INTO @Output(Item)
SELECT SUBSTRING(@Input, @StartIndex, @EndIndex - 1)
SET @Input = SUBSTRING(@Input, @EndIndex + 1, LEN(@Input))
END
RETURN
END
GO
There are other split fucntion with better performance (no use of while loop) that you can search for. SQL Server 2016 has introduced split function. Here is an excellent source for performance analysis of various split functions.
Upvotes: 1
Reputation: 81970
Without a Split/Parse function
Here we pass the delimiter as a | which can be anything you prefer
Declare @Names varchar(max) = 'Smith, John|Williams, Bill'
Insert Into #MyTempTable(Name)
Select RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)')))
From (Select x = Cast('<x>'+ replace((Select @Names as [*] For XML Path('')),'|','</x><x>')+'</x>' as xml).query('.')) as A
Cross Apply x.nodes('x') AS B(i)
With a Split/Parse Function
Declare @Names varchar(max) = 'Smith, John|Williams, Bill'
Insert Into #MyTempTable(Name)
Select RetVal from [dbo].[udf-Str-Parse] (@Names,'|')
The UDF if Needed
CREATE FUNCTION [dbo].[udf-Str-Parse] (@String varchar(max),@Delimiter varchar(10))
Returns Table
As
Return (
Select RetSeq = Row_Number() over (Order By (Select null))
,RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)')))
From (Select x = Cast('<x>'+ replace((Select @String as [*] For XML Path('')),@Delimiter,'</x><x>')+'</x>' as xml).query('.')) as A
Cross Apply x.nodes('x') AS B(i)
);
--Select * from [dbo].[udf-Str-Parse]('Dog,Cat,House,Car',',')
--Select * from [dbo].[udf-Str-Parse]('John Cappelletti was here',' ')
--Select * from [dbo].[udf-Str-Parse]('this,is,<test>,for,< & >',',')
Upvotes: 2