【问题标题】:Dynamically Insert varying number of values based on the input parameter to a procedure根据输入参数向过程动态插入不同数量的值
【发布时间】:2016-12-30 12:14:38
【问题描述】:
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

有什么方法可以动态地将不同数量的名称插入到我的临时表中?

【问题讨论】:

  • 要么以逗号分隔发送您的值,要么考虑在您的过程中添加一个用户定义的表类型作为参数
  • 只使用insert而不是存储过程怎么样?
  • 查看详细解答here
  • @GordonLinoff - 用户将通过 proc 输入名称,因此只希望它作为 proc。谢谢。

标签: sql sql-server-2008 stored-procedures


【解决方案1】:

没有拆分/解析功能

这里我们将分隔符作为 |可以是你喜欢的任何东西

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)

具有拆分/解析功能

Declare @Names varchar(max) = 'Smith, John|Williams, Bill'

Insert Into #MyTempTable(Name)
Select RetVal from [dbo].[udf-Str-Parse] (@Names,'|')

UDF(如果需要)

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,< & >',',')

【讨论】:

  • @balaji 很高兴它有帮助
【解决方案2】:

与其传递可变数量的参数,不如发送一个逗号分隔的名称列表,并在存储的过程中,使用拆分函数检索名称值并插入。

CREATE PROC InsertData_To_TempTable
@NameList VARCHAR(MAX)
AS
BEGIN

    INSERT INTO #MyTempTable(Name)
    SELECT Item
    FROM dbo.SplitString(@NameList)
END

然后调用

EXEC InsertData_To_TempTable 'A,B,C'

EXEC InsertData_To_TempTable 'A,B,C,D,E'

没有内置的拆分功能,所以这里有一个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

您可以搜索其他性能更好的拆分函数(不使用 while 循环)。 SQL Server 2016 引入了拆分功能。 这是various split functions性能分析的绝佳来源。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-24
    • 2017-10-14
    • 1970-01-01
    • 1970-01-01
    • 2016-09-08
    • 1970-01-01
    相关资源
    最近更新 更多