T-SQL:复制层次结构数据的最佳方法?

Mar*_*ijn 7 sql-server

我的数据库看起来像这样:

Questionnaire 
Id 
Description

Category
id
description
QuestionnaireId (FK)    

Question
id
CategoryId (FK)
field
Run Code Online (Sandbox Code Playgroud)

当我复制问卷时,我想复制所有基础表.所以这意味着表调查表得到一个新的Id.然后,还必须复制调查问卷的所有所有类别.因此,新插入的类别必须获得新的问卷ID.在类别之后,必须复制问题.但必须将categoryId更新为新插入的类别.

我怎么能用t-sql做到这一点?

Jam*_*iec 8

这很容易实现,但您必须随时跟踪所有内容.我通常会为此创建一个SP,它将问卷作为输入进行复制.

  DECLARE @newQuestionnaireId INT
  INSERT INTO Questionnaire
  (Id,Description)
  SELECT Id, Description 
  FROM Questionnaire
  WHERE ID = @sourceQuestionnaireID
  SET @newquestionnaireId = SCOPE_IDENTITY()
Run Code Online (Sandbox Code Playgroud)

此时,您有一个新的标题记录,以及新生成的副本ID.下一步是将类别加载到临时表中,该临时表具有新Id的额外字段

DECLARE @tempCategories TABLE (id INT, description VARCHAR(50),newId INT)
INSERT INTO @tempCategories(id,description)
SELECT id, description FROM Category 
WHERE questionnaireId = @sourceQuestionnaireId
Run Code Online (Sandbox Code Playgroud)

现在,您有一个临时表,其中包含要插入的所有类别,以及用于回填此类别的新ID的字段.使用光标覆盖插入新记录的列表,并使用类似的SCOPE_IDENTITY调用来回填新Id.

DECLARE cuCategory CURSOR FOR SELECT Id, Description FROM @tempCategories
DECLARE @catId INT, @catDescription, @newCatId INT
OPEN cuCategory
FETCH NEXT FROM cuCategory INTO @catId,@catDescription
WHILE @@FETCH_STATUS<>0
BEGIN
  INSERT INTO Category(description,questionnaireId)
  VALUES(@catDescription,@newQuestionnaireId)
  SET @newCatId = SCOPE_IDENTITY()

  UPDATE @tempCategories SET newCatId=@newCatId
  WHERE id=@catId
  FETCH NEXT FROM cuCategory INTO @catId,@catDescription
END
CLOSE cuCategory
DEALLOCATE cuCategory
Run Code Online (Sandbox Code Playgroud)

此时,您现在有一个临时表,它将catId从原始问卷映射到新问卷的catId.这可以用来以相同的方式填写决赛桌 - 我将为你留下一个练习,但如果你有困难,可以随时回复.

最后,我建议整个操作在一个事务中执行,以便在出现问题时将您从半完成的副本中保存下来.

一些免责声明:以上所有都是快速输入,不要指望它能够起作用.其次,我认为你所有的PK都是身份字段,它们应该是!如果他们不只是用适当的逻辑替换SCOPE_IDENTITY()调用来生成下一个ID.

编辑:Cursor操作的文档可以在这里找到

  • 我几乎已经为你写了答案,你不能把这些短语输入谷歌?啧. (3认同)