使用Merge.输出来获得Sourcee.id和Target t.id之间的映射非常简单,我有两个表来源和目标。declare @Source table (SourceID int identity(1,2), SourceName varchar(50))declare @Target table (TargetID int identity(2,2),
TargetName varchar(50))insert into @Source values ('Row 1'), ('Row 2')我想把所有的行从@Source到@Target并且知道TargetID每人SourceID因为还有表SourceChild和TargetChild这也需要复制,我需要添加新的TargetID进TargetChild.TargetIDFK柱对此有几个解决方案。使用while循环或游标一次插入一行(Rbar)并使用scope_identity()来填补.的FK.TargetChild.向@Target和插入SourceID..然后,您可以加入该列,以获取TargetID为FK在TargetChild.SET IDENTITY_INSERT OFF为@Target自己来分配新的价值观。你得到一个范围,然后你用在TargetChild.TargetID.我一点也不喜欢他们。到目前为止我用的是游标。我真正想做的是使用output插入语句的子句。insert into @Target(TargetName)output inserted.TargetID, S.SourceIDselect SourceNamefrom @Source as S但这是不可能的The multi-part identifier "S.SourceID" could not be bound.但合并是可能的。merge @Target as Tusing @Source as Son 0=1when not matched then
insert (TargetName) values (SourceName)output inserted.TargetID, S.SourceID;结果TargetID SourceID----------- -----------2 14 3我想知道你有没有用过这个?如果你对解决方案有任何想法,或者看到有什么问题吗?它在简单的场景中运行良好,但是当查询计划由于复杂的源查询而变得非常复杂时,可能会发生一些丑陋的事情。最糟糕的情况是TargetID/SourceID对实际上不匹配。MSDN有关于from_table_name.的.输出量条款。列前缀,它指定DELETE、UPDATE或Merge语句的FROM子句中包含的表,用于指定要更新或删除的行。出于某种原因,他们没有说“要插入、更新或删除的行”,而是要更新或删除的行。任何想法都是受欢迎的,完全不同的解决方案是非常感谢的。
2 回答
蝴蝶不菲
TA贡献1810条经验 获得超4个赞
DECLARE @FolderIndex TABLE (FolderId UNIQUEIDENTIFIER PRIMARY KEY, FolderName varchar(25));INSERT INTO @FolderIndex
(FolderId, FolderName)
VALUES(newid(), 'OriginalFolder');DECLARE @FileIndex TABLE (FileId int identity(1,1) PRIMARY KEY, FileName varchar(10));
INSERT INTO @FileIndex
(FileName)
VALUES('test.txt');DECLARE @FileFolder TABLE (FolderId UNIQUEIDENTIFIER, FileId int, PRIMARY KEY(FolderId, FileId));
INSERT INTO @FileFolder
(FolderId, FileId)
SELECT FolderId,
FileId FROM @FolderIndex CROSS JOIN @FileIndex; -- just to illustrateDECLARE @sFolder TABLE
(FromFolderId UNIQUEIDENTIFIER, ToFolderId UNIQUEIDENTIFIER);DECLARE @sFile TABLE (FromFileId int, ToFileId int);
-- copy Folder StructureMERGE @FolderIndex fiUSING ( SELECT 1 [Dummy],
FolderId,
FolderName FROM @FolderIndex [fi]
WHERE FolderName = 'OriginalFolder'
) d ON d.Dummy = 0WHEN NOT MATCHED THEN INSERT
(FolderId, FolderName)
VALUES (newid(), 'copy_'+FolderName)OUTPUT d.FolderId,
INSERTED.FolderIdINTO @sFolder (FromFolderId, toFolderId);-- copy File structureMERGE @FileIndex fiUSING
( SELECT 1 [Dummy],
fi.FileId,
fi.[FileName]
FROM @FileIndex fi INNER
JOIN @FileFolder fm ON
fi.FileId = fm.FileId INNER
JOIN @FolderIndex fo ON
fm.FolderId = fo.FolderId WHERE fo.FolderName = 'OriginalFolder'
) d ON d.Dummy = 0WHEN NOT MATCHED THEN INSERT ([FileName])
VALUES ([FileName])OUTPUT d.FileId,
INSERTED.FileIdINTO @sFile (FromFileId, toFileId);-- link new files to FoldersINSERT INTO @FileFolder (FileId, FolderId)
SELECT sfi.toFileId, sfo.toFolderId FROM @FileFolder fm INNER
JOIN @sFile sfi ON
fm.FileId = sfi.FromFileId INNER
JOIN @sFolder sfo ON
fm.FolderId = sfo.FromFolderId-- return SELECT * FROM @FileIndex fi
JOIN @FileFolder ff ON
fi.FileId = ff.FileId
JOIN @FolderIndex fo ON
ff.FolderId = fo.FolderId添加回答
举报
0/150
提交
取消
