SQL Server:查询将数据从具有不同结构的另一个表插入到表中

时间:2014-07-31 06:54:58

标签: sql sql-server

我在两个不同的数据库中有两个表。

我的第一个表是旧版本,列数少于第二个表。

我想将旧表的内容复制到新表中。

在每种数据库表中,在这种情况下有几种分布。

如何在不必为每个表手动编写列名的情况下快速将数据从旧表复制到新表?

谢谢!

4 个答案:

答案 0 :(得分:1)

您可以“避免手动编写列名称"在SSMS中通过拖放"列"对象资源管理器中的表下的文件夹到查询窗口(只需将拖动的项目保持在空格或要显示名称的字符位置)。所有列名称将以逗号分隔显示。

SSMS Table Columns folder

您也可以尝试这样的方法来获取两个表之间通用的列列表(然后编写INSERT语句很简单)。

SELECT
   Substring((
      SELECT
         ', ' + S.COLUMN_NAME
      FROM
         INFORMATION_SCHEMA.COLUMNS S
         INNER JOIN INFORMATION_SCHEMA.COLUMNS D
            ON S.COLUMN_NAME = D.COLUMN_NAME
      WHERE
         S.TABLE_SCHEMA = 'dbo'
         AND S.TABLE_NAME = 'Source Table'
         AND D.TABLE_SCHEMA = 'dbo'
         AND D.TABLE_NAME = 'Destination Table'
      FOR XML PATH(''), TYPE
  ).value('.[1]', 'nvarchar(max)'), 3, 21474783647)
;

您还可以创建一个SSIS包,只需将所有数据从一个表移动到另一个表。匹配的列名将自动链接。根据您对SSIS的熟悉程度,这可能需要2分钟,或者可能需要2个小时。

答案 1 :(得分:0)

以下代码应该完成这项工作。 基本上它的作用是:

1。从两个表中收集列名称  2.将列名相交,以过滤掉仅存在于1个表中的列  3.获取一个字符串,该字符串是由逗号分隔的列名  4.使用阶段#3中的字符串创建插入命令  5.执行第4阶段的命令。

--BEGIN TRAN

DECLARE @oldName NVARCHAR(50) = 'OldTableName', @newName NVARCHAR(50) = 'newTableName'
DECLARE @oldDBName NVARCHAR(50) = '[OldDBName].[dbo].['+@oldName+']', @newDBName NVARCHAR(50) = '[newDBName].[dbo].['+@newName+']'

/*This table variable will have columns that exists in both table*/
DECLARE @tCommonColumns TABLE(
ColumnsName NVARCHAR(max) NOT NULL
);

INSERT INTO @tCommonColumns

SELECT column_name --,*
FROM information_schema.columns
WHERE table_name = @oldName
AND COLUMNPROPERTY(object_id(@oldName), column_name, 'IsIdentity') = 0 --this will make sure you ommit IDentity columns

INTERSECT

SELECT column_name --, *
FROM information_schema.columns
WHERE table_name = @newName
AND COLUMNPROPERTY(object_id(@newName), column_name,'IsIdentity') = 0--this will make sure you ommit IDentity columns

--SELECT * FROM @tCommonColumns

/*Get the columns as a comma seperated string */
DECLARE @columns NVARCHAR(max)
SELECT DISTINCT 
                @columns  = STUFF((SELECT ', ' + cols.ColumnsName
                                    FROM @tCommonColumns cols

                                      FOR XML Path('')),1,1,'')
FROM @tCommonColumns
PRINT @columns 
/*Create tyhe insert command*/
DECLARE @InserCmd NVARCHAR(max)
SET @InserCmd = 
'INSERT INTO '+@newDBName +' ('+@columns +')
SELECT '+@columns +' FROM '+@oldDBName

PRINT @InserCmd
/*Execute the command*/
EXECUTE sp_executesql @InserCmd
--ROLLBACK

请注意,如果FOREIGN KEY Constraints已在旧表中实现但未在新表中实现,则此脚本可能会失败。

修改
该查询已更新为省略Identity列。

编辑2:
更新了查询以支持表的不同数据库(请确保设置@oldName@newName@oldDBName@newDBName变量以匹配实际凭据。

答案 2 :(得分:0)

全部谢谢!

我建议它更通用:)

--BEGIN TRAN
DECLARE @Tablename NVARCHAR(50)
SET @Tablename = 'tableName'

DECLARE @Schemaname NVARCHAR(50)
SET @Schemaname = 'schemaName'

DECLARE @Datasource NVARCHAR(50)
SET @Datasource = 'dataSource'

DECLARE @Datadest NVARCHAR(50)
SET @Datadest = 'dataDestination'

/*This table variable will have columns that exists in both table*/
DECLARE @tCommonColumns TABLE(
ColumnsName NVARCHAR(max) NOT NULL
);

--INSERT INTO @tCommonColumns
DECLARE @sql NVARCHAR(max)
SET @sql = 'SELECT column_name
            FROM ' + @Datasource + '.information_schema.columns
            WHERE table_name = ''' + @Tablename + '''
            AND COLUMNPROPERTY(object_id(''' + @Datasource + '.' + @Schemaname + '.' + @Tablename + '''), column_name, ''IsIdentity'') = 0' --this will make sure you ommit IDentity columns

SET @sql = @sql + ' INTERSECT
            SELECT column_name
            FROM ' + @Datadest + '.information_schema.columns
            WHERE table_name = ''' + @Tablename + '''
            AND COLUMNPROPERTY(object_id(''' + @Datadest + '.' + @Schemaname + '.' + @Tablename + '''), column_name, ''IsIdentity'') = 0' --this will make sure you ommit IDentity columns'

INSERT INTO @tCommonColumns EXECUTE sp_executesql @sql

-- SELECT * FROM @tCommonColumns

/*Get the columns as a comma seperated string */
DECLARE @columns NVARCHAR(max)
SELECT DISTINCT 
                @columns  = STUFF((SELECT ', ' + cols.ColumnsName
                                    FROM @tCommonColumns cols

                                      FOR XML Path('')),1,1,'')
FROM @tCommonColumns
--PRINT @columns 
/*Create tyhe insert command*/
DECLARE @InserCmd NVARCHAR(max)
SET @InserCmd = 
'INSERT INTO '+@Datadest+'.'+@Schemaname+'.'+@Tablename +' ('+@columns +')
SELECT '+@columns +' FROM '+@Datasource+'.'+@Schemaname+'.'+@Tablename

PRINT @InserCmd
/*Execute the command*/
--EXECUTE sp_executesql @InserCmd
--ROLLBACK

答案 3 :(得分:-2)

这样的事情:

Insert into dbo.Newtbl 

SELECT * FROM dbo.OldTbl