我正在尝试构建一个映射表,将表中的新行的ID与从其复制的行相关联。 OUTPUT INTO子句似乎是完美的,但它似乎没有根据文档的行为。
我的代码:
DECLARE @Missing TABLE (SrcContentID INT PRIMARY KEY ) INSERT INTO @Missing ( SrcContentID ) SELECT cshadow.ContentID FROM Private.Content AS cshadow LEFT JOIN Private.Content AS cglobal ON cshadow.Tag = cglobal.Tag WHERE cglobal.ContentID IS NULL PRINT 'Adding new content headers' DECLARE @Inserted TABLE (SrcContentID INT PRIMARY KEY,TgtContentID INT ) INSERT INTO Private.Content ( Tag,Description,ContentDate,DateActivate,DateDeactivate,SortOrder,CreatedOn,IsDeleted,ContentClassCode,ContentGroupID,OrgUnitID ) OUTPUT cglobal.ContentID,INSERTED.ContentID INTO @Inserted (SrcContentID,TgtContentID) SELECT Tag,NULL FROM Private.Content AS cglobal INNER JOIN @Missing AS m ON cglobal.ContentID = m.SrcContentID
导致错误消息:
Msg 207,Level 16,State 1,Line 34 Invalid column name 'SrcContentID'.
(第34行是带有OUTPUT INTO的)
实验表明,只能在OUTPUT INTO中选择INSERT目标中实际存在的行。但这与在线图书中的文档相矛盾。关于OUTPUT条款的文章具有描述类似用法的示例E:
The OUTPUT INTO clause returns values
from the table being updated
(WorkOrder) and also from the Product
table. The Product table is used in
the FROM clause to specify the rows to
update.
有没有人使用这个功能?
(在此期间,我重写了我的代码,使用光标循环来完成这项工作,但这很丑,而且我仍然很好奇)
解决方法
我已经验证了问题是您只能使用INSERTED列。文档似乎表明您可以使用from_table_name,但我似乎无法使其正常工作(多部分标识符“m.ContentID”无法绑定。):
TRUNCATE TABLE main SELECT * FROM incoming SELECT * FROM main DECLARE @Missing TABLE (ContentID INT PRIMARY KEY) INSERT INTO @Missing(ContentID) SELECT incoming.ContentID FROM incoming LEFT JOIN main ON main.ContentID = incoming.ContentID WHERE main.ContentID IS NULL SELECT * FROM @Missing DECLARE @Inserted TABLE (ContentID INT PRIMARY KEY,[Content] varchar(50)) INSERT INTO main(ContentID,[Content]) OUTPUT INSERTED.ContentID /* incoming doesn't work,m doesn't work */,INSERTED.[Content] INTO @Inserted (ContentID,[Content]) SELECT incoming.ContentID,incoming.[Content] FROM incoming INNER JOIN @Missing AS m ON m.ContentID = incoming.ContentID SELECT * FROM @Inserted SELECT * FROM incoming SELECT * FROM main
显然,from_table_name前缀只允许在DELETE或UPDATE(或2008年的MERGE)中 – 我不知道为什么:
> from_table_name
是一个列前缀,用于指定用于指定要更新或删除的行的DELETE或UPDATE语句的FROM子句中包含的表。
如果正在修改的表也在FROM子句中指定,则对该表中的列的任何引用必须使用INSERTED或DELETED前缀进行限定。