sql-server - 我们到底什么时候使用带有输出参数的存储过程?

标签 sql-server t-sql stored-procedures

我们到底什么时候使用带输出参数的存储过程,什么时候使用不带参数的存储过程?

我的问题基于一个例子:

带输出参数的存储过程

CREATE PROCEDURE uspGetContactsCountByCity
    @City nvarchar(60),
    @ContactsCount int OUT
AS
BEGIN
    SELECT @ContactsCount = COUNT(ContactID) 
    FROM Contacts
    WHERE City = @City
END

存储过程执行

DECLARE @ContactsTotal INT

EXEC uspGetContactsCountByCity @ContactsCount = @ContactsTotal OUT, @city = 'Berlin'
SELECT @ContactsTotal

结果:2

不带输出参数的存储过程

CREATE PROCEDURE uspGetContactsCountByCity2
    @City nvarchar(60)
AS
BEGIN
    SELECT COUNT(ContactID) 
    FROM Contacts
    WHERE City = @City
END

存储过程执行:

EXEC uspGetContactsCountByCity2 @city = 'Berlin'

结果:2

两个过程以相同的形式返回相同的结果,那么有什么区别呢?

最佳答案

基本上,您看到的结果实际上是过程末尾 SELECT 的结果,它执行相同的操作。

请看一下这个documentation :

If you specify the OUTPUT keyword for a parameter in the procedure definition, the stored procedure can return the current value of the parameter to the calling program when the stored procedure exits. To save the value of the parameter in a variable that can be used in the calling program, the calling program must use the OUTPUT keyword when executing the stored procedure.

所以基本上,如果您希望存储过程仅返回一个值而不是数据集,则可以使用输出参数。例如,我们以您给出的过程为例。他们都做同样的事情,这就是为什么你得到相同的结果。但是在第一个具有输出参数的过程中稍微改变一下怎么样? 这是一个例子:

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)

这是使用输出参数的一种方法。在获取初始数据集后,您无需执行额外的查询即可获得所需的不同数据和计数。

最后回答你的问题:

Both procedures gives us the same result, in same form, so what's the difference?

您没有对自己的结果产生影响,这就是为什么您没有真正注意到差异。

其他示例:

您可以在其他类型的过程中使用OUT 参数。假设您的存储过程不返回任何内容,它更像是对数据库的命令,但您仍然想要返回一种消息,或更具体地说是一个值。举这两个例子:

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

这些只是虚拟示例,只是为了使想法更加清晰。

关于sql-server - 我们到底什么时候使用带有输出参数的存储过程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48841374/

相关文章:

sql - 在 SQL Server 中确定百分比协议(protocol)

sql-server - 保持此架构清晰的最佳方法是什么?

asp.net - 当用户的浏览器断开连接时,如何取消 ASP.NET 中的数据库查询?

sql - 将索引列添加到 SQL Server View 的最佳方法是什么?

java - SQLServer 2000 : how to make aynchoronous call to procedures in database?

mysql - 创建存储过程 phpmyadmin 时出错

sql - 条件检查,多列的单值/多值,逗号分隔列

sql - 我们如何在没有数据透视的情况下对子查询使用 group by 进行计数?

sql - PLI 关键字的用途是什么?

sql-server - SQL Server 数据库的 SQL 脚本导出的命令行方法