简体   繁体   中英

How to Update a column by getting the column name dynamically from another table in sql server

 create table #tableA
(
    Id int,
    ColumnName1 nvarchar(50),
    ColumnName2 nvarchar(50),
    ColumnName3 nvarchar(50),
    ColumnName4 nvarchar(50) 
) 
 create table #tableB
(
    Id int,
    UpdateColumn nvarchar(50),
    UpdateValue nvarchar(50)
) 

Insert Into #tableA values (1,'Val1','Val2','Val3','Val4')
Insert Into #tableA values (2,'Val1','Val2','Val3','Val4')
Insert Into #tableA values (3,'Val1','Val2','Val3','Val4')
Insert Into #tableA values (4,'Val1','Val2','Val3','Val4')

Insert Into #tableB values (1,'ColumnName4','Column4Value')
Insert Into #tableB values (2,'ColumnName1','Column1Value') 

declare @Sql nvarchar(max)
set @Sql='Update a set {The column should be the value from b.UpdateColumn}={b.UpdateValue} from #tableA a join #tableB b on a.Id=b.Id'

print @Sql
exec sp_executesql @Sql 

I need to update #tableA column dynamically based on from #tableB value.

I tried to build a dynamic sql by concatenating the value from the join clause but nothing worked.

Please suggest.. Thanks in advance...

I would do this using dynamic SQL (although you could). Assuming you have only one update per id, use case :

update a
    set ColumnName1 = (case when b.UpdateColumn = 'ColumnName1' then b.UpdateValue else ColumnName1 end),
        ColumnName2 = (case when b.UpdateColumn = 'ColumnName2' then b.UpdateValue else ColumnName2 end),
        ColumnName3 = (case when b.UpdateColumn = 'ColumnName3' then b.UpdateValue else ColumnName3 end),
        ColumnName4 = (case when b.UpdateColumn = 'ColumnName4' then b.UpdateValue else ColumnName4 end)
    from #tableA a join
         #tableB b
         on a.id = b.id;

If you want to generate one update statement from your reference tables, you can use stuff and for xml to concatenate all your operations into one string value:

if object_id('tempdb..#tableA') is not null
drop table #tableA;
if object_id('tempdb..#tableB') is not null
drop table #tableB;

create table #tableA
(
    Id int,
    ColumnName1 nvarchar(50),
    ColumnName2 nvarchar(50),
    ColumnName3 nvarchar(50),
    ColumnName4 nvarchar(50) 
);
insert Into #tableA values (1,'Val1','Val2','Val3','Val4'),(2,'Val1','Val2','Val3','Val4'),(3,'Val1','Val2','Val3','Val4'),(4,'Val1','Val2','Val3','Val4');

create table #tableB
(
    Id int,
    UpdateColumn nvarchar(50),
    UpdateValue nvarchar(50)
);
insert Into #tableB values (1,'ColumnName4','Column4Value'),(1,'ColumnName3','Column3Value'),(2,'ColumnName1','Column1Value');

declare @sql nvarchar(max);
with c as
(
select distinct id
                ,stuff((select char(10) + '   ,' + UpdateColumn + ' = ''' + UpdateValue + ''''
                        from #tableB
                        where id = b.id
                        for xml path('')
                        ),1,5,'') as Cols
from #tableB b
)
select @sql = stuff((select ';update #tableA set'
                            + char(10)
                            + '    ' + c.Cols
                            + char(10)
                            + 'where id = ' + cast(c.id as nvarchar(10))
                            + char(10)
                            + char(10)
                from c
                for xml path('')
                ),1,1,'')

print @sql;
exec sp_executesql @sql;

Which outputs and executes the following script:

update #tableA set
    ColumnName4 = 'Column4Value'
   ,ColumnName3 = 'Column3Value'
where id = 1

;update #tableA set
    ColumnName1 = 'Column1Value'
where id = 2

Using Triggers.

CREATE TRIGGER triggerName ON [dbo].[tableB] 
AFTER Update
AS
Begin
--Update tableA here
End

Now every time tableB updated this trigger will be called and you can use any condition within it.

drop table if exists #tableA;
drop table if exists #tableB;

create table #tableA
(
    Id int,
    ColumnName1 nvarchar(50),
    ColumnName2 nvarchar(50),
    ColumnName3 nvarchar(50),
    ColumnName4 nvarchar(50) 
) 
 create table #tableB
(
    Id int,
    UpdateColumn nvarchar(50),
    UpdateValue nvarchar(50)
) 

Insert Into #tableA values (1,'Val1','Val2','Val3','Val4')
Insert Into #tableA values (2,'Val1','Val2','Val3','Val4')
Insert Into #tableA values (3,'Val1','Val2','Val3','Val4')
Insert Into #tableA values (4,'Val1','Val2','Val3','Val4')

Insert Into #tableB values (1,'ColumnName4','Column4Value')
Insert Into #tableB values (2,'ColumnName1','Column1Value') 

declare @Sql nvarchar(max)

select
    @SQL = string_agg('update a
    set
        ' + b.UpdateColumn +  ' = ''' + b.UpdateValue + '''
    from #tableA a', ';')
from #tableB b

print @Sql
exec sp_executesql @Sql

select
*
from #tableA

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