繁体   English   中英

sql 中行的级联副本

[英]Cascade copy of rows in sql

我在这里找到了这个帖子: http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=16836我有完全相同的问题。 引用:

Rob Pearmain 写道:“我有 3 个表格来存放问题。

表 1:问题

字段:ID(唯一) 字段:名称(文本)

表 2:问题文本(参考 Table1-ID)

字段:ID(唯一) 字段:QuestionID(整数引用到 Table1 ID) 字段:文本

表 3:选项

字段:ID(唯一) 字段:QuestionTextID(整数引用到 Table2 ID) 字段:文本

例如,我创建了一个包含 2 个问题文本记录和 5 个选项记录的问题。 如果我想将该问题复制到一个新问题,并将问题文本记录复制到新 ID 以及所有相关选项,我该如何轻松地做到这一点(因为重复的问题将有一个新的 ID,每个重复的问题文本和每个选项都会有新的 ID)。”

建议的解决方案是:

create procedure CopyQuestion
@idtocopy int
AS
declare @tempquestionid
declare @tempquestiontextid
declare @questiontextid

insert into question (name)
     select name from question where id = @idtocopy

select @tempquestionid = @@identity

declare question_cursor cursor for
     select id from [question text] where id = @idtocopy
open question_cursor
fetch next from question_cursor into @questiontextid
while @@fetch_status = 0
begin
   insert into [question text] (questionid, text)
      select @tempquestionid, text from [question text] where id = @questiontextid
   select @tempquestiontextid = @@identity
      insert into [options] (questiontextid, text)
   select @tempquestiontextid, text from [options] where questiontextid = @questiontextid
   fetch next from question_cursor into @questiontextid
end
close question_cursor
deallocate question_cursor

这个问题有更好的解决方案吗? 我将使用插入触发器。 谢谢!

您可以使用带有 output 子句的合并语句来获取 questionText 中新旧 id 之间的匹配。 这在这个问题中有所描述Using merge..output to get mapping between source.id and target.id

在您的情况下,代码看起来像这样。 该代码未经测试,因此可能存在任何数量的拼写错误,但它显示了您可以做什么。

create procedure CopyQuestion
  @idtocopy int
as

declare @QuestionID int

insert into question
select Name 
from question 
where ID = @idtocopy

select @QuestionID = scope_identity() 

declare @IDs table (NewQID int, OldQID int)

merge questionText as T
using (select ID, @QuestionID as QuestionID, Field
       from questionText
       where QuestionID = @idtocopy) as S
on 0=1
when not matched then
  insert (QuestionID, Field) values (QuestionID, Field)
output inserted.ID, S.ID   into @IDs;       

insert into options
select 
    I.NewQID,
    O.Field
from options O
  inner join @IDs as I
    on O.QuestionTextID = I.OldQID

这是另一种方式来做同样的事情多一点基于集合。 在下面的示例中,我使用了一个临时表来 map 两个新表之间的 ID。 另外请从您的表名中删除空格(仅仅因为您可以并不意味着您应该这样做)。

CREATE PROCEDURE udf_COPY_QUESTION 
@ID_TO_COPY int
 as 
BEGIN TRANSACTION
BEGIN TRY
DECLARE @NEW_QUESTION_ID INT, @MAX_ID INT
insert into question (name)
     select name from question where id = @ID_TO_COPY
SET @NEW_QUESTION_ID = SCOPE_IDENTITY()
SET @MAX_ID =IDENT_CURRENT( 'question text' )
select @NEW_QUESTION_ID AS questionid,
       Text,
       ROW_NUMBER() OVER (ORDER NAME) + @MAX_ID as new_text_id, 
       id as old_text_id
 INTO  #TEMP  from [question text] 
      where questionid = @ID_TO_COPY         
insert into [question text] (QuestionID,Text)
      select questionid,Text from #TEMP 
      order by new_text_id
insert into Options  (questiontextid, text) 
      select t.new_text_id,o.Text from options o
      inner join #temp t on t.old_text_id = o.questiontextid
COMMIT TRANSACTION
END TRY
BEGIN CATCH
    RAISERROR('COPY FAILED',10,1)
    ROLLBACK TRANSACTION 
END CATCH    

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM