As a part of getting to learn Stored procedures , I came up with this.
CREATE PROCEDURE StoredProcedure1
#oResult int output
AS
BEGIN
SELECT #oResult = 2
RETURN #oResult
END
But the problem is on execution of this SP, it just returns something like.
Procedure or function 'StoredProcedure1' expects parameter '#oResult', which was not supplied.
I want this procedure just to return a result when called.
Any ideas why ?
I supplied as it was asking,EXEC StoredProcedure1 #oResult = 0 but it just says Command Completed Successfully but no output.
Any ideas why ?
In ADO.NET when you call a Stored Procedure that expects a parameter, you need to give that parameter, also if it is an output parameter.
using(SqlConnection cnn = new SqlConnection(.....))
using(SqlCommand cmd = new SqlCommand("StoredProcedure1", cnn))
{
cnn.Open();
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter p = new SqlParameter("#oResult", SqlDbType.Int);
p.Direction = ParameterDirection.Output;
cmd.Parameters.Add(p);
cmd.ExecuteNonQuery();
int result = Convert.ToInt32(cmd.Parameters["#oResult"].Value);
}
Of course, in the stored procedure you should set the #oResult parameter in some way as explained in the other answers, but if you use an OUTPUT parameter there is no need to RETURN the same value.
However you could have both an OUTPUT parameter and a RETURN value if you need to. In this case your call from C# should be
using(SqlConnection cnn = new SqlConnection(.....))
using(SqlCommand cmd = new SqlCommand("StoredProcedure1", cnn))
{
cnn.Open();
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter p = new SqlParameter("#oResult", SqlDbType.Int);
p.Direction = ParameterDirection.Output;
cmd.Parameters.Add(p);
// Here the name #returnValue is arbitrary, you could call it whatever you like
SqlParameter r = new SqlParameter("#returnValue", SqlDbType.Int);
r.Direction = ParameterDirection.ReturnValue;
cmd.Parameters.Add(r);
cmd.ExecuteNonQuery();
int result = Convert.ToInt32(cmd.Parameters["#oResult"].Value);
int returnValue = Convert.ToInt32(cmd.Parameters["#returnValue"].Value);
}
But keep in mind that RETURN values are limited to Integer Expressions.
You could do this:
Store procedure
CREATE PROCEDURE StoredProcedure1
#oResult int output
AS
BEGIN
SET #oResult = 2
END
And then calling it like this:
DECLARE #Result INT
exec StoredProcedure1 #oResult = #Result output
SELECT #Result
This will output
2
Update:
Like addressed in the comment. You could also simplify the statement. By doing this:
DECLARE #Result INT
exec StoredProcedure1 #Result output
SELECT #Result
Reference:
Execute stored procedure with an Output parameter?
You do not need to write return ..try below code :-
CREATE PROCEDURE StoredProcedure1
#oResult int output
AS
BEGIN
SET #oResult = 2
END
CREATE PROCEDURE SP1
(
#oResult int output
)
AS
BEGIN
SET #oResult=2
Select #oResult
END
Related
I am using the following code to run a stored procedure given some input from user. The stored procedure updates some tables if the input was valid and there isn’t going to be a duplicate record.
If the input is invalid or that record already exists, stored procedure returns a value of the OUT parameter that is assigned to variable message.
How can I display the value of message on the screen? Messabebox would be ideal, but couldn’t find where should call it from.
partial void MyStorProc_Inserting(MyStorProcOperation entity)
{
using (SqlConnection connection = new SqlConnection())
{
string connMyDB = this.DataWorkspace.MyDB.Details.Name;
connection.ConnectionString = ConfigurationManager.ConnectionStrings[connMyDB].ConnectionString;
string proc = "[MyDB].[dbo].[szMyStorProc]";
using (SqlCommand command = new SqlCommand(proc, connection))
{
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("#Uname", entity.Uname));
command.Parameters.Add(new SqlParameter("#BU", entity.BU));
SqlParameter output = new SqlParameter();
output.ParameterName = "#ResultDescription";
output.SqlDbType = System.Data.SqlDbType.VarChar;
output.Direction = ParameterDirection.Output;
output.Size = 256;
command.Parameters.Add(output);
connection.Open();
command.ExecuteNonQuery();
string message = output.Value.ToString();
}
}
this.Details.DiscardChanges();
}
stored procedure goes somewhat like this:
CREATE PROCEDURE [dbo].[szMyStorProc]
-- Add the parameters for the stored procedure here
#Uname varchar(50) = '',
#BU varchar(50) = '',
#ResultDescription varchar(256)= '' OUTPUT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
DECLARE #EmployeeID INT
DECLARE #BUID INT
SELECT #EmployeeID = ID FROM tEmployee WHERE Uname = #Uname
IF #EmployeeID IS NULL
BEGIN
SELECT #ResultDescription = 'User name not found'
PRINT #ResultDescription
END
ELSE
...
...
END
GO
Hi all I have the following stored procedure
#UserName varchar(150),
#UserEmail varchar(300),
#UserPassword varchar(150),
#ContactNumber varchar(150),
#ContactMobile varchar(150),
#AreaOfCountry varchar(150),
#UserId int OUTPUT,
#AllreadyReg int OUTPUT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
--DECLARE #UserId int, #AllreadyReg int
IF (SELECT COUNT(UserId) FROM Users WHERE (UserName = #UserName) OR (UserEmail = #UserEmail)) > 0
BEGIN
SET #UserId = 0
SET #AllreadyReg = 1
END
ELSE
BEGIN
INSERT INTO Users (UserName,UserEmail,UserPassword,ContactNumber,ContactMobile,AreaOfCountry) VALUES (#UserName,#UserEmail,#UserPassword,#ContactNumber,#ContactMobile,#AreaOfCountry)
SELECT #UserId = SCOPE_IDENTITY()
SET #AllreadyReg = 0
END
however when I use it using c# and asp.net its not returning anything, however when I just execute it it does have a results #UserId and #AllreadyReg but the return value is 0 and a single field.
my c# code is below but it never has any rows
using (SqlConnection con = new SqlConnection(connectionString))
{
Response.Write("Line 61");
using (SqlCommand cmd = new SqlCommand("spR_Register", con))
{
Response.Write("line 64");
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#UserName", TxtUsername.Text.Trim());
cmd.Parameters.AddWithValue("#UserEmail", TxtEmail.Text.Trim());
cmd.Parameters.AddWithValue("#UserPassword", TxtPassword.Text.Trim());
cmd.Parameters.AddWithValue("#ContactNumber", TxtPhone.Text);
cmd.Parameters.AddWithValue("#ContactMobile", TxtMobile.Text);
cmd.Parameters.AddWithValue("#AreaOfCountry", TxtAreaOfCountry.SelectedValue);
cmd.Parameters.AddWithValue("#UserId", ParameterDirection.Output);
cmd.Parameters.AddWithValue("#AllreadyReg", ParameterDirection.Output);
con.Open();
SqlDataReader reader = cmd.ExecuteReader();
if (reader.HasRows)
{
Response.Write("line 78");
etc etc
can anyone help
thanks
With the edit: the mistake is using ExecuteReader on a command that doesn't select a data grid - that should be done with ExecuteNonQuery.
The important thing here is how the parameter is added. For example:
var alreadyReg = cmd.CreateParameter();
alreadyReg.Direction = System.Data.ParameterDirection.Output;
alreadyReg.ParameterName = "AllreadyReg";
alreadyReg.DbType = DbType.Int32;
cmd.Parameters.Add(alreadyReg);
//...
cmd.ExecuteNonQuery();
//...
int val = (int)alreadyReg.Value;
Depending on the type of DbCommand object, there may be an overload that accepts all of these in one line - the above assumes just DbCommand. With SqlCommand, you can simplify a bit:
var alreadyReg = cmd.Parameters.Add("AllreadyReg", SqlDbType.Int);
alreadyReg.Direction = ParameterDirection.Output;
//...
cmd.ExecuteNonQuery();
//...
int val = (int)alreadyReg.Value
You might have already handled it, but just in case, make sure to specify direction of parameter in c# code.
Here
cmd.Parameters.AddWithValue("#UserId", ParameterDirection.Output);
wrong usage of AddWithValue. The second parameter is parsed as parameter value, not direction type. Use proper parameter contructor and the add the result to collection.
Alter procedure budgetno_proc
#wono varchar(max),
#retvalue varchar(max) output
as
begin
declare #budno varchar(max)
if not exists(select * from budgetdet where wono=#wono)
begin
set #budno =LEFT(#wono,13)+'-'+RIGHT('0'+CAST((SELECT ISNULL(MAX(CONVERT(INT,LEFT(#wono,13))),0)+1 from budgetdet WHERE wono=#wono) AS VARCHAR(20)),1)
end
else
begin
set #budno=LEFT(#wono,13)+'-'+'1R'+'-'+RIGHT('000'+CAST((SELECT MAX(CONVERT(INT,SUBSTRING(budno,18,LEN(budno))))+1 from budgetdet WHERE wono=#wono) AS VARCHAR(20)),3)
end
set #retvalue = #budno
end
This is my stored procedure with output parameter.
And this is my C# code:
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["gdb"].ConnectionString);
con.Open();
SqlCommand cmd = new SqlCommand("budgetno_proc", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#wono",Workorder_txt.Text);
SqlParameter param = new SqlParameter("#retvalue", SqlDbType.VarChar,30);
param.Direction = ParameterDirection.ReturnValue;
cmd.Parameters.Add(param);
string budgetnum = (string)cmd.Parameters["#retvalue"].Value;
cmd.ExecuteNonQuery();
con.Close();
I can't get that #retvalue value from the procedure.
Any changes that I have to make? Please note it.
Thanks
You have set the ParameterDirection to Output instead of ReturnValue
param.Direction = ParameterDirection.Output;
cmd.Parameters.Add(param);
cmd.ExecuteNonQuery();
string budgetnum = (string)cmd.Parameters["#retvalue"].Value;
Surely you need to swap these lines
cmd.ExecuteNonQuery();
string budgetnum = (string)cmd.Parameters["#retvalue"].Value;
Execute first and then try to read the return value
At first glance, if you want to use ParamDirection.ReturnValue you need to add the RETURN statement as the last line of your SP, but, looking at the page about RETURN statement you will notice this info about the return expression
Is the integer value that is returned. Stored procedures can return an
integer value to a calling procedure or an application.
So you cannot return a string. This leaves only one option.
Using the ParamDirection.Output for the #retvalue parameter instead of the ReturnValue.
Also you have another problem. The size of the parameter cannot be fixed to 30 char if you expect (or declare) an output parameter of VARCHAR(MAX). You need to set the size to -1 on the C# side of your code.
So these lines need to be changed
SqlParameter param = new SqlParameter("#retvalue", SqlDbType.VarChar,-1); //<-Size=-1
param.Direction = ParameterDirection.Output; // <- Output
cmd.Parameters.Add(param);
I am using a code to call a Stored Procedure having 2 output and 1 input parameter. But i keep getting an error every time I call this stored proc:
CREATE PROCEDURE [dbo].[usp_StoredProcName]
#inputVal nvarchar(255),
#isError bit OUTPUT,
#errorInfo nvarchar(255) OUTPUT
AS BEGIN
DECLARE #totalRow int = 0;
DECLARE #inputValID uniqueidentifier;
SET #isError = 1;
SET #errorInfo = '';
SELECT #inputValID = [inputValID]
FROM testTable
WHERE inputVal = #inputVal;
IF #inputValID IS NULL
BEGIN
SET #isError = 0;
SET #errorInfo = 'inputVal not found';
RETURN
END
END
I have used couple of C# methods to call the stored proc and I get they all return this error:
Procedure or function 'usp_StoredProcName' expects parameter '#inputVal', which was not supplied.
C# Method 1 (to call the stored proc)
using (SqlConnection con = new SqlConnection(myFullConncectionStringToDB))
{
using (SqlCommand cmd = new SqlCommand("usp_StoredProcName", con))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#inputVal", "MyParamVal_12345");
cmd.Parameters["#isError"].Direction = ParameterDirection.Output;
cmd.Parameters["#errorInfo"].Direction = ParameterDirection.Output;
con.Open();
cmd.ExecuteNonQuery();
var isError = cmd.Parameters["#isError"].Value;
var errInfo = cmd.Parameters["#errorInfo"].Value;
con.Close();
}
}
Method 2 ( to call the stored proc)
SqlConnection con = new SqlConnection(myFullConncectionStringToDB);
SqlCommand cmd = new SqlCommand("usp_StoredProcName", con);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter in_parm = new SqlParameter("#inputVal", SqlDbType.NVarChar);
in_parm.Size = 255;
in_parm.Value = "MyParamVal_12345";
in_parm.Direction = ParameterDirection.Input;
cmd.Parameters.Add(in_parm);
SqlParameter out_parm = new SqlParameter("#errorInfo", SqlDbType.NVarChar);
out_parm.Size = 255;
out_parm.Direction = ParameterDirection.Output;
cmd.Parameters.Add(out_parm);
SqlParameter out_parm1 = new SqlParameter("#isError", SqlDbType.Bit);
out_parm1.Direction = ParameterDirection.Output;
cmd.Parameters.Add(out_parm1);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
Both of the above methods I tried return the same error:
Procedure or function 'usp_StoredProcName' expects parameter '#inputVal', which was not supplied.
Please tell me what am I doing wrong here in my C# code to execute the stored procedure.
I am clearly passing the parameter value in both of my methods but can't figure out why I keep getting this error.
Thank you for your help.
I usually break down the solution into pieces an make sure each one works.
First, test the Stored Procedure to make sure it works as planned. Sample call is below.
-- Switch to your database
USE [YourDatabase]
GO
-- Declare output variables
DECLARE #out_is_error bit;
DECLARE #out_error_info nvarchar(255);
-- Execute sp
EXECUTE [dbo].[usp_StoredProcName]
N'In Data',
#isError = #out_is_error OUTPUT,
#errorInfo = #out_error_info OUTPUT;
-- Show any SQL errors / return data
PRINT ##ERROR;
PRINT 'Error = ' + #out_error_info;
PRINT 'Flag = ';
PRINT CAST(#out_is_error as CHAR(1));
GO
Next, look at the C# piece of the puzzle. Aaron suggestion about correct database is a good one. Do you have two copies of the SP floating around?
Good luck.
I'm trying to retrieve the return value of a stored procedure in SQL Server 2005 as follows:
OleDbCommand comm = new OleDbCommand(process_name, connection);
comm.CommandType = CommandType.StoredProcedure;
for (int i = 0; i < process_parameters.Length; i++)
comm.Parameters.AddWithValue(process_parameters[i].ParameterName, process_parameters[i].Value);
//Add output param
comm.Parameters.Add("#TestID", OleDbType.Integer).Direction = ParameterDirection.ReturnValue;
comm.ExecuteNonQuery();
When ExecuteNonQuery() is called, however, I get back a OleDbException saying: "Procedure or function myStoredProcedure has too many arguments specified." My stored procedure begins as follows:
ALTER PROCEDURE [dbo].[spTabtempTestsINSERT]
(
#Param1 char (64),
#Param2 char (128),
#Param3 char (64),
)
AS
BEGIN
Declare #TestID int
And ends with the following:
RETURN #TestID
END
Does the fact that the return value is declared, rather than being passed as a parameter, have anything to do with it? If so, how can I get the return value of a param that's declared after the stored procedure begins? Thanks for your help.
UPDATE:
I've tried the changes suggested so far, I added the following line:
OleDbCommand comm = new OleDbCommand(process_name, connection);
comm.CommandType = CommandType.StoredProcedure;
for (int i = 0; i < process_parameters.Length; i++)
comm.Parameters.AddWithValue(process_parameters[i].ParameterName, process_parameters[i].Value);
var testID = (int)comm.ExecuteScalar();
Now when ExecuteScalar() gets executed, I get a NullReferenceException with Object reference not set to an instance of an object.
Note: I also tried setting it to an integer int testID = (int)comm.ExecuteScalar(); and I still get the same error.
Change
comm.ExecuteNonQuery();
to
int returnValue = (int) comm.ExecuteScalar();
And remove:
comm.Parameters.Add("#TestID", OleDbType.Integer).Direction = ParameterDirection.ReturnValue;
I thought ExecuteNonQuery() doesn't return anything from SQL..... am I missing something here?
remove these:
//Add output param
comm.Parameters.Add("#TestID", OleDbType.Integer).Direction = ParameterDirection.ReturnValue;
comm.ExecuteNonQuery();
and use this instead: var testID = (int) comm.ExecuteScalar();
Ok, I was able to get it to work properly. My problem was that, I neglected to declare any of the parameters as OUTPUT, I added an extra variable and set that as the output variable and had the stored procedure return that. After word I just checked that output parameter ,after calling the stored procedure, from my C# code, the following shows the changes:
ALTER PROCEDURE [dbo].[spTabtempTestsINSERT]
(
#Param1 char (64),
#Param2 char (128),
#Param3 char (64),
#ReturnValue int OUTPUT
)
AS
BEGIN
Declare #TestID int
And at the end make a simple change:
SET #ReturnValue = #TestID
RETURN #ReturnValue
END
Finally, back in my code:
OleDbCommand comm = new OleDbCommand(process_name, connection);
comm.CommandType = CommandType.StoredProcedure;
for (int i = 0; i < process_parameters.Length; i++)
comm.Parameters.AddWithValue(process_parameters[i].ParameterName, process_parameters[i].Value);
//Add output param
comm.Parameters.Add("#ReturnValue", OleDbType.Integer).Direction = ParameterDirection.ReturnValue;
comm.ExecuteNonQuery();
Console.WriteLine("Stored Procedure returned a value of "+ comm.Parameters["#ReturnValue"].Value); //Success
Thank you all for your suggestions. Any alternatives or further insights are welcome.
In response to the accepted answer...
Because you are setting the parameter's Direction to ReturnValue here:
comm.Parameters.Add("#ReturnValue", OleDbType.Integer).Direction = ParameterDirection.ReturnValue;
You don't need an OUTPUT parameter in your stored procedure at all. You could change it back to:
ALTER PROCEDURE [dbo].[spTabtempTestsINSERT]
(
#Param1 char (64),
#Param2 char (128),
#Param3 char (64),
)
AS
BEGIN
Declare #TestID int
With:
RETURN #TestID
END
at the end and it would still work exactly as it does now.
It is purely coincidental that your ReturnValue Parameter in C# bears the same name as your OUTPUT parameter. There is a separate parameter Direction for OUTPUT parameters.
I had the same issue, the problem is that you have to declare the return parameter first (before the input and output ones), this way it works:
OleDbCommand comm = new OleDbCommand(process_name, connection);
comm.CommandType = CommandType.StoredProcedure;
//Add the return param first
comm.Parameters.Add("#TestID", OleDbType.Integer).Direction = ParameterDirection.ReturnValue;
for (int i = 0; i < process_parameters.Length; i++)
comm.Parameters.AddWithValue(process_parameters[i].ParameterName, process_parameters[i].Value);
comm.ExecuteNonQuery();
Object return_value = comm.Parameters["#TestID"].Value;