我的数据库看起来像这样:
Questionnaire
Id
Description
Category
id
description
QuestionnaireId (FK)
Question
id
CategoryId (FK)
field
当我复制问卷时,我想复制所有基础表。所以这意味着表 Questionnaire 获得了一个新的 Id。然后,还必须复制问卷的所有所属类别。所以新插入的类别必须获得新的问卷 ID。在分类之后,必须复制问题。但是 categoryId 必须更新为新插入的类别。
如何使用 t-sql 执行此操作?
最佳答案
这很容易完成,但您必须在进行时跟踪所有内容。我通常会为此创建一个 SP,它将调查问卷作为输入进行复制。
DECLARE @newQuestionnaireId INT
INSERT INTO Questionnaire
(Id,Description)
SELECT Id, Description
FROM Questionnaire
WHERE ID = @sourceQuestionnaireID
SET @newquestionnaireId = SCOPE_IDENTITY()
此时,您有一个新的标题记录,以及新生成的副本 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
现在,您有一个临时表,其中包含要插入的所有类别,以及一个用于回填此类别的新 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
此时,您现在有一个临时表,它将原始问卷中的 catId 映射到新问卷的 catId。这可用于以几乎相同的方式填充决赛 table - 我将其作为练习留给您,但如果您有困难,请随时在此处发帖。
最后,我建议在事务中执行整个操作,以便在出现问题时避免半完成的副本。
一些免责声明:以上都是快速输入的,不要指望它会立即起作用。其次,我假设你所有的 PK 都是身份字段,它们应该是!如果他们不只是用适当的逻辑替换 SCOPE_IDENTITY() 调用来生成下一个 ID。
编辑:documentation for Cursor operations can be foundhere
关于sql-server - T-SQL : Best way to copy hierarchy data?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3854607/