基本上,您看到的结果实际上是您在过程结束时SELECT 的结果,它正在做同样的事情。
请看一下这个documentation:
如果在过程定义中为参数指定了 OUTPUT 关键字,则存储过程可以在存储过程退出时将参数的当前值返回给调用程序。要将参数的值保存在调用程序可以使用的变量中,调用程序在执行存储过程时必须使用 OUTPUT 关键字。
所以基本上如果你希望你的存储过程只返回一个值而不是一个数据集,你可以使用输出参数。例如,让我们以您给出的程序为例。他们都做同样的事情,这就是你得到相同结果的原因。但是在第一个具有输出参数的过程中稍微改变一下呢?
这是一个例子:
create table OutputParameter (
ParaName varchar(100)
)
insert into OutputParameter values ('one'), ('two'),('three'),('one')
CREATE PROCEDURE AllDataAndCountWhereOne
@name nvarchar(60),
@count int OUT
as
Begin
SELECT @count = COUNT(*) from OutputParameter
Where ParaName = @name
select Distinct(ParaName) from OutputParameter
End
Declare @TotalCount int
Exec AllDataAndCountWhereOne @count = @TotalCount OUT, @name = 'One'
Select @TotalCount
在此示例中,您将获取表中所有不同的存储数据,以及给定名称的计数。
ParaName
--------------------
one
three
two
(3 row(s) affected)
-----------
2
(1 row(s) affected)
这是使用输出参数的一种方式。在获得初始数据集后,您无需进行额外查询即可获得不同的数据和所需的计数。
最后,回答你的问题:
这两个过程以相同的形式给我们相同的结果,那么有什么区别?
你自己的结果没有改变,这就是你没有真正注意到差异的原因。
其他例子:
您可以在其他类型的过程中使用OUT 参数。假设您的存储过程不返回任何内容,它更像是对 DB 的命令,但您仍然想要返回一种消息,或者更具体地说是一个值。举两个例子:
CREATE PROCEDURE InsertDbAndGetLastInsertedId
--This procedure will insert your name in the database, and return as output parameter the last inserted ID.
@name nvarchar(60),
@LastId int OUT
as
Begin
insert into OutputParameterWithId values (@name);
SELECT @LastId = SCOPE_IDENTITY()
End
或:
CREATE PROCEDURE InsertIntoDbUnlessSomeLogicFails
--This procedure will only insert into the db if name does exist, but there's no more than 5 of it
@name nvarchar(60),
@ErrorMessage varchar(100) OUT
as
Begin
set @ErrorMessage = ''
if ((select count(*) from OutputParameterWithId) = 0)
begin
set @ErrorMessage = 'Name Does Not Exist'
return
end
if ((select count(*) from OutputParameterWithId) = 5)
begin
set @ErrorMessage = 'Already have five'
return
end
insert into OutputParameterWithId values (@name);
End
这些只是虚拟示例,只是为了让概念更清晰。