sql-server - T-SQL : Best way to copy hierarchy data?

标签 sql-server

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

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/

相关文章:

SQL 服务器 : List all values from tableA for each values in tableB

python - pyodbc sqlserver游标小数四舍五入

sql - 如何在 SQL 中为特定值设置别名?

sql-server - 为什么我的主键会减慢我的查询速度?

sql-server - SQL Server 2008 中的枚举类型?

java - 从 JDBC MSSQL 获取返回值

sql - 是否可以将可变列名传递到更新语句中?

sql - 将数据转换为多列

java - OpenJPA 1 - 未创建序列表

c# - 使用 C# 获取数据库服务器列表