我正在使用SQL Server,我想编写一个查询以将表1中的数据追加到表2中,该表中已经有一些数据。
这是我当前正在使用的,但这仅在列以完全相同的顺序完全相同时才起作用。我的2个表具有相同的列,但是顺序不同。有200多个列,所以我不想手动对其重新排序或在查询中列出它们。
INSERT INTO table2
SELECT * FROM table1
这是我可以做到的一种方法,但是有没有一种方法可以将table1中的数据追加到table2中而不必指定每一列?
INSERT INTO table2
SELECT column1, column2 (in the order of table2 columns)
FROM table1
答案 0 :(得分:0)
我同意Elaskanator关于明确列出您的列名的警告。但是,此方法将起作用。
在table1上创建一个具有table2列顺序的视图(vw_table1)。您将需要在视图中指定正确的列顺序。
INSERT INTO table2
SELECT * FROM vw_table1
如果您只需要用逗号分隔的列列表,则可以通过多种方式获得...
答案 1 :(得分:0)
使用exec
进行构建是一种不太整洁但可能实用的方法。 string_agg
仅在2017年可用
declare @col_names nvarchar(max) = (
select string_agg(column_name, ',')
from information_schema.columns
where table_name = N'table1'
)
exec ('insert into table2 (' + @col_names + ') select ' + @col_names + ' from table1')
对于SQL Server 2017之前的评论:
declare @col_names nvarchar(max)
select @col_names = ISNULL(@col_names + ', [' + column_name + ']', '[' + column_name + ']')
from information_schema.columns
where table_name = @dest
答案 2 :(得分:0)
永远不要编写缺少明确列列表的INSERT
语句,否则将来如果有人重新排序列(在表中间添加新列时也会发生这种情况) ),所有内容都会突然开始崩溃(希望如此,因为您可能最终会插入隐式转换一段时间的值,稍后导致随机故障,这将使您的生活陷入困境)。
如果您最关心的是列的数量庞大,这使得编写该语句非常困难(您是在水平存储数据还是在某种程度上保存数据?),请使用动态SQL来朝正确的方向前进:
DECLARE @TableName NVARCHAR(255) = N'MyBigassTable'--SET ME
DECLARE @ColumnList NVARCHAR(MAX) = NULL--build column list string
SELECT @ColumnList = ISNULL(@ColumnList + CHAR(13) + CHAR(10) + CHAR(9) + ',', CHAR(9) + ' ') + QUOTENAME(C.name)
FROM--ordering is guaranteed to match with the current table definition, presumably from clustered index on the sys.columns table?
sys.tables AS T
INNER JOIN sys.columns AS C ON
C.object_id = T.object_id
AND C.is_identity = 0--https://docs.microsoft.com/en-us/sql/t-sql/statements/set-identity-insert-transact-sql
AND C.is_computed = 0--https://docs.microsoft.com/en-us/sql/relational-databases/tables/specify-computed-columns-in-a-table
WHERE T.name = @TableName--beware if you have multiple schemas with the same table name
--form the insert statement
DECLARE @InsertQuery NVARCHAR(MAX) =
N'INSERT INTO ' + QUOTENAME(@TableName) + CHAR(13) + CHAR(10)
+'(' + CHAR(13) + CHAR(10)
+ @ColumnList + CHAR(13) + CHAR(10)
+ ')' + CHAR(13) + CHAR(10)
+ 'SELECT' + CHAR(13) + CHAR(10)
+ @ColumnList
--output results, handling maximum print size limitation
DECLARE @i INT = 1, @Step INT = 4000
WHILE @i < LEN(@InsertQuery) BEGIN
PRINT SUBSTRING(@InsertQuery, @i, @Step)--you will have to manually fix newlines created by PRINT batches
SET @i += @Step
END
抽样结果
INSERT INTO [MyBigassTable]
(
[ID]
,[Name]
...
)
SELECT
[ID]
,[Name]
...
请注意,CHAR(13) + CHAR(10)
是\r\n
(回车加换行符,或 Return ),而CHAR(9)
是\t
( Tab < / kbd>)。
现在根据需要自定义结果。