6

我有 2 个表,其中一个与另一个有外键关系

CREATE TABLE foo (
  id INT NOT NULL PRIMARY KEY IDENTITY,
  value VARCHAR(50) DEFAULT NULL,
);

CREATE TABLE bar (
  id INT NOT NULL PRIMARY KEY IDENTITY,
  foo_key INT NOT NULL
  value VARCHAR(50) DEFAULT NULL,
);

我正在使用参数化的 ADO.NET ExecuteReader 来插入新行。我的泡菜是,如果我想在同一个事务中的不同表中插入 2 行,即在提交之前,我不能在 bar 中插入行,因为我还不知道 foo.id 的值。你会怎么做呢?即我如何确保 bar.foo_key 获得正确的值?尝试选择它什么都没有,因为我猜它实际上还没有。我是否应该使用存储过程来尝试动态生成密钥,或者可能有一个可以使用的内部变量。或者有没有办法让插入返回新的ID?我是否需要外键声明,尽管我不确定这是否有用,因为我仍然不知道要使用什么 id?

我想一次性完成的原因是由于错误处理,我希望能够在发生错误时回滚所有内容。

4

2 回答 2

5

您可以使用scope_identity()检索新生成的identity

begin tran;
insert Foo (value) values ('6*7');
declare @fk int = scope_identity();
insert bar (foo_key, value) values (@fk, '42');
commit tran;

根据 HLGEM 的评论,要将新生成的身份的值返回给客户端,您可以使用output

insert Foo (value) output inserted.ID values ('6*7');

请注意,对于跨越两个会话的事务,您需要一个分布式事务,这非常昂贵。

于 2013-03-25T20:15:18.523 回答
0

我发现我可以在插入时返回 scope_identity()

INSERT INTO [foo] ([value]) VALUES (@0) SELECT SCOPE_IDENTITY() AS [SCOPE_IDENTITY];
于 2013-03-25T20:41:53.657 回答