I still suggest to go with @iliketocode.
Dynamic Columns Generate as per your requirement
This is just another option, but purely dynamic as you want (only its need some time to execute rather than above answer). To achieve the result without define each column, you can create dynamic query which automatically add column as null via loop.
The same issue I faced and due to short time, I was done as above. But today I fill to give the proper solution (which I not done at that time) and I created a sample for you as you want, I hope this will help you.
--create table t1 (col1 int , col2 int, col3 int)
--create table t2 (col1 int , col2 int, col3 int, col4 int)
--insert into t1 values (1,11,111), (2,22,222)
--insert into t2 values (1,11,111,1111), (2,22,222,null)
--Step 1 - Declaration of variable
Declare @NoOfColumnForUnion int = 5
declare @T1TableColumnList nvarchar(max) ='' ,@T2TableColumnList nvarchar(max) ='' , @colName nvarchar(500) , @test cursor
--Step 2 - Get the column list of first table i.e. t1 and store into @T1TableColumnList variable
set @test = cursor for
select name from syscolumns
where id = object_id('t1')
open @test
fetch next from @test into @colName
while @@fetch_status = 0
begin
set @T1TableColumnList = @T1TableColumnList + @colName + ','
fetch next from @test into @colName
end
set @T1TableColumnList = left( @T1TableColumnList , len(@T1TableColumnList )-1)
close @test
deallocate @test
--Step 3 - Get the column list of Second table i.e. t2 and store into @T2TableColumnList variable
set @test = cursor for
select name from syscolumns
where id = object_id('t2')
open @test
fetch next from @test into @colName
while @@fetch_status = 0
begin
set @T2TableColumnList = @T2TableColumnList + @colName + ','
fetch next from @test into @colName
end
set @T2TableColumnList = left( @T2TableColumnList , len(@T2TableColumnList )-1)
close @test
deallocate @test
--Step 4 - Check the length of column list to add null columns or remove columns
--First table check
Declare @T1lengthofColumnList int
set @T1lengthofColumnList = (len(@T1TableColumnList) - len(replace(@T1TableColumnList, ',', '')) ) + 1
--add columns
if( @T1lengthofColumnList < @NoOfColumnForUnion)
Begin
While (@T1lengthofColumnList < @NoOfColumnForUnion)
Begin
set @T1lengthofColumnList = @T1lengthofColumnList + 1
Set @T1TableColumnList = @T1TableColumnList + ', null col' + cast( @T1lengthofColumnList as varchar(10))
End
End
--remove columns
Else if( @T1lengthofColumnList > @NoOfColumnForUnion)
Begin
While (@T1lengthofColumnList > @NoOfColumnForUnion)
Begin
set @T1lengthofColumnList = @T1lengthofColumnList - 1
Set @T1TableColumnList = LEFT(@T1TableColumnList, LEN(@T1TableColumnList) - CHARINDEX(',',REVERSE(@T1TableColumnList)))
End
End
--Second table check
Declare @T2lengthofColumnList int
set @T2lengthofColumnList = (len(@T2TableColumnList) - len(replace(@T2TableColumnList, ',', '')) ) + 1
--add columns
if( @T2lengthofColumnList < @NoOfColumnForUnion)
Begin
While (@T2lengthofColumnList < @NoOfColumnForUnion)
Begin
set @T2lengthofColumnList = @T2lengthofColumnList + 1
Set @T2TableColumnList = @T2TableColumnList + ', null col' + cast( @T2lengthofColumnList as varchar(10))
End
End
--remove columns
Else if( @T2lengthofColumnList > @NoOfColumnForUnion)
Begin
While (@T2lengthofColumnList > @NoOfColumnForUnion)
Begin
set @T2lengthofColumnList = @T2lengthofColumnList - 1
Set @T2TableColumnList = LEFT(@T2TableColumnList, LEN(@T2TableColumnList) - CHARINDEX(',',REVERSE(@T2TableColumnList)))
End
End
--Step 5 - create dynamic query and execute
DECLARE @template AS varchar(max)
SET @template = 'select ' + @T1TableColumnList + ' from t1 union all '
+ ' select ' + @T2TableColumnList + ' from t2 '
select @template
EXEC (@template)
--drop table t1
--drop table t2