我有一个这样的存储过程:
CREATE PROCEDURE [dbo].[create_myNewId]
(@parentId BIGINT)
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO [Mapping] (ParentId)
VALUES (@parentId)
SELECT SCOPE_IDENTITY();
END
此函数单独运行时,将返回新的 id ,该新的 id 已分配给使用父ID 插入的新行。但是,当我做这样的事情时:
DECLARE @NewId int
EXEC @NewId = create_myNewId @parentId = 33333
SELECT @NewId
运行此命令时,输出窗口将显示存储过程的结果,该结果返回一个ID,但@NewId
始终为0。我通过将存储过程更改为使用RETURN SCOPE_IDENTITY()
来解决了这个问题,但是想知道为什么SELECT
在这种情况下不起作用?
我怀疑它是0周围的东西,它是首先从存储过程而不是结果中返回成功状态,但是很好奇为什么直接从客户端调用时却不发生这种情况。
答案 0 :(得分:1)
不!正确编写程序:
CREATE PROCEDURE [dbo].[create_myNewId] (
@parentId bigint,
@outId bigint OUTPUT
) AS
BEGIN
SET NOCOUNT ON;
DECLARE @ids TABLE (id bigint);
INSERT INTO [Mapping](ParentId)
OUTPUT id INTO @ids
VALUES (@parentId);
SELECT @outId = id
FROM @ids;
END;
然后将其称为:
DECLARE @NewId int;
EXEC create_myNewId @parentId = 33333, @NewId OUTPUT;
SELECT @NewId;
OUTPUT
子句是从数据修改子句获取结果的推荐方法。使用*_IDENTITY()
函数的旧方法应该被淘汰。
存储过程确实返回值。这些是 integers ,旨在返回状态信息。其他信息应通过OUTPUT
参数返回。
答案 1 :(得分:0)
Microsoft对存储过程的设计意图是,它们总是返回一个int来描述该过程执行的过程的成功程度。它并非旨在返回结果数据,您可以自由定义要返回的用于描述成功,部分成功等的位。如果需要,可以滥用它来返回整数结果数据(例如,计数查询),但这不是设计意图
在存储过程中执行选择查询会创建一个结果集,如果该存储过程是旨在返回数据的那种类型,则可以在客户端上读取该结果集
答案 2 :(得分:0)
我的建议是使用OUTPUT参数。不仅在调用SPROC时更“容易”使用,而且对于调用SPROC的人也更加清晰。
CREATE PROCEDURE [dbo].[create_myNewId] (
@parentId BIGINT,
@myNewId BIGINT OUTPUT)
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO [Mapping] ([ParentId])
VALUES (@parentId);
SET @myNewId = SCOPE_IDENTITY();
END;
GO
然后您将像这样呼叫您的SPROC:
DECLARE @myNewId BIGINT;
EXECUTE [dbo].[create_myNewId] @parentId = 0, -- bigint
@myNewId = @myNewId OUTPUT; -- bigint
SELECT [This was just inserted] = @myNewId;