I'm trying to add a column to a table from data of another table. What I want is like
Select Mname, datatype from tableA
This query will return data like this:
A|float
B|float
C|int
I want to add this data as a column name with datatype of the data in another table
Alter table tableB
Add A float null, B float null, C int null
How can I achieve this?
CodePudding user response:
You can use dynamic SQL for this. As, however, you have no column for the scale and precision, then the defaults will be used. For something like a datetime2
this'll be (7)
, but for a decimal
this would be (18,0)
and a varchar
it would be (1)
, which could make them unsuitable. As such you likely need to address you design to include the precision and scale.
I also check that the data type in datatype
actually exists and that the column doesn't already exist in the table TableB
; the columns will be omitted if they would cause problems. You can omit this logic if you want, which would mean that if the data type doesn't exist, an error would be thrown; it depends what behaviour you want.
I also assume you are using a fully supported version of SQL Server; if not, you'll need to use the "old" FOR XML PATH
(and STUFF
) method for your string aggregation.
DECLARE @SQL nvarchar(MAX);
SELECT @SQL = N'ALTER TABLE dbo.TableB ADD ' STRING_AGG(QUOTENAME(A.Mname) N' ' QUOTENAME(t.[name]) N' NULL',N', ') N';'
FROM dbo.TableA A
JOIN sys.types t ON A.datatype = t.[name]
WHERE NOT EXISTS (SELECT 1
FROM sys.columns c
WHERE c.name = A.Mname
AND c.object_id = OBJECT_ID(N'dbo.TableA'));
--PRINT @SQL;
EXEC sys.sp_executesql @SQL;
CodePudding user response:
Try the following Dynamic SQL
But the STRING_AGG()
will working on SQL Server 2017
and later versions only.
create table tableA (mname varchar(10), datatype varchar(100))
create table tableB (id int)
insert into tableA Values('A','int')
insert into tableA Values('B','float')
insert into tableA Values('C','int')
declare @ColNames varchar(1000) = '', @executeQuery NVARCHAR (MAX)
select @ColNames = STRING_AGG(mname ' ' datatype,',') from tableA
SELECT @executeQuery = 'Alter table tableB ADD ' @ColNames
EXEC sys.sp_executesql @executeQuery;
select * from tableB
drop table tableA
drop table tableB