我尝试编写一个存储过程,首先将新记录插入表中,然后返回此新记录的id。我不确定这是否是正确的方法和最佳方式。
ALTER PROCEDURE dbo.spAddAsset
(
@Name VARCHAR(500),
@URL VARCHAR(2000)
)
AS
BEGIN
Set NOCOUNT on;
Insert Into Assets (Name, URL) Values (@Name, @URL)
Declare @new_identity int;
SELECT @new_identity = SCOPE_IDENTITY()
return @new_identity;
END
答案 0 :(得分:29)
要向调用者返回单个标量值,您应该使用OUTPUT
参数,而不是RETURN
。 RETURN
用于错误/状态代码。前缀sp也是多余的,也是不必要的。
CREATE PROCEDURE dbo.AddAsset
@Name VARCHAR(500),
@URL VARCHAR(2000),
@new_identity INT = NULL OUTPUT
AS
BEGIN
SET NOCOUNT ON;
INSERT dbo.Assets(Name, URL) SELECT @Name, @URL;
SET @new_identity = SCOPE_IDENTITY();
END
GO
然后调用它:
DECLARE @new_identity INT;
EXEC dbo.AddAsset @Name = 'a', @URL = 'b', @new_identity = @new_identity OUTPUT;
PRINT @new_identity;
编辑只是添加一个在这个特定情况下不会影响提问者的免责声明,但可能会对其他情况或未来的读者有所帮助。在SQL Server 2008 R2及更早版本中,当使用并行性派生要插入的结果时(SCOPE_IDENTITY
),有potentially nasty bug内置函数,例如INSERT FROM othertable
。此错误(here is the Connect item)已在Cumulative Update #5 for SQL Server 2008 R2 SP1中修复,但到目前为止,修订版尚未出现在2008 R2 RTM,2008或2005中。
答案 1 :(得分:1)
我不明白为什么有必要将返回的行值放入新变量 @new_identity
中。我会简单地在存储过程的末尾包含 SELECT SCOPE_IDENTITY();
,如下所示:
CREATE PROCEDURE dbo.AddAsset
@Name VARCHAR(500),
@URL VARCHAR(2000)
AS
BEGIN
SET NOCOUNT ON;
INSERT dbo.Assets(Name, URL) SELECT @Name, @URL;
SELECT SCOPE_IDENTITY();
END
GO