我有这个SQL Server存储过程:
CREATE procedure [dbo].[sp_FinancialInstitutionsAdd]
@Name varchar(50)
AS
set nocount on
begin tran
declare @retval int = 0
declare @rmdID int
execute @rmdID = dbo.sp_MetaDataRecsAdd
select @rmdID as rmdID
if @@ERROR <> 0
begin
rollback tran
return -1
end
insert FinancialInstitutions (Name, rmdID)
values (@Name, @rmdID)
if @@ERROR <> 0
begin
rollback tran
return -1
end
return scope_identity()
commit tran
我只能取回插入的MetaDataRecs
表的ID,但我想要FinacialInstitutions
表的ID。直接在SQL中执行时,该过程可以正常工作,但在使用代码中的ExecuteScalar
命令执行时,该过程无效。
答案 0 :(得分:1)
首先,除非您使用非常旧的SQL Server版本,否则应使用Try...catch
而不是旧样式if @@ERROR <> 0
。自2005年版以来,Sql server支持Try ... catch
其次,我怀疑你从scope_identity()
函数中获取了错误的标识,因为它没有包含在事务中。如果交易被回滚,我不确定它应该返回什么
试试这个:
CREATE procedure [dbo].[sp_FinancialInstitutionsAdd]
(
@Name varchar(50),
@ReturnValue int output
)
AS
set nocount on
declare @rmdID int,
@retval int = 0
begin Try
begin tran
execute @rmdID = dbo.sp_MetaDataRecsAdd
-- select @rmdID as rmdID -- What is that row? I've commented it out since it makes no sense to me
insert into FinancialInstitutions (Name ,rmdID)
values (@Name ,@rmdID)
set @ReturnValue = scope_identity()
commit tran
end try
begin catch
rollback tran
end catch
注意#1 :您需要更改对此过程的调用,以将@ReturnValue添加为输出参数。
注意#2 :如果此过程在此行set @ReturnValue = scope_identity()
之前遇到错误,则@ReturnValue
的值将保持为DBNull.Value
。
答案 1 :(得分:-1)
根据我的理解,您依赖于处理错误的旧方法。 尝试使用TRY..CATCH块以提高可读性和良好的实践设计。
也不要使用RETURN将Identity值返回给调用者,好的做法是为此目的声明OUTPUT参数。
答案 2 :(得分:-2)
@@ identity和scope_identity()都将返回您创建的最后一个ID。 对于使用触发器将某些东西插入另一个表的人来说,这也是一个问题。
我不知道你的桌子,但我做了类似
的事情declare @id int
select @id = max(id) from FinancialInstitutions
return @id
欢呼声