[英]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.