Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
sql中行的级联拷贝_Sql_Sql Server 2008 - Fatal编程技术网

sql中行的级联拷贝

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个选项记录。如果我想把这个问题复制到一个新的 问题,并将问题文本记

我在这里找到了这条线索: 我也有同样的问题。引述:

Rob Pearmain写道:“我有3张表格,上面有问题

表1:问题

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

表2:问题文本(参考文献表1)

字段:ID(唯一)字段:QuestionID(表1 ID的整数引用) 字段:文本

表3:备选方案

字段:ID(唯一)字段:QuestionTextID(表2 ID的整数引用) 字段:文本

例如,我创建了一个问题,其中包含两个问题文本记录和 5个选项记录。如果我想把这个问题复制到一个新的 问题,并将问题文本记录复制到新ID,以及所有 相关选项,我如何能轻松做到这一点(如复制 问题将有一个新的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
这个问题有更好的解决办法吗?我将使用插入触发器。
谢谢

这是另一种做同样事情的方法,稍微基于集合。在下面的示例中,我使用一个临时表在两个新表之间映射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