如果不存在,则检查列是否存在为该列分配空值

时间:2014-09-18 06:53:30

标签: sql-server sql-server-2008 sql-server-2005 sql-server-2008-r2 sql-server-2012

我对SQL有一个小问题 - 当将数据从一个表加载到另一个表时,我遇到了一个问题。

第一张表:emp

id | name | sal | deptno | loc  | referby
----------------------------------------
 1 | abc  | 100 |   10   | hyd  | xyz
 2 | mnc  | 200 |   20   | chen | pqr 

第二张表:emprefers

id | name | sal | deptno | loc | referby

现在我想将加载emp表数据加载到emprefers表中,那时我会编写像

这样的查询
insert into emprefers 
    select * 
    from emp

运行此查询后,数据将加载到如下所示的内容中:

id | name | sal | deptno | loc  |referby
----------------------------------------
 1 | abc  | 100 |   10   | hyd  | xyz
 2 | mnc  | 200 |   20   | chen | pqr 

现在我第二次运行相同的查询,但失败了。原因是名称列从emp表中删除

现在我编辑像

这样的查询
insert into emprefers 
    select 
        id, 'null' as name, sal, deptno, loc, referby 
    from emp

编辑查询后,我运行了它 - 现在记录被加载到emprefers表中,数据看起来像

id  | name  | sal | deptno | loc   | referby
--------------------------------------------
 1  | null  | 100 |   10   | hyd   | xyz
 2  | null  | 200 |   20   | chen  | pqr 

每次加载emprefers表之前,我都会截断emprefers表数据。 并且emprefers表结构从未改变过。

再次,第三次我再次运行相同的查询查询失败原因在emp表中缺少sal,deptno列

现在我不想再次编辑查询原因是我们不知道从emp表中删除了哪些列。那时我们要解决问题并且我们想要将数据加载到

第二个表如果emp表中可用的列然后加载数据,我们需要为该列传递null或空值。

如果存在检索列,请告诉我如何编写查询以检查列是否存在,否则为该列分配空值。

3 个答案:

答案 0 :(得分:0)

快速解决方法是使用以下查询,因为您的表格结构没有变化。如果它发生变化,则需要更多的工作。

DECLARE @sql nvarchar(max) = N''

IF EXISTS(SELECT 1 FROM sys.columns c WHERE c.object_id = OBJECT_ID(N'emp') AND c.name = 'id')
    SET @sql = @sql + ', id'

IF EXISTS(SELECT 1 FROM sys.columns c WHERE c.object_id = OBJECT_ID(N'emp') AND c.name = 'name')
    SET @sql = @sql + ', name'

IF EXISTS(SELECT 1 FROM sys.columns c WHERE c.object_id = OBJECT_ID(N'emp') AND c.name = 'sal')
    SET @sql = @sql + ', sal'

IF EXISTS(SELECT 1 FROM sys.columns c WHERE c.object_id = OBJECT_ID(N'emp') AND c.name = 'deptno')
    SET @sql = @sql + ', deptno'

IF EXISTS(SELECT 1 FROM sys.columns c WHERE c.object_id = OBJECT_ID(N'emp') AND c.name = 'loc')
    SET @sql = @sql + ', loc'

IF EXISTS(SELECT 1 FROM sys.columns c WHERE c.object_id = OBJECT_ID(N'emp') AND c.name = 'referby')
    SET @sql = @sql + ', referby'

SET @sql = 'INSERT INTO emprefers (' + STUFF(@sql, 1, 2, '') + ') SELECT * FROM emp'

PRINT @sql
EXEC(@sql)

答案 1 :(得分:0)

您可以使用Cross Apply

SELECT x.*
FROM (SELECT NULL AS id,null as name,null as sal,null as deptno, null as loc,null as referby) AS dummy
CROSS APPLY
(
  SELECT
   id,name,sal,deptno,loc,referby
  FROM dbo.emprefers
) AS x;

已在http://sqlfiddle.com/#!3/f2e558/4

进行测试

答案 2 :(得分:0)

我不相信做这样的事情是个好主意,因为名字可能已经改变了键可能存在等等。 但这应该做你需要的:

Create Procedure P_Insert4ExisitingFields(@Source varchar(255),@Dest varchar(255)) as

DECLARE @SQL VARCHAR(max)
-- collect all columns existing in both tables
Select @SQL = @SQL + '['+ a.name+'],' from
(
Select s.name from sys.syscolumns s
Join sysobjects m ON m.xtype ='U' and m.Name=@Source and s.id=m.ID
) a
JOIN
(
Select s.name from sys.syscolumns s
Join sysobjects m ON m.xtype ='U' and m.Name=@Dest and s.id=m.ID
) b on a.name=b.name 
--strip last ,
Select @SQL = SubString(@SQL,1,len(@SQL)-1)

Select @SQL = 'INSERT into [' + @Dest + '] ('+@SQL+') Select '+@SQL+' from [' + @Source +']'
--PRINT @SQL
EXEC (@SQL)

示例调用将是:

P_Insert4ExisitingFields  'emp','emprefers'

分配NULL值不是必需的,因为这应该是字段的默认值。