Очень упрощенно, у меня есть две таблицы Source и Target.
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.TargetID
FK.
Для этого есть несколько решений.
- Используйте цикл или курсоры while для вставки одной строки (RBAR) в Target за раз и используйте
scope_identity()
для заполненияФК TargetChild
. - Добавьте временный столбец к
@Target
и вставьте SourceID
.Затем вы можете присоединиться к этому столбцу, чтобы получить TargetID
для FK в TargetChild
. SET IDENTITY_INSERT OFF
для @Target
и обрабатывать назначение новых значений самостоятельно.Вы получаете диапазон, который затем используете в TargetChild.TargetID
.
. Я не очень люблю их.Я использовал до сих пор курсоры.
Что я действительно хотел бы сделать, так это использовать выражение output
оператора вставки.
insert into @Target(TargetName)
output inserted.TargetID, S.SourceID
select SourceName
from @Source as S
Но это невозможно
The multi-part identifier "S.SourceID" could not be bound.
Но это возможно при слиянии.
merge @Target as T
using @Source as S
on 0=1
when not matched then
insert (TargetName) values (SourceName)
output inserted.TargetID, S.SourceID;
Результат
TargetID SourceID
----------- -----------
2 1
4 3
Я хочу знать, использовали ли вы это?Если у вас есть мысли по поводу решения или вы видите какие-либо проблемы с ним?Он отлично работает в простых сценариях, но, возможно, что-то ужасное может произойти, когда план запроса действительно усложняется из-за сложного исходного запроса.В худшем случае пары TargetID / SourceID на самом деле не совпадают.
В MSDN есть это, чтобы сказать о from_table_name
предложения output .
Префикс столбца, который указывает таблицу, включенную в предложение FROMоператор DELETE, UPDATE или MERGE, который используется для указания строк, которые нужно обновить или удалить.
По какой-то причине они не говорят «строки для вставки, обновления или удаления« только »строк вобновить или удалить ".
Любые мысли приветствуются, и совершенно разные решения оригинальной проблемы высоко ценится.