复制另一个表中的行和相关行,以及另一个表中的相关行,等等

时间:2019-03-28 23:38:10

标签: sql sql-server

我有一个带有'id'列和其他各个列的表。每行数据将具有唯一的“ id”。此“ id”在另一个表中引用,该表也具有带有唯一“ id”的行。每一个都在另一个表中引用。

我们将表称为“ items”,“ item_options”和“ sub_options”。我想复制“项目”中的一行,还复制“ item_options”中与其ID关联的所有内容,以及“ item_options”中与ID关联的“ sub_options”中的所有内容。

例如:

在“项目”中说,列是“ id”和“ title”。
在“ item_options”中,列为“ id”,“ itemID”和“ option”。
在“ sub_options”中,列为“ id”,“ item_optionsID”和“ subOption”。

我可以做到这一点:

insert into dbo.items (title)
  select title
  from dbo.items where id = '123'

从这里开始,我一直在返回“ itmes”中新复制的行的新id,然后使用服务器端语言遍历并复制“ item_options”,然后遍历那些以复制“ sub_options”,但是我经常碰到数据库,而性能却受到打击。

我想用SQL进行全部操作,但似乎无法弄清楚。

对于示例数据,我将尝试以下方法:

dbo.items
id:“ 123”
标题:“新车”

dbo.item_options
id:“ 456”
itemID:“ 123”
选项:“自定义车轮”

id:'457'
itemID:“ 123”
选项:“自定义绘画”

dbo.sub_options
id:“ 789”
item_optionsID:“ 456”
子选项:“ Chrome”

id:“ 790”
item_optionsID:“ 456”
子选项:“ 20英寸”

id:'791'
item_optionsID:“ 457”
子选项:“红色”

基本上,我想复制所有这些,同时使ID与复制时所有新生成的ID都匹配。

2 个答案:

答案 0 :(得分:0)

您需要在插入每个表中时捕获新的“ id”值,以将其用于子表中的外键引用。捕获新“ id”的最可靠方法是使用SQL output clause,因为它将始终提供正确的ID并可以处理多个ID(许多其他方法来获取新创建的记录ID都应避免陷阱)

您还希望将其包装在事务中以确保其全部或全部操作(您可能还需要其他错误处理)。

由于output语句上的insert子句不允许原始表中的值,因此我在第二部分中使用了merge语句,匹配条件为{ {1}},即它永远不会匹配,因此总是插入,并且1=0语句的确允许来自merge子句中原始表的值。

output

答案 1 :(得分:0)

已更新(经过OP澄清):

您正在尝试在表items中插入新行,并且需要保存新生成的ID(AKA IDENTITY),以便将该行用作其他插入操作中的FK(在您的情况下,想要在item_options中使用它)。

如果itemsitem_options中的ID是身份,则可以使用SCOPE_IDENTITY()

SCOPE_IDENTITY()

  

返回插入到的身份列中的最后一个身份值   范围相同

Learn More ...

因此,您的插入内容将像这样简单:

INSERT INTO dbo.items (title) VALUES ('New Car')

INSERT INTO item_options (itemId, [option]) VALUES (SCOPE_IDENTITY(), 'Custom Wheels')

INSERT INTO sub_options (item_optionsId, subOption) VALUES (SCOPE_IDENTITY(), 'Chrome')

第一个SCOPE_IDENTITY()将使用item中最后生成的ID,第二个将使用item_options id,依此类推。

您还可以将id存储在变量中,以进一步使用,如下所示:

DECLARE 
    @itemId INT 
,   @optionId INT


INSERT INTO dbo.items (title) VALUES ('New Car')

SELECT @itemId = SCOPE_IDENTITY()

INSERT INTO item_options (itemId, [option]) VALUES (@itemId, 'Custom Wheels')

SELECT @optionId = SCOPE_IDENTITY()

INSERT INTO sub_options (item_optionsId, subOption) VALUES (@optionId, 'Chrome')

这将为您提供超出其范围的ID的更多灵活性。

我希望这可以解决您的难题。