需要有关在ms sql查询中使用IDENT_CURRENT('tablename')的建议

时间:2013-05-27 00:21:11

标签: sql-server database tsql

我有三个表 - 员工,联系人和登录。 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执行存储过程时,尽管存在错误,每次插入尝试的主键都会增加,无论失败和成功。我想做的事情就像有错误时,主键不会增加。我该怎么做?

1 个答案:

答案 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