The formal parameter “#mode” was not declared as an OUTPUT parameter, but the actual parameter passed in requested output - sql

I have this stored procedure:
ALTER PROCEDURE spCertificationType
#result nvarchar(15) output,
#mode int
AS
BEGIN
if #mode = 1
begin
exec spGeneratedID 2, #result output
print #result
end
END
but when I tried to execute it,it has this error
The formal parameter “#mode” was not declared as an OUTPUT parameter, but the actual parameter passed in requested output.
I tried to set #mode as output like this:
ALTER PROCEDURE spCertificationType
#result nvarchar(15) output,
#mode int output
AS
BEGIN
if #mode = 1
begin
exec spGeneratedID 2, #result output
print #result
end
END
but the it returns a null value.
Any fix for this? Thanks in advance.

the sequence of parameter in store procedure is that first use input parameter then use output parameter:-
you can see this link for more knowledge of store procedure:-
http://www.codeproject.com/Articles/126898/Sql-Server-How-To-Write-a-Stored-Procedure-in-SQL
ALTER PROCEDURE spCertificationType
#mode int,
#result nvarchar(15) output
AS
BEGIN
if #mode = 1
begin
exec spGeneratedID 2, #result output
print #result
end
END

I fixed this error a different way.
I had removed the OUTPUT statement after a parameter in my SP.
I then got the error.
I then went back to the SQLDataSource Configure Data Source wizard and went through the steps again. I discovered that changing the SP made the wizard delete the settings associated with the parameter that used to have OUTPUT after it.

In my case, I had declared the OUTPUT parameter last but was also getting a similar exception.
I moved the default parameters (like #var FLOAT = null) to the end after the output parameter then it started working.

Related

Why is the default value in the output parameter of this stored procedure not returning? [duplicate]

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.

Save result of stored procedure to variable

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

How to change data type of output of stored procedure? I want to output money data type but procedure always returns int

This is my procedure:
ALTER PROCEDURE spMaxOfInvoiceTotal
AS
BEGIN
DECLARE #max MONEY
SET #max = (SELECT MAX(InvoiceTotal) FROM Invoices)
PRINT #MAX
RETURN #MAX
END
GO
But when I execute, it returns int not money type.
DECLARE #return_value int
EXEC #return_value = [dbo].[spMaxOfInvoiceTotal]
SELECT 'Return Value' = #return_value
GO
As a result, a value is incorrect. It has to be 37966.19. But procedure returns 37966.
Even if I change #return_value money, I still get int. How to change procedure so return value would be money?
Stored procedure return value is used to return exit code, it is integer.
You should define output parameter
CREATE PROCEDURE mysp
#Maxval MONEY OUTPUT
http://msdn.microsoft.com/en-us/library/ms188655.aspx
What RDBMS is this for? SQL Server?
The value returned from a stored procedure in SQL Server is always INT and you can't change that - it's typically used to convey back a success/failure flag, or a "number of rows affected" information.
If you to "return" a MONEY (or better yet: DECIMAL) value - you can either use an OUTPUT parameter (which works fine for a single value), or you need to return a result set with that value.
So in your case, you could try something like:
CREATE PROCEDURE GetMaxOfInvoiceTotal
#MaxValue DECIMAL(20,4) OUTPUT
AS
BEGIN
SET #MaxValue = (SELECT MAX(InvoiceTotal) FROM Invoices)
END
GO
and then call this stored procedure like this:
DECLARE #RC INT
DECLARE #MaxValue DECIMAL(20,4)
EXECUTE #RC = [dbo].[GetMaxOfInvoiceTotal] #MaxValue OUTPUT
GO

SQL Server output parameter issue

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

Is it possible to ignore an output param of a stored procedure?

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.