create procedure [dbo].[basic_und6] (#name varchar(500), #email varchar(500), #result int out)
as
begin
Select #result=COUNT(*) from tbl_Students
where Firstname= #name and Email=#email
print #result
end
Given below is the query which I am running to execute the stored procedure
**declare #result1 int
execute basic_und6 Amit,'amit#abc.com',#result1
print #result1**
I am getting result as 1.
But according to my understanding, it should have displayed two 1's
First 1 is from the stored procedure print and second 1 from the query which had print statement.
Modify your execute statement to this :
declare #result1 int
execute basic_und6 Amit,'amit#abc.com', #result1 OUTPUT
print #result1
This is because, you haven't specified a variable where the output value must be returned to. The calling statement must do this by explicitly using the OUTPUT keyword. More info here
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.
No it will show only one 1
when we select a value into a variable the row count will not be shown
Related
I have a stored procedure that has a bunch of input and output parameters because it is Inserting values to multiple tables. In some cases the stored proc only inserts to a single table (depending on the input parameters). Here is a mocked up scenario to illustrate.
Tables / Data Objects:
Person
Id
Name
Address
Name
Id
FirstName
LastName
Address
Id
Country
City
Say I have a stored procedure that inserts a person. If the address doesn't exist I won't add it to the Address table in the database.
Thus when I generate the code to call the stored procedure I don't want to bother adding the Address parameter. For INPUT parameters this is ok because SQL Server allows me to supply default values. But for the OUTPUT parameter what do I do in the stored procedure to make it optional so I do not receive an error...
Procedure or function 'Person_InsertPerson' expects parameter
'#AddressId', which was not supplied.
Both input and output parameters can be assigned defaults. In this example:
CREATE PROCEDURE MyTest
#Data1 int
,#Data2 int = 0
,#Data3 int = null output
AS
PRINT #Data1
PRINT #Data2
PRINT isnull(#Data3, -1)
SET #Data3 = #Data3 + 1
RETURN 0
the first paramter is required, and the second and third are optional--if not set by the calling routine, they will be assigned the default values. Try messing around with it and the following test-call routine in SSMS using different values and settings to see how it all works together.
DECLARE #Output int
SET #Output = 3
EXECUTE MyTest
#Data1 = 1
,#Data2 = 2
,#Data3 = #Output output
PRINT '---------'
PRINT #Output
Output parameters and default values do not work well together! This is from SQL 10.50.1617 (2008 R2). Do not be fooled into believing this construct magically does a SET to that value on your behalf (like my co-worker did)!
This "toy" SP interrogates the OUTPUT parameter value, whether it is the default value or NULL.
CREATE PROCEDURE [dbo].[omgwtf] (#Qty INT, #QtyRetrieved INT = 0 OUTPUT)
AS
IF #QtyRetrieved = 0
BEGIN
print 'yay its zero'
END
IF #QtyRetrieved is null
BEGIN
print 'wtf its NULL'
END
RETURN
If you send in an uninitialized value (i.e. NULL) for the OUTPUT, you really got NULL inside the SP, and not 0. Makes sense, something got passed for that parameter.
declare #QR int
exec [dbo].[omgwtf] 1, #QR output
print '#QR=' + coalesce(convert(varchar, #QR),'NULL')
output is:
wtf its NULL
#QR=NULL
If we add an explicit SET from the caller we get:
declare #QR int
set #QR = 999
exec [dbo].[omgwtf] 1, #QR output
print '#QR=' + coalesce(convert(varchar, #QR),'NULL')
and the (unsurprising) output:
#QR=999
Again, makes sense, a parameter is passed, and SP took no explicit action to SET a value.
Add a SET of the OUTPUT parameter in the SP (like you're supposed to do), but do not set anything from the caller:
ALTER PROCEDURE [dbo].[omgwtf] (#Qty INT, #QtyRetrieved INT = 0 OUTPUT)
AS
IF #QtyRetrieved = 0
BEGIN
print 'yay its zero'
END
IF #QtyRetrieved is null
BEGIN
print 'wtf its NULL'
END
SET #QtyRetrieved = #Qty
RETURN
Now when executed:
declare #QR int
exec [dbo].[omgwtf] 1234, #QR output
print '#QR=' + coalesce(convert(varchar, #QR),'NULL')
the output is:
wtf its NULL
#QR=1234
This is the "standard" behavior for OUTPUT parameter handling in SPs.
Now for the plot twist: The only way to get the default value to "activate", is to not pass the OUTPUT parameter at all, which IMHO makes little sense: since it's set up as an OUTPUT parameter, that would mean returning something "important" that should be collected.
declare #QR int
exec [dbo].[omgwtf] 1
print '#QR=' + coalesce(convert(varchar, #QR),'NULL')
gives this output:
yay its zero
#QR=NULL
But this fails to capture the SPs output, presumably the purpose of that SP to begin with.
IMHO this feature combination is a dubious construct I would consider a code smell (phew!!)
Looks like I can just add a default value to the OUTPUT parameter such as:
#AddressId int = -1 Output
Seems like its poor in terms of readability since AddressId is intended strictly as an OUTPUT variable. But it works. Please let me know if you have a better solution.
Adding on to what Philip said:
I had a stored procedure in my sql server database that looked like the following:
dbo.<storedProcedure>
(#current_user char(8) = NULL,
#current_phase char(3) OUTPUT)
And I was calling it from my .net code as the following:
DataTable dt = SqlClient.ExecuteDataTable(<connectionString>, <storedProcedure>);
I was getting an System.Data.SqlClient.SqlException: Procedure or function expects parameter '#current_phase', which was not supplied.
I am also using this function somewhere else in my program and passing in a parameter and handling the output one. So that I didn't have to modify the current call I was making I just changed the stored procedure to make the output parameter also optional.
So it now looks as the following:
dbo.<storedProcedure>
(#current_user char(8) = NULL,
#current_phase char(3) = NULL OUTPUT)
Since you are executing a stored procedure and not a SQL statement, you have to set the command type of your SQL Command to Stored Procedure:
cmd.CommandType = CommandType.StoredProcedure;
Taken from here.
Also, once you get that error removed, you can use SQL's nvl() function in your procedure to specify what you want displayed when a NULL value is encountered.
Sorry about not properly addressing the question...must have misunderstood you. Here's an example of nvl, which I think might address it a little better?
select NVL(supplier_city, 'n/a')
from suppliers;
The SQL statement above would return 'n/a' if the supplier_city field contained a null value. Otherwise, it would return the supplier_city value.
Given a stored procedure like the one shown below:
CREATE PROCEDURE [dbo].[GetBusinessUnitSysNameAndGroupNames]
#ModelAfter varchar(100),
#BusinessUnitSystemName varchar(100) OUT,
#GroupsName varchar(4000) OUT
AS
BEGIN
if (#ModelAfter = 'Corporate')
BEGIN
SET #GroupsName = 'Admins'
SET #BusinessUnitSystemName = 'AcmeOutdoors'
END
else if (#ModelAfter = 'Retailers')
BEGIN
SET #GroupsName = 'Sellers'
SET #BusinessUnitSystemName = 'AcmeShoppers'
END
END
When I run from the SQL Studio command line:
EXEC [dbo].[GetBusinessUnitSysNameAndGroupNames] '~ModelAfter~', 'acmeoutdoors', 'admins'
I just get a result in the message panel like Command(s) completed successfully. But what I would like to see the actual result, not just a success message. Something like shown below(which doesn't work, just my idea).
DECLARE #Result varchar(max)
SET #Result = EXEC [dbo].[GetBusinessUnitSysNameAndGroupNames] '~ModelAfter~', 'acmeoutdoors', 'admins'
PRINT #Result
Returning Data by Using OUTPUT Parameters
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.
DECLARE #Result1 varchar(max), #Result2, varchar(max)
EXEC [dbo].[GetBusinessUnitSysNameAndGroupNames] 'Corporate', #Result1 OUT, #Result2 OUT
PRINT #Result1
PRINT #Result2
I am trying to execute a procedure(A) inside another procedure(B) and I want to store the value returned from the procedure A in a variable called #LogId.
after executing Procedure A
exec TES_usp_getnextlogid
it returns something like
NewLogId = xxxx
I tried doing the following in procedure B.
declare #LogId int
exec #LogId = TES_usp_getnextlogid
my question is, why doesn't #LogId holds the value which is returned from TES_usp_getnextlogid Procedure?
Thanks.
use output parameter for this, return value should only be used for returning Success/Faliuer status.
CREATE PROCEDURE My_Outter_Proc2
AS
BEGIN
DECLARE #NextID INT;
EXEC TES_usp_getnextlogid #NextID OUTPUT
EXEC My_Inner_Proc #NextID
END
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)?
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).
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.
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
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;
}
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?
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)
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
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
How can I ignore an output parameter of a stored procedure? I'm calling the procedure from another procedure, e.g.:
DECLARE #param1 integer
EXEC mystoredprocedure
#in_param_1,
#in_param2_,
#param1 OUTPUT,
-- what do I type here to ignore the second output param??
I'm using T-SQL (MS SQL 2005).
You can just use NULL as the last parameter, and it should work fine - as long as that parameter isn't expected for input logic in the proc as well.
In your case, you'd call the proc as
exec mystoredproc #in_param_1, #in_param2_, #param1 OUTPUT, null
Here's another example that for the same scenario...
create proc MyTempProc
(#one int,
#two int out,
#three int out)
AS
begin
set #two = 2
set #three = 3
select #one as One
end
go
declare #p1 int,
#p2 int
set #p1 = 1
exec MyTempProc #p1, #p2 out, null
print #p1
print #p2
The output parameter has to have a default in order for you to not pass it. See below
create proc x (#in int = null, #out int = null OUTPUT)
as
Begin
Select #in
End
exec x 1
EDIT
To clarify a little, the error is being returned because the stored procedure that is being called has a parameter defined (in this case #param1), for which no default is defined. (i.e. #param1 int rather than #param int = -1) In the case where neither a parameter or default is specified for a defined parameter of a stored procedure when calling the stored procedure an error will occur. The same thing would happen if you tired to omit an input parameter that does not have a default specified.
You'll probably have to just ignore the OUTPUT param yourself by just not doing anything with the value. It's not like the overhead of that variable is an issue or anything. The only issue here is that your code will be a little bit uglier. So slap a comment on there explaining that the OUTPUT param isn't being used and everything should be alright.
If the SP you're calling expects a parameter to be passed, you have to have one there. Even if you disregard the output of it, it is part of the structure of the SP.
Think of parameters as a "Data Contract". If they're not defaulted, they're required. Even if the values are disregarded.
Forcing you to declare a dummy value you'll never read is the cost of calling that stored proc that may be used by something that DOES need to utilize the value of the output parameter.