Это так близко, чтобы установить на основе, как я могу это сделать. Проблема в том, что мы не можем знать, какие новые значения идентичности будут назначены до тех пор, пока строки не будут фактически в таблице. Таким образом, невозможно вставить все строки за один раз с правильными родительскими значениями.
Я использую MERGE
ниже, так что я могу получить доступ как источник и inserted
таблицы в предложении OUTPUT
, которое не позволило INSERT
заявления:
declare @FromUserID int
declare @ToUserID int
declare @ToCopy table (OldParentID int,NewParentID int)
declare @ToCopy2 table (OldParentID int,NewParentID int)
select @FromUserID = 1,@ToUserID = 2
merge into T1 t
using (select Folder_ID,Parent_Folder_ID,Folder_Name
from T1 where User_ID = @FromUserID and Parent_Folder_ID is null) s
on 1 = 0
when not matched then insert (Parent_Folder_ID,Folder_Name,User_ID)
values (NULL,s.Folder_Name,@ToUserID)
output s.Folder_ID,inserted.Folder_ID into @ToCopy (OldParentID,NewParentID);
while exists (select * from @ToCopy)
begin
merge into T1 t
using (select Folder_ID,p2.NewParentID,Folder_Name from T1
inner join @ToCopy p2 on p2.OldParentID = T1.Parent_Folder_ID) s
on 1 = 0
when not matched then insert (Parent_Folder_ID,Folder_Name,User_ID)
values (NewParentID,Folder_Name,@ToUserID)
output s.Folder_ID,inserted.Folder_ID into @ToCopy2 (OldParentID,NewParentID);
--This would be much simpler if you could assign table variables,
-- @ToCopy = @ToCopy2
-- @ToCopy2 = null
delete from @ToCopy;
insert into @ToCopy(OldParentID,NewParentID)
select OldParentID,NewParentID from @ToCopy2;
delete from @ToCopy2;
end
(я также написал это на предположение о том, что мы никогда не хотим иметь строки в таблице с неправильными или отсутствующими родительскими ценностями)
в случае логик не ясен - мы сначала находим строки для старого пользователя, у которых нет родителей - те e мы можем четко скопировать для нового пользователя немедленно. На основе этой вставки мы отслеживаем, какие новые значения идентичности были присвоены, с которым старое значение идентичности.
Затем мы продолжаем использовать эту информацию для идентификации следующего набора строк для копирования (в @ToCopy
) - поскольку строки, родители которых были просто скопированы, являются следующим набором, подлежащим копированию. Мы зацикливаемся до тех пор, пока не создадим пустой набор, а это означает, что все строки были скопированы.
Это не соответствует родительским/дочерним циклам, но, надеюсь, у вас их нет.
Является ли ваш '' Folder_ID' в колонку IDENTITY'? –
Да, это столбец идентичности. – user3398663
Вы хотите сказать, что пользователь1 может иметь родительскую папку как папку user2? –