Sql server 在同一个表中动态解析列值

Sql server 在同一个表中动态解析列值,sql-server,sql-server-2008,Sql Server,Sql Server 2008,我有一个存储过程,它接受可输入的作为参数: create table inputTable (id int, ItemQty varchar(100)) insert into inputTable(id, ItemQty) values (1, 'a,b,c'), (2, 'x,y'), (3, 'l,m,n,o,p'), (4, 'a,b'), (5, 'm') 我编写的存储过程如下所示: ALTER PROCEDURE [dbo].[dynamic_tbl]

我有一个存储过程,它接受可输入的
作为参数:

create table inputTable (id int, ItemQty varchar(100))

insert into inputTable(id, ItemQty) 
values (1, 'a,b,c'), (2, 'x,y'), (3, 'l,m,n,o,p'),
       (4, 'a,b'), (5, 'm')
我编写的存储过程如下所示:

ALTER PROCEDURE [dbo].[dynamic_tbl] 
    (@tablename VARCHAR(50))
AS 
BEGIN
    /* To get the maximum value of ItemQty with comma's [IN THIS CASE IT IS 5 ] */
    DECLARE @ColumnCount int
    DECLARE @rowcount TABLE (Value int);

    INSERT INTO @rowcount
        EXEC('SELECT MAX(len(ITEMQTY) - len(replace(ITEMQTY, '','', '''')) +1) from '+@tablename);

    SELECT @ColumnCount = Value FROM @rowcount;

    DECLARE @ColumnName NVARCHAR(10)='qty_'
    DECLARE @count INT = 0

    IF (@ColumnCount > 0)
    BEGIN
        SET @count = @count + 1;

        WHILE (@ColumnCount >= @count) 
        BEGIN
            SET @ColumnName = 'qty_'+CONVERT(varchar(2),@count)
            EXEC ('ALTER TABLE '+@tablename+' ADD ['+@ColumnName +'] varchar(20)')

            DECLARE @myvar AS VARCHAR(MAX)

            --set @myvar='update '+@tablename+' set '+@ColumnName +' =itemQty'

            /* HERE ACTUALLY I AM GETTING PROBLEM, BECAUSE I WANT TO PARSE VALUES IN THE RESPECTIVE COLUMNS. */
           EXEC(@myvar)

           /* HERE, I wish to write the Actual update statement DYNAMICALLY*/
           EXEC ('UPDATE '+@tablename+' set'+@ColumnName+'=     ' )
           SET @count = @count + 1;
       END
   END
END
我的输入和输出(期望的输出应如下图所示)

输出:

 declare @myvar as varchar(max)

                SET @MYVAR= 'update '+@tablename+ 'set' +@ColumnName+'=case  when '+@count+' = 1 then itemQty else  end'

                exec(@myvar)

以动态方式将类似内容添加到代码中

 declare @myvar as varchar(max)

                SET @MYVAR= 'update '+@tablename+ 'set' +@ColumnName+'=case  when '+@count+' = 1 then itemQty else  end'

                exec(@myvar)

请检查以下SQL Select语句

;with cte as (
select 
    i.id, i.ItemQty, s.id as rn, s.val
from inputTable as i
cross apply dbo.Split(ItemQty,',') as s
)
select
    id, ItemQty, 
    max(qty1) qty1,
    max(qty2) qty2,
    max(qty3) qty3,
    max(qty4) qty4,
    max(qty5) qty5
from (
select 
    id,
    ItemQty,
    case when rn = 1 then val else null end as qty1,
    case when rn = 2 then val else null end as qty2,
    case when rn = 3 then val else null end as qty3,
    case when rn = 4 then val else null end as qty4,
    case when rn = 5 then val else null end as qty5
from cte
) t
group by id, ItemQty
结果如下

请注意,对于此解决方案,您需要一个。 检查可用于拆分字符串值的引用用户定义函数。 尽管您可以使用SQL Server 2016或更高版本的数据库平台,但我更喜欢使用自己的拆分函数,因为该函数也会返回拆分字符串片段的顺序


我希望它能有所帮助,

变体,其中
ItemQty
只包含一个符号
'a,b,c'

ALTER PROCEDURE [dbo].[dynamic_tbl] (@tablename varchar(50))
AS 

CREATE TABLE #inputTable(id int,ItemQty varchar(100))

-- insert all the data into temp table
DECLARE @copyScript varchar(MAX)
SET @copyScript='SELECT id,ItemQty FROM '+@tablename

INSERT #inputTable(id,ItemQty)
EXEC(@copyScript)

-- add columns and update data in #inputTable
DECLARE @maxColNum int
SET @maxColNum=(SELECT (MAX(LEN(ItemQty))+1)/2 FROM #inputTable)

DECLARE @curColNum int
SET @curColNum=1

DECLARE @updateScript varchar(MAX)
DECLARE @alterScript varchar(MAX)

WHILE @curColNum<=@maxColNum
BEGIN

  -- add new column
  SET @alterScript='ALTER TABLE '+@tablename+' ADD qty'+CAST(@curColNum AS varchar(5))+' varchar(100)'

  --PRINT @alterScript
  EXEC(@alterScript)

  -- update data in new column
  SET @updateScript='UPDATE i
SET
  qty'+CAST(@curColNum AS varchar(5))+'=q.word
FROM '+@tablename+' i
JOIN
  (
    SELECT id,SUBSTRING(ItemQty,'+CAST((@curColNum-1)*2+1 AS varchar(5))+',1) word
    FROM #inputTable
    WHERE LEN(ItemQty)+1>='+CAST(@curColNum*2 AS varchar(5))+'
  ) q
ON i.ID=q.ID'

  --PRINT @updateScript
  EXEC(@updateScript)

  SET @curColNum=@curColNum+1
END

DROP TABLE #inputTable    
GO

-- test
EXEC dynamic_tbl 'inputTable'

-- show result
SELECT *
FROM inputTable
如果执行以下操作,可以将其作为脚本进行测试

--ALTER PROCEDURE [dbo].[dynamic_tbl] (@tablename varchar(50))
--AS 
DECLARE @tablename varchar(50)='inputTable'
...

您好,谢谢您的时间,但我需要动态的方式,您可以完成它的代码,并向我展示输出。我不想使用分割函数,以及我不熟悉的xml路径,所以我希望它是可能的更新与一些动态循环您可以做分割使用一个WHILE循环在自定义项。请检查一下,您肯定可以找到其他T-SQL开发人员创建的许多SQL拆分函数。我认为有了#word,解决方案将更加简短和清晰。递归CTE只有一个额外的查询-这是一个一般性的区别。如果输入表有一个,bb,ccc,那么它应该在相应的列中将其作为bb ccc分开,但是如果使用第一个带#字的varian。此变体只能与“a、b、c”一起使用。