简体   繁体   中英

Union all if the table exists in SQL server 2008

In the below code, I need to check if the table exists in each line. Please tell me how to do it.

Select * from Table 1 union all
select * from Table 2 union all
Select * from Table 3

I tried this but didn't work

if objectid ('Table1') is not null
Select * from Table 1 union all
if objectid ('Table2') is not null
select * from Table 2 union all
if objectid ('Table3') is not null
Select * from Table 3

A possible solution would be this:

USE MyDB;

DECLARE @recordsExistingTables TABLE(Column1 nvarchar(50), Column2 nvarchar(50));

IF (EXISTS (SELECT * 
                 FROM INFORMATION_SCHEMA.TABLES 
                 WHERE TABLE_SCHEMA = 'dbo' 
                 AND  TABLE_NAME = 'Table1'))
BEGIN
   INSERT INTO @recordsExistingTables 
   SELECT *
   FROM Table1; 
END 

IF (EXISTS (SELECT * 
                 FROM INFORMATION_SCHEMA.TABLES 
                 WHERE TABLE_SCHEMA = 'dbo' 
                 AND  TABLE_NAME = 'Table2')) 
BEGIN
   INSERT INTO @recordsExistingTables 
   SELECT *
   FROM Table2; 
END 

IF (EXISTS (SELECT * 
                 FROM INFORMATION_SCHEMA.TABLES 
                 WHERE TABLE_SCHEMA = 'dbo' 
                 AND  TABLE_NAME = 'Table3')) 
BEGIN
   INSERT INTO @recordsExistingTables 
   SELECT *
   FROM Table3; 
END 


SELECT * FROM @recordsExistingTables;

Using a table variable, you insert only the rows of the tables that exist in your database. At the end of the checks, selecting the records of the table variable, you have the rows of each existing table.

Tried to create a sort of generic solution. Created a procedure, where you have to pass all table names in comma separated values and it will return the complete data list of all tables.

Create Procedure spGetTableData
@tableNames varchar(4000) --expecting all table names in csv format here
As
Begin
declare @sql nvarchar(max);
declare @tablelist table(tablename varchar(50));

--getting all existint table names in one table
set @sql = 'select name from sys.objects where name in (''' + REPLACE(@tableNames, ',',''',''') + ''')';

insert into @tablelist
exec (@sql);

--creating query with union all
set @sql = '';
select @sql = @sql + 'Select * from ' + tablename + ' Union All ' From @tablelist;

set @sql = left(@sql, len(@sql) - 9);

exec sp_executesql @sql;

End

You can execute this as :

Exec spGetTableData 'existing1,nonexisting1,existing2,existing3'

Hope it helps.

The tables do not exist so you will need to build the select statement dynamically. Here is an example of what you would need to do. I am not going to reproduce all the if statements as there would be 9 different combinations but you should get the general idea.

    if objectid ('Table2') is not null AND objectid ('Table1') IS not null and objectid('Table3') is not null 
    @SelectStatement = 'Select * from Table1 UNION ALL SELECT * FROM TABLE2 UNION ALL SELECT * FROM TABLE3' 

    if objectid ('Table2') is not null AND objectid ('Table1') IS not null and objectid ('Table3') is null 
    @SelectStatement = 'Select * from Table1 UNION ALL SELECT * FROM TABLE2 ' 

    if objectid ('Table2') is not null AND objectid ('Table1') IS null and objectid ('Table3') is not null 
    @SelectStatement = 'Select * from Table2 UNION ALL SELECT * FROM TABLE3 ' 

    if objectid ('Table2') is null AND objectid ('Table1') IS NOT null and objectid ('Table3') is not null 
    @SelectStatement = 'Select * from Table1 UNION ALL SELECT * FROM TABLE3 ' 

    if objectid ('Table2') is null AND objectid ('Table1') IS null and objectid ('Table3') is not null 
    @SelectStatement = 'SELECT * FROM TABLE3 ' 

    if objectid ('Table2') is null AND objectid ('Table1') IS null and objectid ('Table3') is not null 
    @SelectStatement = 'SELECT * FROM TABLE3 ' 

//..... for 3 tables there will be 9 conbinations of TABLE1, TABLE2 and TABLE3 is null checks to perform and possible combinations

EXECUTE sp_executesql @FullStatement

It is worth noting that a union requires all columns to match in type, as well as having the same number of columns.

Assuming that they do match (if they exist), and that you have a fixed number of tables, the following query works:

declare @sql varchar(max)

if object_id('Table1') is not null
Begin
  set @sql = 'select * from Table1'
end 


if object_id('Table2') is not null
Begin
   if len(@sql) > 0 
   begin
      set @sql = @sql + char(10) + 'union all '
   end
  set @sql = @sql + 'select * from Table2'
end 


if object_id('Table3') is not null
Begin
   if len(@sql) > 0 
   begin
      set @sql = @sql + char(10) + 'union all '
   end
  set @sql = @sql + 'select * from Table3'
end 


execute(@sql)

This works by first creating a dynamic SQL statement, and storing it in the @SQL variable. when done evaluating/creating the statement, it is executed using the execute(@sql) statement

Just as an alternative, and in no way am I suggesting this is the best way to do it, but for my own curiosity I wondered if a CASE could do this. Turns out it can. Probably no more or less clunky than any other solution.

SET CONCAT_NULL_YIELDS_NULL OFF
DECLARE @sql NVARCHAR(4000)
SELECT @sql = CASE WHEN name = 'table1' THEN 'select * from table1 ' END FROM sys.tables WHERE name = 'table1'

SELECT @sql += CASE WHEN @sql IS NOT NULL AND name = 'table2' THEN ' union all select * from table2' WHEN @sql IS NULL AND name = 'table2' THEN 'select * from table2' END FROM sys.tables WHERE name = 'table2'

SELECT @sql += CASE WHEN @sql IS NOT NULL AND name = 'table3' THEN ' union all select * from table3' WHEN @sql IS NULL AND name = 'table3' THEN 'select * from table3' END FROM sys.tables WHERE name = 'table3'

PRINT @sql

EXEC sp_executesql @sql

You can see it working on this Fiddle (except the sp_executesql bit - SQLFiddle won't return results from that).

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