sql中行的级联拷贝
我在这里找到了这条线索: 我也有同样的问题。引述: Rob Pearmain写道:“我有3张表格,上面有问题 表1:问题 字段:ID(唯一)字段:名称(文本) 表2:问题文本(参考文献表1) 字段:ID(唯一)字段:QuestionID(表1 ID的整数引用) 字段:文本 表3:备选方案 字段:ID(唯一)字段:QuestionTextID(表2 ID的整数引用) 字段:文本 例如,我创建了一个问题,其中包含两个问题文本记录和 5个选项记录。如果我想把这个问题复制到一个新的 问题,并将问题文本记录复制到新ID,以及所有 相关选项,我如何能轻松做到这一点(如复制 问题将有一个新的ID,每个重复的问题文本 将具有新ID,每个选项也将具有新ID)。” 建议的解决办法是:sql中行的级联拷贝,sql,sql-server-2008,Sql,Sql Server 2008,我在这里找到了这条线索: 我也有同样的问题。引述: Rob Pearmain写道:“我有3张表格,上面有问题 表1:问题 字段:ID(唯一)字段:名称(文本) 表2:问题文本(参考文献表1) 字段:ID(唯一)字段:QuestionID(表1 ID的整数引用) 字段:文本 表3:备选方案 字段:ID(唯一)字段:QuestionTextID(表2 ID的整数引用) 字段:文本 例如,我创建了一个问题,其中包含两个问题文本记录和 5个选项记录。如果我想把这个问题复制到一个新的 问题,并将问题文本记
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
这个问题有更好的解决办法吗?我将使用插入触发器。
谢谢 这是另一种做同样事情的方法,稍微基于集合。在下面的示例中,我使用一个临时表在两个新表之间映射ID。另外,请从表名中删除空格(因为您可以删除空格并不意味着您应该删除空格) 您可以将语句与output子句一起使用,以在questionText中获得新旧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
我还没有仔细研究其余的逻辑,但请停止使用@IDENTITY-改用SCOPE\u IDENTITY()。所以问题有id和名称,您可以创建一个名称完全相同但具有新代理身份值的新问题?用户将如何区分他们-他们必须记住ID吗?我会的。我更关心光标,我在想有更好的方法,我不理解它的逻辑。光标是否应该实际显示questionid=@idtocopy的位置?您似乎混淆了一个名为“id”的列的用法。。。这个光标真的做了你期望的事情吗?你能展示一些样本数据和期望的结果吗?另外,您的数据类型真的是文本吗?您应该在SQLServer2008中使用VARCHAR或NVARCHAR。文本已被弃用。整洁的方法,但如果不将整个内容包装到事务中,则可能会失败。如果其他用户在运行此操作时试图复制或添加问题,则ID可能会失去同步。假设QuestionText.ID值是按顺序给出的(理论上无论如何),也可能有点危险。这就是我认为光标可能是解决此问题的最佳方法的原因之一。我也想到了这一点,但如果唯一的字段是问题文本,那么选项是否与包含相同文本的text1或text2配对,副本的最终结果是完全相同的。我同意交易方面的意见。合并为+1。这似乎是SQL Server 2008的最佳答案。
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