动态添加列名并将其值添加为行sql server

时间:2017-03-28 15:37:24

标签: sql sql-server dynamic

我有一个表table1,列名为a,b,c,d,e,f。 现在的任务是获取每列的值,它肯定是单行值,并将其插入到其他table2 - 列(x,y,z)中。所以我的查询就像:

 insert into table2 (x, y, z)
select a, '', '' from table1
union all
select b, '', '' from table1
union all
select c, '', '' from table1
union all
select d, '', '' from table1
union all
select e, '', '' from table1
.
.
.
union all
select f, '', '' from table1

现在,如果在table1中添加了一个新列,那么我必须再添加一个select语句。只是想避免这种情况如何编写动态查询,自动考虑所有列并使其更短。

4 个答案:

答案 0 :(得分:2)

似乎在寻找动态EAV结构(实体属性值)。现在很酷的部分是@YourTable可以是任何查询

Declare @YourTable table (ID int,Col1 varchar(25),Col2 varchar(25),Col3 varchar(25))
Insert Into @YourTable values
 (1,'a','z','k')
,(2,'g','b','p')
,(3,'k','d','a')


Select A.ID
      ,C.*
 From  @YourTable A
 Cross Apply (Select XMLData=cast((Select A.* for XML Raw) as xml)) B
 Cross Apply (
                Select Attribute = attr.value('local-name(.)','varchar(100)')
                      ,Value     = attr.value('.','varchar(max)')              -- change datatype if necessary
                 From  B.XMLData.nodes('/row') as A(r)
                 Cross Apply A.r.nodes('./@*') AS B(attr)
                 Where attr.value('local-name(.)','varchar(100)') not in ('ID','OtherFieldsToExclude')  -- Field Names case sensitive
             ) C

返回

ID      Attribute   Value
1       Col1        a
1       Col2        z
1       Col3        k
2       Col1        g
2       Col2        b
2       Col3        p
3       Col1        k
3       Col2        d
3       Col3        a

答案 1 :(得分:1)

更简单的方法是使用cross apply

insert into table2 (x, y, z)
    select v.x, '', ''
    from table1 t1 cross apply
         (values (t1.a), (t1.b), (t1.c), (t1.d), (t1.e), (t1.f)
         ) v(x);

如果要在将新列添加到表中时插入新值,则需要DDL并且可能需要DML触发器。 DML触发器是“标准”触发器。

您可以在documentation中了解DDL触发器。

也就是说,我非常怀疑鼓励添加新列和新表的数据库系统。可能有更好的方法来设计应用程序,例如,使用EAV数据模型,为属性提供更大的灵活性。

答案 2 :(得分:0)

试试这个

insert into table2 
select Tmp.id, tb1.* from table1 tb1,
((SELECT B.id FROM (SELECT [value] = CONVERT(XML ,'<v>' + REPLACE('a,b,c,d,e,f' , ',' , '</v><v>')+ '</v>')) A     
OUTER APPLY 
(SELECT  id = N.v.value('.' , 'varchar(100)') FROM A.[value].nodes('/v') N ( v )) B)) Tmp 

答案 3 :(得分:0)

如果我正确地阅读它,这看起来是一个完美的使用时间 PIVOT