Calling stored procedure with return value - c#

I am trying to call a stored procedure from my C# windows application. The stored procedure is running on a local instance of SQL Server 2008. I am able to call the stored procedure but I am not able to retrieve the value back from the stored procedure. This stored procedure is supposed to return the next number in the sequence. I have done research online and all the sites I've seen have pointed to this solution working.
Stored procedure code:
ALTER procedure [dbo].[usp_GetNewSeqVal]
#SeqName nvarchar(255)
as
begin
declare #NewSeqVal int
set NOCOUNT ON
update AllSequences
set #NewSeqVal = CurrVal = CurrVal+Incr
where SeqName = #SeqName
if ##rowcount = 0 begin
print 'Sequence does not exist'
return
end
return #NewSeqVal
end
Code calling the stored procedure:
SqlConnection conn = new SqlConnection(getConnectionString());
conn.Open();
SqlCommand cmd = new SqlCommand(parameterStatement.getQuery(), conn);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter param = new SqlParameter();
param = cmd.Parameters.Add("#SeqName", SqlDbType.NVarChar);
param.Direction = ParameterDirection.Input;
param.Value = "SeqName";
SqlDataReader reader = cmd.ExecuteReader();
I have also tried using a DataSet to retrieve the return value with the same result. What am I missing to get
the return value from my stored procedure? If more information is needed, please let me know.

You need to add a ReturnValue-direction parameter to the command:
using (SqlConnection conn = new SqlConnection(getConnectionString()))
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = parameterStatement.getQuery();
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("SeqName", "SeqNameValue");
// #ReturnVal could be any name
var returnParameter = cmd.Parameters.Add("#ReturnVal", SqlDbType.Int);
returnParameter.Direction = ParameterDirection.ReturnValue;
conn.Open();
cmd.ExecuteNonQuery();
var result = returnParameter.Value;
}
Setting the parameter's direction to ParameterDirection.ReturnValue instructs the SqlCommand to declare it as a variable and assign the stored procedure's return value to it (exec #ReturnValue = spMyProcedure...), exactly like you would write it in SQL.

I know this is old, but i stumbled on it with Google.
If you have a return value in your stored procedure say "Return 1" - not using output parameters.
You can do the following - "#RETURN_VALUE" is silently added to every command object. NO NEED TO EXPLICITLY ADD
cmd.ExecuteNonQuery();
rtn = (int)cmd.Parameters["#RETURN_VALUE"].Value;

The version of EnterpriseLibrary on my machine had other parameters.
This was working:
SqlParameter retval = new SqlParameter("#ReturnValue", System.Data.SqlDbType.Int);
retval.Direction = System.Data.ParameterDirection.ReturnValue;
cmd.Parameters.Add(retval);
db.ExecuteNonQuery(cmd);
object o = cmd.Parameters["#ReturnValue"].Value;

I had a similar problem with the SP call returning an error that an expected parameter was not included. My code was as follows.
Stored Procedure:
#Result int OUTPUT
And C#:
SqlParameter result = cmd.Parameters.Add(new SqlParameter("#Result", DbType.Int32));
result.Direction = ParameterDirection.ReturnValue;
In troubleshooting, I realized that the stored procedure was ACTUALLY looking for a direction of "InputOutput" so the following change fixed the problem.
r
Result.Direction = ParameterDirection.InputOutput;

This is a very short sample of returning a single value from a procedure:
SQL:
CREATE PROCEDURE [dbo].[MakeDouble] #InpVal int AS BEGIN
SELECT #InpVal * 2; RETURN 0;
END
C#-code:
int inpVal = 11;
string retVal = "?";
using (var sqlCon = new SqlConnection(
"Data Source = . ; Initial Catalog = SampleDb; Integrated Security = True;"))
{
sqlCon.Open();
retVal = new SqlCommand("Exec dbo.MakeDouble " + inpVal + ";",
sqlCon).ExecuteScalar().ToString();
sqlCon.Close();
}
Debug.Print(inpVal + " * 2 = " + retVal);
//> 11 * 2 = 22

ExecuteScalar(); will work, but an output parameter would be a superior solution.

You can try using an output parameter. http://msdn.microsoft.com/en-us/library/ms378108.aspx

Or if you're using EnterpriseLibrary rather than standard ADO.NET...
Database db = DatabaseFactory.CreateDatabase();
using (DbCommand cmd = db.GetStoredProcCommand("usp_GetNewSeqVal"))
{
db.AddInParameter(cmd, "SeqName", DbType.String, "SeqNameValue");
db.AddParameter(cmd, "RetVal", DbType.Int32, ParameterDirection.ReturnValue, null, DataRowVersion.Default, null);
db.ExecuteNonQuery(cmd);
var result = (int)cmd.Parameters["RetVal"].Value;
}

I see the other one is closed. So basically here's the rough of my code. I think you are missing the string cmd comment. For example if my store procedure is call:DBO.Test. I would need to write cmd="DBO.test". Then do command type equal to store procedure, and blah blah blah
Connection.open();
String cmd="DBO.test"; //the command
Sqlcommand mycommand;

Related

Stored Procedure not accepting parameter value

I am new to SQL, so I need some help. I have a simple stored procedure that counts the rows in the select statement and returns the number of rows. I create an ODBC command and add all the information to it. When I call the stored procedure I get the error. Procedure or function 'CountUsers' expects parameter '#cacLogin', which was not supplied. The stored procedure works fine when I run it SMS. I have no Idea what the problem is. Any help will be greatly appreciated.
The stored procedure is:
CREATE PROCEDURE [dbo].[CountUsers]
(#cacLogin VARCHAR(100),
#rowcount INT OUTPUT)
AS
SELECT #rowcount = COUNT(*)
FROM UserInfo
WHERE strCACLogin = #cacLogin
RETURN #rowcount
GO
The SQL statement is:
public void storedprocedure()
{
int i;
OdbcConnection conn = new OdbcConnection(ConfigurationManager.ConnectionStrings["dbConnect3"].ConnectionString);
OdbcCommand dbComm = new OdbcCommand();
dbComm.Connection = conn;
dbComm.CommandType = CommandType.StoredProcedure;
dbComm.CommandText = "CountUsers";
dbComm.Parameters.Add("#cacLogin", OdbcType.VarChar, 100).Value = "MAULDIN.THOMAS.C.12345";
dbComm.Connection.Open();
i = dbComm.ExecuteNonQuery();
}
I'm not super experienced with calling stored procedures through OCDB myself but this documentation (https://support.microsoft.com/en-us/help/310130/how-to-execute-sql-parameterized-stored-procedures-by-using-the-odbc-n) suggests the proper way to call the stored procedure for your example would be:
new OdbcCommand("{call CountUsers(?)}", conn);
Change your Stored Procedure to this:
CREATE PROCEDURE [dbo].[CountUsers]
#cacLogin VARCHAR(100)
AS
BEGIN
DECLARE #rowcount INT
SELECT #rowcount = COUNT(*)
FROM UserInfo
WHERE strCACLogin = #cacLogin
RETURN #rowcount
END
And your C# code to this:
OdbcConnection conn = new OdbcConnection(ConfigurationManager.ConnectionStrings["dbConnect3"].ConnectionString);
OdbcCommand dbComm = new OdbcCommand();
dbComm.Connection = conn;
dbComm.CommandType = CommandType.StoredProcedure;
dbComm.CommandText = "CountUsers";
dbComm.Parameters.AddWithValue("#cacLogin", "MAULDIN.THOMAS.C.12345");
var returnParameter = dbComm.Parameters.Add("#rowcount", OdbcType.Int);
returnParameter.Direction = ParameterDirection.ReturnValue;
conn.Open();
dbComm.ExecuteNonQuery();
var i = returnParameter.Value;
I hope this helps you.
As per the comments, a direct SQL connection should work ok.
Using SqlConn As New SqlConnection(ConfigurationManager.ConnectionStrings("dbConnect3").ConnectionString)
SqlConn.Open()
Using cmd As New SqlCommand("CountUsers", SqlConn)
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.AddWithValue("#cacLogin", "MAULDIN.THOMAS.C.12345")
cmd.Parameters.Add("#rowcount", SqlDbType.Int).Direction = ParameterDirection.Output
cmd.ExecuteNonQuery();
End Using
End Using
Sorry for using VB but the DB calls are equivalent.

how to get oracle stored procedure standard output in c#

I am trying to get the stand output in c# returned from oracle stored procedure. dbms_output.put_line('Hello Word')
The c# code i am using is
using (OracleConnection con = new OracleConnection())
{
con.ConnectionString = My_connection_string;
con.Open();
OracleCommand cmd = new OracleCommand("tmp_test", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.BindByName = true;
var result = cmd.ExecuteScalar();
}
The oracle stored procedure code is
create or replace procedure tmp_test as
v_count integer;
begin
dbms_output.put_line('Hello Word');
end;
The stored procedure execute successfully but I can't get the Hello Word back.
After some struggle i have managed to find the answer and decided to post that might help other.
using (OracleConnection con = new OracleConnection())
{
con.ConnectionString = My_connection_string;
con.Open();
OracleCommand cmd = new OracleCommand("tmp_test", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.BindByName = true;
var result = cmd.ExecuteScalar();
//it is included dbms_output
cmd.CommandText = "begin dbms_output.enable (1000); end;";
cmd.CommandType = CommandType.Text;
cmd.ExecuteNonQuery();
string out_string;
int status = 0;
cmd.CommandText = "BEGIN DBMS_OUTPUT.GET_LINE (:out_string, :status); END;";
cmd.CommandType = CommandType.Text;
cmd.Parameters.Clear();
cmd.Parameters.Add("out_string", OracleType.VarChar, 32000);
cmd.Parameters.Add("status", OracleType.Double);
cmd.Parameters[0].Direction = System.Data.ParameterDirection.Output;
cmd.Parameters[1].Direction = System.Data.ParameterDirection.Output;
cmd.ExecuteNonQuery();
out_string = cmd.Parameters[0].Value.ToString();
status = int.Parse(cmd.Parameters[1].Value.ToString());
}
Here's a link to a the documentation for DBMS_OUTPUT package in Oracle - DBMS_OUTPUT
It specifically states that it's used for debugging Oracle Stored Procedures and that this is in essence a debug buffer that you need to actively poll use GET_LINES in order to see the output.
Function in PL/SQL should be something like this:
create or replace function tmp_test as
begin
RETURN 'Hello World';
end;

Register output parameter for calling stored procedure in SQL

I have this stored procedure:
create procedure sp_findMaxEmployee
#maxID as varchar(10) OUTPUT
as
SET #maxID = (SELECT MAX(e_ID) FROM Employee)
go
I try to register an output parameter like this:
public string generateID()
{
connection = new SqlConnection(connectionStr);
cmd = new SqlCommand("sp_findMaxEmployee", connection);
SqlParameter param = new SqlParameter();
param.ParameterName = "#maxID";
param.Direction = ParameterDirection.Output;
param.SqlDbType = SqlDbType.VarChar;
cmd.Parameters.Add(param);
connection.Open();
cmd.ExecuteNonQuery();
connection.Close();
return cmd.Parameters["#maxID"].Value.ToString();
}
I tried to execute this procedure in SQL and it return right value, but when I execute project in debug mode, it shows me error:
String[0]: the Size property has an invalid size of 0.
Null value? Can you help me, thank you so much!
Assuming e_ID is a integer, you can just perform a SELECT and ExecuteScalar to return a single value:
create procedure sp_findMaxEmployee
as
SELECT MAX(e_ID) FROM Employee
go
Then in code, something like:
public string generateID()
{
connection = new SqlConnection(connectionStr);
cmd = new SqlCommand("sp_findMaxEmployee", connection);
connection.Open();
var maxId = cmd.ExecuteScalar();
connection.Close();
return maxId.ToString();
}
Finally, there's probably a deeper question as to why you are returning the last ID, hopefully it's not to get the next available ID, which you should let SQL do on your behalf by letting it auto-increment.
Little Tweak for SP
The Tweak is not necessary but it looks better this way :) and also please avoid using sp_ prefix for your stored procedures. Use usp_ instead.
create procedure usp_findMaxEmployee
#maxID as varchar(10) OUTPUT
AS
BEGIN
SET NOCOUNT ON;
SELECT #maxID = MAX(e_ID) FROM Employee;
END
Calling from Code
public string generateID()
{
SqlConnection conn = new SqlConnection(connectionStr);
SqlCommand cmd = new SqlCommand("usp_findMaxEmployee", conn);
cmd.CommandType = CommandType.StoredProcedure;
// set up the parameters
cmd.Parameters.Add("#maxID", SqlDbType.VarChar, 10).Direction = ParameterDirection.Output;
// open connection and execute stored procedure
conn.Open();
cmd.ExecuteNonQuery();
// read output value from #maxID
String maxID = Convert.ToString(cmd.Parameters["#maxID"].Value);
conn.Close();
return maxID;
}
Note
Use the using block of Try/Catch/Finnaly blocks to close connection if anything goes wrong.
You need to specify a .Size for your parameter. Your stored procedure specifies an output of varchar(10), so you should set the param.Size = 10;
You need to specify that cmd.CommandType = CommandType.StoredProcedure, the default CommandType is CommandType.Text
Make those changes and your method works as you intended.

SQL error with Stored Procedure

I am inserting rows in sql table through my c# code , which calls a Stored procedure .
C# code:
SqlCommand myCommand = thisConnection.CreateCommand();
myCommand.CommandText = "FederationUpdateCTRAndImpressionCountsForAllYPIds";
myCommand.CommandType = CommandType.StoredProcedure;
myCommand.Parameters.Add("#bid", SqlDbType.UniqueIdentifier);
myCommand.Parameters.Add("#uid", SqlDbType.UniqueIdentifier);
myCommand.Parameters.Add("#imp", SqlDbType.VarChar);
myCommand.Parameters.Add("#ctr", SqlDbType.VarChar);
while (myfederationReader.Read())
{
myCommand.Parameters["#bid"].Value = myfederationReader["BusinessId"];
myCommand.Parameters["#uid"].Value = myfederationReader["UId"];
myCommand.Parameters["#imp"].Value = myfederationReader["Impression"];
myCommand.Parameters["#ctr"].Value = myfederationReader["CTR"];
rowsAffected = myCommand.ExecuteNonQuery();
}
Stored proc:
CREATE PROCEDURE [dbo].[FederationUpdateCTRAndImpressionCountsForAllYPIds]
#bid uniqueidentifier,
#uid uniqueidentifier,
#imp varchar(255),
#ctr varchar(255)
AS BEGIN
UPDATE BasicBusinessInformation
SET BasicBusinessInformation.CTR = #ctr , BasicBusinessInformation.Impression = #imp
WHERE BasicBusinessInformation.BusinessId = #bid AND BasicBusinessInformation.UId = #uid
END
On executing it , following error is reported:
procedure has no parameters and arguments were supplied
Try clearing the Command parametres
[C#]
public bool ExportAndClear() {
SqlParameter[] myParamArray = new SqlParameter[myCmd.Parameters.Count - 1];
myCmd.Parameters.CopyTo(myParamArray, 0);
myCmd.Parameters.Clear();
return true;
}
try to fetch data from reader before you fire this command
like
1)Fetch data from reader and store in list or datatable
2)For loop on list or datatable
3)in for loop fire this command
Try moving the following
SqlCommand myCommand = thisConnection.CreateCommand();
myCommand.CommandText = "FederationUpdateCTRAndImpressionCountsForAllYPIds";
myCommand.CommandType = CommandType.StoredProcedure;
myCommand.Parameters.Add("#bid", SqlDbType.UniqueIdentifier);
myCommand.Parameters.Add("#uid", SqlDbType.UniqueIdentifier);
myCommand.Parameters.Add("#imp", SqlDbType.VarChar);
myCommand.Parameters.Add("#ctr", SqlDbType.VarChar);
In the while loop, see if you get different results.

passing parameters to a stored procedure in C#

How can i send three parameters a to stored procedure in sql?
Here is my error: Procedure or function GetIslemIdleri has too many arguments specified.
This is my stored procedure:
CREATE PROCEDURE GetIslemDetayIdleri
#islemId int,
#dovizTanim nvarchar(10),
#yapilanIslemTuru nvarchar(20)
AS
BEGIN
SET NOCOUNT ON;
SELECT ([t0].[TOPLAMTUTAR]) + ([t0].[KDVTUTAR]) AS [value]
FROM [dbo].[TBLP1ISLEMDETAY] AS [t0]
INNER JOIN [dbo].[TBLP1ISLEM] AS [t1] ON [t1].[ID] = [t0].[ISLEM_ID]
WHERE ([t0].[ISLEM_ID] = #islemId) AND
([t0].[FIYATBIRIM] = #dovizTanim) AND
([t1].[YAPILANISLEM] = #yapilanIslemTuru) AND
([t0].[KDVDAHILMI] = 0)
END
Here is my code:
decimal kurToplamQuery = 0;
string connString = System.Configuration.ConfigurationManager.ConnectionStrings["LocalSqlServer1"].ConnectionString;
SqlConnection sqlConn = new SqlConnection(connString);
sqlConn.Open();
SqlCommand cmd;
cmd = new SqlCommand("GetIslemIdleri", sqlConn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("#islemId", SqlDbType.Int)).Value = islemId;
cmd.Parameters.Add(new SqlParameter("#dovizTanim", SqlDbType.NVarChar)).Value = dovizTanim;
cmd.Parameters.Add(new SqlParameter("#yapilanIslemTuru", SqlDbType.NVarChar)).Value = yapilanIslemTipi;
using (var reader = cmd.ExecuteReader())*//error occurs here*
{
while (reader.Read())
{
kurToplamQuery = reader.GetDecimal(0);
}
}
sqlConn.Close();
return kurToplamQuery;
Thanks for your helps.
The stored procedure is called GetIslemDetayIdleri but the code is using a stored procedure called GetIslemIdleri. Maybe the latter has fewer parameters than the former and you meant to call the former in the code?
Your stored procedure: GetIslemDetayIdleri have different name then your invocation:
cmd = new SqlCommand("GetIslemIdleri", sqlConn);
GetIslemDetayIdleri != GetIslemIdleri
in my case this code is worked .i hope this will work for your case
Procedure parameter names , type and lenght must be same
like that
cmd.Parameters.Add(new SqlParameter("#islemId", SqlDbType.Int)).Value = islemId;
cmd.Parameters.Add(new SqlParameter("#dovizTanim", SqlDbType.NVarChar ,10)).Value = dovizTanim;
cmd.Parameters.Add(new SqlParameter("#yapilanIslemTuru", SqlDbType.NVarChar,20)).Value = yapilanIslemTipi;

Categories