我正在尝试运行代码,使用来自不同数据库的不同表中的行从一个表插入行 我有这个:
INSERT [testDB].[dbo].[table1]
SELECT * FROM
[sourceDB].[dbo].[table1]
LEFT OUTER JOIN [testDB].[dbo].[table1]
ON [sourceDB].[dbo].[table1].[PKcolumn] = [testDB].[dbo].[table1].[PKcolumn]
WHERE [testDB].[dbo].[table1].[PKcolumn] IS NULL
但是我被告知要添加相关名称,所以我做了这个:
INSERT test
SELECT * FROM
[sourceDB].[dbo].[table1] as source
LEFT OUTER JOIN
[testDB].[dbo].[table1] as test
ON
source.[PKcolumn] = test.[PKcolumn]
WHERE test.[PKcolumn] IS NULL
我最终将此视为错误消息:
Msg 208,Level 16,State 1,Line 1 无效的对象名称'test'。
有谁知道我做错了什么?
答案 0 :(得分:1)
在第一行中,您应该使用实际表名称,如
insert into testDB.dbo.table1
SQLServer不接受该位置的别名或相关名称,我通过测试确认了这一点。
但是您可以在查询中稍后使用别名,这样做非常有用,可以避免关于列来自哪个表格的模糊性。
此查询中的另一个潜在问题是使用select *。这会尝试将sourcedb.dbo.table1和testdb.dbo.table1中的组合列集插入testdb.dbo.table1。那不行。
而不是选择*你可以说...(假设源和测试具有完全相同的列)
select source.*
或者您可以在...中调出特定的列
select source.colA, source.col3, etc....
我不知道你的专栏名称。
答案 1 :(得分:0)
INSERT test
SELECT *
FROM [sourceDB].[dbo].[table1] as source
LEFT OUTER JOIN [testDB].[dbo].[table1] as test
ON source.[PKcolumn] = test.[PKcolumn]
WHERE test.[PKcolumn] IS NULL
让我们谈谈这有什么问题。首先选择*将包含源和测试中的所有列,这显然比您计划插入的表中的列多。由于多种原因,在insert语句中使用select *是绝对不可接受的。
首先,如果有人更改了列的顺序或表的结构,则插入会中断。其次,当你有这样的连接时,它的列数就是错误的。第三,即使它们在不同的顺序中具有相同的列,您也可以将数据放入worng列。如果它们是相似的数据类型并且数据适合或可以进行隐含转换,则数据库不会阻止您执行此操作。
接下来,您不能使用select中的别名作为插入中的目标,您必须引用实际的表名。
最后,在每个插入中不使用列列表是一种非常糟糕的做法。这有助于维护,并确保您可以检查列中的列是否与插入中的列匹配。此外,如果您有自动生成的字段,则必须使用列列表,否则它将尝试插入自动生成的字段,从而出错。
所以你的陈述应该是这样的:
INSERT [testDB].[dbo].[table1] (field1, field2, field3)
SELECT source.field1, source.field2, source.field3
FROM [sourceDB].[dbo].[table1] as source
LEFT OUTER JOIN [testDB].[dbo].[table1] as test
ON source.[PKcolumn] = test.[PKcolumn]
WHERE test.[PKcolumn] IS NULL
或者(可能更有效率,您必须在特定情况下进行测试):
INSERT [testDB].[dbo].[table1] (field1, field2, field3)
SELECT source.field1, source.field2, source.field3
FROM [sourceDB].[dbo].[table1] as source
WHERE NOT EXISTS (SELECT * FROM testDB].[dbo].[table1] test
WHERE source.[PKcolumn]=test.[PKcolumn])