33

I am using SQL Server 2008 Enterprise. I am learning OUTPUT parameter of SQL Server stored procedure. For example, stored procedure sp_add_jobschedule has an OUTPUT parameter called schedule_id.

http://msdn.microsoft.com/en-us/library/ms366342.aspx

My confusion is, looks like OUTPUT parameter could be provided an input value and also returns a value, looks like it has behaviors of both INPUT and OUTPUT parameter? Is it allowed not to provide any INPUT values for OUTPUT parameter (to make it look like pure output parameter behavior)?

8 Answers 8

61

The confusion is justified to a degree - and other RDBMS like Oracle do have stored procedure parameters which can be of type IN (input only), OUT (output only), or INOUT (both ways - "pass by reference" type of parameter).

SQL Server is a bit sloppy here since it labels the parameter as OUTPUT, but really, this means INPUT/OUTPUT - it basically just means that the stored proc has a chance of returning a value from its call in that parameter.

So yes - even though it's called OUTPUT parameter, it's really more of an INPUT/OUTPUT parameter, and those IN, INOUT, OUT like in Oracle do not exist in SQL Server (in T-SQL).

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks Marc, "The confusion is justified to a degree - and other RDBMS like Oracle do have stored procedure parameters" -- this is just why I am confused. I am migrating from DB2 to SQL Server. A lot of concepts are different. :-(
A further question, we could make OUTPUT parameter as an optional parameter, i.e. we could not provide its input value, and just use it as output?
Yes of course - you could provide in INPUT value or leave it empty - if you don't use it inside your stored procedure, it's totally pointless what you pass in. It's up to you and the code your write in your procedure whether or not you even look at the value passed in. The "OUTPUT" clause just means that the stored procedure has the ability to RETURN a value in this parameter - that's all.
But when I use this in SSIS, OUT is just out, I really wish that OUT works for both in and out.
@IrawanSoetomo Yes, I also just realized that: An OUTPUT-declared parameter in SSIS does not behave like a SQL OUTPUT parameter (nor then an Oracle INOUT): The parameter is passed into T-SQL as NULL no matter what it is at call-time.
20

I can give you short example on how to create stored procedure with output parameter.

CREATE PROCEDURE test_proc

@intInput int,
@intOutput int OUTPUT

AS
set @intOutput = @intInput + 1 

go

And to call this procedure and then use output parameter do as following:

declare @intResult int
exec test_proc 3 ,@intResult OUT
select @intResult

You see, that you should declare ouput variable first. And after executing stored procedure, the output value will be in your variable. You can set any value to your output variable, but after executing stored procedure it will contain exactly what stored procedure return (no matter what value was in the output variable).

For example:

declare @intResult int
exec test_proc 3 ,@intResult OUT
select @intResult

It will return 4. And:

declare @intResult int
set @intResult = 8
exec test_proc 3 ,@intResult OUT
select @intResult

Also return 4.

2 Comments

Thanks, so OUTPUT parameter has both input parameter and output parameter behaviors?
@George2: Yes, OUTPUT parameter acts as both input and output parameter.
6

Yes, you can use an OUTPUT parameter for both passing in and retrieving values (although I can't think of a good reason to do that at the moment).

Here's a trivial example that demonstrates this:

-- The stored procedure
CREATE PROCEDURE OutParamExample
    @pNum int OUTPUT
AS
BEGIN
    select @pNum
    set @pNum = @pNum + 5
END
GO

-- use a local variable to retrieve your output param value
declare @TheNumber int
set @TheNumber = 10

print @TheNumber
exec OutParamExample @TheNumber OUTPUT
print @TheNumber

The results will look like this:

10

-----------
10

(1 row(s) affected)

15

EDIT: OK, I think I missed a "not" in the second paragraph and may not have answered the question you asked. If you want a strict output parameter (e.g. something like a return code), you certainly don't have to provide a value to the local variable passed as the output parameter, but you still have to declare that local variable so that you'll have a way of accessing the returned value outside of the scope of the procedure itself.

For example:

declare @LocalNumber int
-- I don't have to assign a value to @LocalNumber to pass it as a parameter
exex OutParamExample @LocalNumber OUTPUT  
-- (assume SP has been altered to assign some reasonable value)

-- but I do have to declare it as a local variable so I can get to
-- the return value after the stored procedure has been called
print @LocalNumber

Comments

3

Adding further to what others have said above, OUTPUT parameters can act as INPUT as well as OUTPUT. But, it depends on the stored procedure to use the value passed to it.

If the stored procedures ignores the value passed in for OUTPUT parameter (which it generally should), the INPUT value gets ignored anyway.

Using Sergey's code, I can use the value user passed for @intOutput (if I need to)

create PROCEDURE test_proc

@intInput int,
@intOutput int OUTPUT

AS
set @intOutput = @intOutput + 1 

go

But, that defeats the purpose of OUTPUT parameter.
To give a different view, c# compiler forces you to overwrite the out parameter's value by assignment (without using the output parameter).

e.g. I cannot do this in c#. Here it acts as only out parameter (i.e ignore the value user passed to this function)

static void dosomething(out int i)
{
    //i = 0;
    i = i + 1;
}

Comments

2

The question is - why do you want to disallow to provide input? This makes no sense whatsoever. Consider this simple example:

CREATE PROCEDURE test (@param AS INT OUTPUT) AS
BEGIN
  SET @param = 100
END
GO

DECLARE @i INT
SET @i = 0

EXECUTE test @i OUTPUT
PRINT @i

DROP PROCEDURE test

This prints

100

See - how are you supposed to get a value out if you do not put a variable in first?

3 Comments

Thanks Tomalak, I am not sure whether I can design a store procedure with output parameter in this way. I can treat output parameter as both an optional input parameter (because output parameter allows us not to input any values) and as a return value?
I'm not sure what's so hard to understand about this. :) What is the actual problem?
I am using OUTPUT parameter as an option input parameter, I am not sure whether it is correct usage? I am using in this way, in the store procedure, I will check whether caller has input any values for the OUTPUT parameter, if yes, I will do some something, if no input value for the OUTPUT parameter, I will do something else.
2

Think about OUTPUT PARAMETERS as passed by reference in programming languages, it's the same. The best example I can think right now is returning error code. You want some insert... if you select the return code from the SP you have to fetch it back in your code, with OUTPUT parameter you don't have, it will be already in your parameter (I mean using C# commands, PHP init stored proc methods, or something different then constructing strings)

3 Comments

Thanks Svetlio, so looks like it has behaviors of both INPUT and OUTPUT parameter? Is it allowed not to provide any INPUT values for OUTPUT parameter (to make it look like pure output parameter behavior)?
@George2: "Is it allowed not to provide any INPUT values for OUTPUT parameter (to make it look like pure output parameter behavior)" - Isn't that what Sergey has shown in the code for example 1?
You mean this one? declare @intResult int exec test_proc 3 ,@intResult OUT select @intResult
2

One additional note regarding part of the original question:

"Is it allowed not to provide any INPUT values for OUTPUT parameter (..)?"

In SQLServer it is possible to specify a default value for an OUTPUT parameter (which as others have pointed out actually INOUT). Consider the following example in which you could specify a explicit value or let the function itself generate an ID.

CREATE PROCEDURE test (@id uniqueidentifier = NULL OUTPUT) AS
BEGIN
  IF @id IS NULL SET @id = NEWID()
  -- INSERT INTO xyz (...) VALUES (@id, ...)
  PRINT 'Insert with id: ' + CAST (@id as nvarchar(36))
END
GO

DECLARE @insertedId uniqueidentifier
EXECUTE test '00000000-0000-0000-0000-000000000000'
EXECUTE test @insertedId OUTPUT
PRINT @insertedId

DROP PROCEDURE test

This prints

Insert with id: 00000000-0000-0000-0000-000000000000
Insert with id: 67AE3D27-8EAB-4301-B384-30EEA1488440
67AE3D27-8EAB-4301-B384-30EEA1488440

Comments

0

Two other things I think that are worth noting:

1) You can pass more than one parameter as OUTPUT,

2) You do not have to call the parameters with OUTPUT if you don't want the results

CREATE PROCEDURE ManyOutputs @a int, @b int output, @c varchar(100) output, @d bit output
AS
BEGIN
    SET @b = @a + 11
    SET @c = 'The Value of A is ' + CAST(@a AS varchar(5)) + ', and the value of B is ' + CAST(@b AS varchar(5))
    IF (@a % 2 = 1)
        SET @d = 1
    ELSE
        SET @d = 0
END
GO

Calling this routine:

DECLARE @bVal int
DECLARE @cVal varchar(100)
DECLARE @dVal bit

EXEC ManyOutputs 1, @bVal, @cVal, @dVal
SELECT @bVal AS bVal, @cVal as cVal, @dVal as dVal

Returns NULL, NULL, NULL

EXEC ManyOutputs 2, @bVal OUT, @cVal OUT, @dVal OUT
SELECT @bVal AS bVal, @cVal as cVal, @dVal as dVal

Returns 13, "The Value of A is 2, and the value of B is 13", 0

EXEC ManyOutputs 3, @bVal, @cVal, @dVal
SELECT @bVal AS bVal, @cVal as cVal, @dVal as dVal

Returns 13, "The Value of A is 2, and the value of B is 13", 0

(the same as the last call, because we didn't get new values by using OUTPUT, so it retained the old values.)

EXEC ManyOutputs 5, @bVal OUT, @cVal OUT, @dVal OUT
SELECT @bVal AS bVal, @cVal as cVal, @dVal as dVal

Returns 16, "The Value of A is 5, and the value of B is 16", 1

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.