我有三个表 - 员工,联系人和登录。 Employee表将emp_id作为具有标识值的主键。 Contact表有emp_id作为外键,它引用了Employee表的emp_id,而Login表也有emp_id作为引用Employee表的emp_id的外键。所有表都有自动增加的主键,因为所有表都设置为标识(1,1)。
这是我的SQL查询:
create procedure [dbo].[sp_registerEmp]
@start_date datetime,
@first_name varchar(50),
@middle_name varchar(50),
@last_name varchar(50),
@father_name varchar(50),
@grandfather_name varchar(50),
@country varchar(20),
@mobile_no int,
@email_id varchar(30),
@designation varchar(30),
@username varchar(20),
@password varchar(15),
@security_question varchar(150),
@security_answer varchar(50)
as
begin
begin try
begin transaction
insert into [dbo].[Employee]([start_date])
values(@start_date)
insert into [dbo].[Contact](first_name,middle_name,last_name,father_name,grandfather_name,
country,mobile_no,email_id,emp_id)
values(@first_name,@middle_name,@last_name,@father_name,@grandfather_name,
@country,@mobile_no,@email_id,SCOPE_IDENTITY());
insert into [dbo].[Login](username,userpassword,security_question,security_answer,emp_id)
values(@username,@password,@security_question,@security_answer,IDENT_CURRENT('Employee'));
commit transaction
end try
begin catch
rollback transaction
end catch
end
现在我的问题是,由于ident_current('tablename')返回该表中生成的最后一个标识值,无论会话和范围如何。现在使用ident_current('tablename')可能无法提供所需的emp_id,在这些情况下我可能具有针对一个用户的登录表,但是为另一个用户创建。我只想拥有由事务的第一个查询插入的登录表的emp_id。我怎么能实现这个?
另一个问题是,当从visual studio执行存储过程时,尽管存在错误,每次插入尝试的主键都会增加,无论失败和成功。我想做的事情就像有错误时,主键不会增加。我该怎么做?
答案 0 :(得分:1)
我只想拥有由事务的第一个查询插入的emp_id ....我怎么能实现这个目标呢?
您可以声明一个局部变量来存储SCOPE_IDENTITY()
的结果。然后,您可以在后续语句中使用此变量:
...
begin transaction
declare @emp_id int
insert into [dbo].[Employee]([start_date])
values(@start_date)
-- store for later use
set @emp_id = SCOPE_IDENTITY()
insert into [dbo].[Contact](first_name,middle_name,last_name,father_name,grandfather_name,
country,mobile_no,email_id,emp_id)
values(@first_name,@middle_name,@last_name,@father_name,@grandfather_name,
@country,@mobile_no,@email_id, @emp_id );
--- here ----------------------------> ^^^^^^^
insert into [dbo].[Login](username,userpassword,security_question,security_answer,emp_id)
values(@username,@password,@security_question,@security_answer, @emp_id );
--- here -----------------------------------------------------> ^^^^^^^
...
我想做的事情就像有错误时一样,主键不会增加。我该怎么做?
我认为没有一种简单的方法可以做到这一点 - 你必须在每次错误后重新定位身份值:
DBCC CHECKIDENT (<table_name>, RESEED)
我认为这很容易出错(您是否会在所有错误上调用上述内容?),这不是一个好主意。另请参阅MSDN上的DBCC CHECKIDENT。