我正在尝试构建一个映射表,以便将表中新行的in与从中复制它们的in关联起来。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, Description, ContentDate, DateActivate, DateDeactivate, SortOrder, CreatedOn, IsDeleted, ContentClassCode, ContentGroupID, 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中被选择。但这与在线书籍中的文档相矛盾。关于输出子句的文章中有一个示例E,它描述了类似的用法:
OUTPUT INTO子句返回被更新的表(WorkOrder)和Product表中的值。在FROM子句中使用Product表来指定要更新的行。
有没有人用过这个功能?
(在此期间,我重写了我的代码,使用游标循环来完成这项工作,但这很丑陋,我仍然很好奇)
发布于 2008-10-01 05:35:22
我已经验证了问题在于您只能使用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
前缀限定对该表中列的任何引用。
发布于 2011-03-25 02:14:56
您可以在Sql Server2008中使用MERGE来完成此操作。示例代码如下:
--drop table A
create table A (a int primary key identity(1, 1))
insert into A default values
insert into A default values
delete from A where a>=3
-- insert two values into A and get the new primary keys
MERGE a USING (SELECT a FROM A) AS B(a)
ON (1 = 0) -- ignore the values, NOT MATCHED will always be true
WHEN NOT MATCHED THEN INSERT DEFAULT VALUES -- always insert here for this example
OUTPUT $action, inserted.*, deleted.*, B.a; -- show the new primary key and source data
结果是
INSERT, 3, NULL, 1
INSERT, 4, NULL, 2
即对于每一行,新的主键(3,4)和旧的主键(1,2)。例如,创建一个名为#OUTPUT的表,并在OUTPUT子句的末尾添加“INTO #OUTPUT;”可以保存记录。
发布于 2009-03-18 16:48:48
我遇到了和你完全一样的问题,我感受到了你的痛苦...据我所知,没有办法在INSERT语句中使用from_table_name前缀。我相信这有一个可行的技术原因,我很想知道它到底是什么。
好了,找到了,这是一个论坛帖子,解释为什么它不能工作:MSDN forums
https://stackoverflow.com/questions/155321
复制相似问题