1

我有三个表——Employee、Contact 和 Login。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 执行存储过程时,即使有错误,每次插入尝试的主键都会增加,无论失败和成功。我想做一些事情,比如当有错误时,主键不会增加。如何我应该这样做吗?

4

1 回答 1

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

于 2013-05-27T00:53:03.327 回答