如何将值插入具有外键关系的两个表中?

Ca *_*Van 9 sql database sql-server sql-server-2014

我创建了两个表:

  • tblStaff的列id(主键,自动递增)name,age,address

  • tblRoleOfStaff的列id(主键,自动递增), StaffId(外键tblStaff)RoleId

我有形式来创建具有现有角色的新员工.要插入的数据样本:

(name, age, address, roleId) = ('my name',20,'San Jose', 1)
Run Code Online (Sandbox Code Playgroud)

我想写在SQL Server 2014存储过程中插入新员工tblStaff,并插入新记录tbleRoleOfStaffstaffId我刚插入.

我该怎么办?

如果我的问题与其他问题重复,我很抱歉.我对SQL更新.谢谢你的帮助.

gof*_*fr1 12

使用SCOPE_IDENTITY()第二次插入到tblRoleOfStuff一个地方StaffId.喜欢:

insert into tblStaff values
(@name, @age, @address)

insert into tblRoleOfStuff values
(scope_identity(), @roleid)
Run Code Online (Sandbox Code Playgroud)

编辑

关于这个答案有太多评论,所以我想给出一个解释.

如果OP保证他不会使用他可能使用的任何触发器@@IDENTITY(不良做法),这足以满足他的需求,但最佳实践是使用SCOPE_IDENTITY().

与@@ IDENTITY一样,SCOPE_IDENTITY()将返回在当前会话中创建的最后一个标识值,但它也会将其限制为当前范围.换句话说,它将返回您显式创建的最后一个标识值,而不是由触发器或用户定义的函数创建的任何标识.

SCOPE_IDENTITY() 将保证您从当前操作获得身份,而不是从另一个连接或最后一个连接获得.

为什么不IDENT_CURRENT呢?因为

IDENT_CURRENT不受范围和会话的限制; 它仅限于指定的表格.IDENT_CURRENT返回在任何会话和任何范围内为特定表生成的标识值.

所以你制作最后一个范围,但不是当前范围.是的,OP也可以使用它,但在这种情况下这是一种不好的做法(比如只使用@@IDENTITY)

使用OUTPUT确实是很好的做法,但只有一个身份复杂.如果OP需要在一段时间内处理多行 - 是的,他需要 OUTPUT.

  • 我建议使用**`SCOPE_IDENTITY()`**而不是其他任何东西(比如`@@ IDENTITY`)来获取新插入的标识值.[请参阅此博客文章,了解为何解释](http://blog.sqlauthority.com/2007/03/25/sql-server-identity-vs-scope_identity-vs-ident_current-retrieve-last-inserted-identity -of-记录/) (3认同)

Mat*_*att 6

因为看起来您一次讨论 1 行,所以有些人可能会告诉您使用系统变量@@IDENTITY或其他一些系统变量,但为了确保更确定,我建议OUTPUT使用 insert 语句的子句。这种方法的好处是它可以很容易地适应一次处理超过 1 行。

DECLARE @Output AS TABLE (StaffId INT)

INSERT INTO tblStaff (name, age, address)
OUTPUT inserted.Id INTO @Output (StaffId)
VALUES (@name, @age, @address)

DECLARE @StaffId INT
SELECT @StaffId = StaffId FROM @Output

INSERT INTO tblRoleOfStaff (StaffId, RoleId)
VALUES (@StaffId,@RoleId)
Run Code Online (Sandbox Code Playgroud)

@@IDENTITY在执行与您的操作相关联的其他操作时不使用的原因。例如,触发器将另一行插入另一个表,或更新数据库中的另一条记录。SCOPE_IDENTITY当触发器修改同一个表时,也有类似的不足。 IDENT_CURRENT也有一个短暂的未来。进行互联网搜索以了解更多信息,这些方面有大量优秀资源。