I have an existing stored procedure in SQL Server that I need to call from my C# code and get result. Here is how this SP looks like
CREATE PROCEDURE [dbo].[sp_MSnextID_DDB_NextID]
#tablesequence varchar(40)
AS
declare #next_id integer
begin transaction
update DDB_NextID
set DDB_SEQUENCE = DDB_SEQUENCE + 1
where DDB_TABLE = #tablesequence
select #next_id = DDB_SEQUENCE from DDB_NextID
where DDB_TABLE = #tablesequence
commit transaction
RETURN #next_id
Here is my C# code
using (OdbcConnection connection = new OdbcConnection(GetConnectionString()))
{
using (IDbCommand command = new OdbcCommand())
{
command.CommandText = "sp_MSnextID_DDB_NEXTID";
command.CommandType = CommandType.StoredProcedure;
IDbDataParameter parameter1 = command.CreateParameter();
parameter1.DbType = DbType.String;
parameter1.ParameterName = "#tablesequence";
parameter1.Value = "ddb_dc_document";
parameter1.Direction = ParameterDirection.Input;
command.Parameters.Add(parameter1);
IDbDataParameter parameter2 = command.CreateParameter();
parameter2.DbType = DbType.Int32;
parameter2.ParameterName = "#Return_Value";
parameter2.Direction = ParameterDirection.ReturnValue;
command.Parameters.Add(parameter2);
command.Connection = connection;
connection.Open();
command.ExecuteNonQuery();
IDbDataParameter o = (command.Parameters)["#Return_Value"] as IDbDataParameter;
//Got return value from SP in o.Value
}
}
The trouble is I am getting exception
[42000] [Microsoft][SQL Native Client][SQL Server]Procedure or function 'sp_MSnextID_DDB_NextID' expects parameter '#tablesequence',
which was not supplied.
which I can't explain or fix. What I am missing?
To find a way around, I was trying different approach: executing the following query that sets data in a temp table
create table #temp (i integer); insert into #temp exec sp_MSNextID_DDB_NEXTID #tablesequence='ddb_dc_document';select * from #temp;
In this case SP is executed correctly but select returns zero rows!
Unfortunately, you can't use named parameters with OdbcCommand. You will need to instead execute a call statement to your stored procedure.
using (OdbcConnection connection = new OdbcConnection(GetConnectionString()))
{
using (IDbCommand command = new OdbcCommand())
{
command.CommandText = "{ ? = CALL sp_MSnextID_DDB_NEXTID(?) }";
command.CommandType = CommandType.StoredProcedure;
IDbDataParameter parameter2 = command.CreateParameter();
parameter2.DbType = DbType.Int32;
parameter2.ParameterName = "#Return_Value";
parameter2.Direction = ParameterDirection.ReturnValue;
command.Parameters.Add(parameter2);
IDbDataParameter parameter1 = command.CreateParameter();
parameter1.DbType = DbType.String;
parameter1.ParameterName = "#tablesequence";
parameter1.Value = "ddb_dc_document";
parameter1.Direction = ParameterDirection.Input;
command.Parameters.Add(parameter1);
command.Connection = connection;
connection.Open();
command.ExecuteNonQuery();
IDbDataParameter o = (command.Parameters)["#Return_Value"] as IDbDataParameter;
//Got return value from SP in o.Value
}
}
To make your workaround work you should replace
RETURN #next_id
in your procedure with
SELECT #next_id
Related
Hi I am trying to call an as400 stored procedure using OleDB. Could you please post an example of how to do it cause I've been following some tutorials but not matter what I do I always get an Invalid Token Exception
this is what I do
OleDbCommand sp = new OleDbCommand("CALL NASVARWG.SP001(?,?,?,?,?) ", connectionDB);
sp.CommandType = CommandType.StoredProcedure;
sp.Parameters.Add("P1", System.Data.OleDb.OleDbType.Char).Value = "ESANASTRIS";
sp.Parameters["P1"].Size = 10;
sp.Parameters["P1"].Direction = ParameterDirection.Input;
sp.Parameters.Add("P2", System.Data.OleDb.OleDbType.Char).Value = "SAMNAS";
sp.Parameters["P2"].Size = 10;
sp.Parameters["P2"].Direction = ParameterDirection.Input;
sp.Parameters.Add("P3", System.Data.OleDb.OleDbType.Char).Value = textBox_Reparto.Text;
sp.Parameters["P3"].Size = 6;
sp.Parameters["P3"].Direction = ParameterDirection.Input;
sp.Parameters.Add("P4", System.Data.OleDb.OleDbType.Char).Value = "we can do this";
sp.Parameters["P4"].Size = 60;
sp.Parameters["P4"].Direction = ParameterDirection.Input;
sp.Parameters.Add("P5", System.Data.OleDb.OleDbType.Char).Value = "help";
sp.Parameters["P5"].Size = 256;
sp.Parameters["P5"].Direction = ParameterDirection.Input;
sp.Prepare();
sp.ExecuteNonQuery();
the exception I get says "NASVARWG" is not a valid token. Why? that is the name of the library containing the procedure and the spelling is correct.
Thanks for your help
A C# code with CommandType.StoredProcedure example :
// assume a DB2Connection conn
DB2Transaction trans = conn.BeginTransaction();
DB2Command cmd = conn.CreateCommand();
String procName = "INOUT_PARAM";
cmd.Transaction = trans;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = procName;
A C# code with CommandType.Text example :
// assume a DB2Connection conn
DB2Transaction trans = conn.BeginTransaction();
DB2Command cmd = conn.CreateCommand();
String procName = "INOUT_PARAM";
String procCall = "CALL INOUT_PARAM (#param1, #param2, #param3)";
cmd.Transaction = trans;
cmd.CommandType = CommandType.Text;
cmd.CommandText = procCall;
// Register input-output and output parameters for the DB2Command
cmd.Parameters.Add( new DB2Parameter("#param1", "Value1");
cmd.Parameters.Add( new DB2Parameter("#param2", "Value2");
DB2Parameter param3 = new DB2Parameter("#param3", IfxType.Integer);
param3.Direction = ParameterDirection.Output;
cmd.Parameters.Add( param3 );
// Call the stored procedure
Console.WriteLine(" Call stored procedure named " + procName);
cmd.ExecuteNonQuery();
// Register input-output and output parameters for the DB2Command
...
// Call the stored procedure
Console.WriteLine(" Call stored procedure named " + procName);
cmd.ExecuteNonQuery();
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.
procedure select_card_transaction(trans_id nvarchar2,
usr_id number,
Quantity out number) is
begin
select count(*)
into Quantity
from user_cards u
where u.transaction_id = trans_id
and u.user_id = usr_id;
end;
and Consuming it:
using(var conn = new OracleConnection(Settings.Default.OraWUConnString))
{
var cmd = conn.CreateCommand();
cmd.CommandText = "for_temporary_testing.select_card_transaction";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("trans_id", TransactionID);
cmd.Parameters.AddWithValue("usr_id", UserID);
var q = new OracleParameter("Quantity", OracleType.Number);
q.Direction = ParameterDirection.Output;
cmd.Parameters.Add(q);
//cmd.Parameters[0].OracleType = OracleType.NVarChar;
//cmd.Parameters[1].OracleType = OracleType.Number;
conn.Open();
var obj = cmd.ExecuteNonQuery();
conn.Close();
return (int)q.Value == 1;
}
It returns the following error.
ORA-06550 wrong number or types of arguments when calling Oracle stored procedure...
ANY IDEA?
I have had the same problem before. Are you using the ODP.Net drivers? I was able to solve the problem by adding the output parameter first. This needs to be done before the input parameters. In your case it would look like
using(var conn = new OracleConnection(Settings.Default.OraWUConnString))
{
conn.Open();
var cmd = conn.CreateCommand();
cmd.CommandText = "for_temporary_testing.select_card_transaction";
cmd.CommandType = CommandType.StoredProcedure;
// Return value parameter has to be added first !
var Quantity = new OracleParameter();
Quantity.Direction = ParameterDirection.ReturnValue;
Quantity.OracleDbType = OracleDbType.Int32;
cmd.Parameters.Add(Quantity);
//now add input parameters
var TransID = cmd.Parameters.Add("trans_id", TransactionID);
TransID.Direction = ParameterDirection.Input;
TransID.OracleDbType = OracleDbType.NVarchar2;
var UsrID = cmd.Parameters.Add("usr_id", UserID);
UsrID.Direction = ParameterDirection.Input;
UsrID.OracleDbType = OracleDbType.Int32;
cmd.ExecuteNonQuery();
conn.Close();
return Convert.ToInt32(Quantity.Value);
}
The problem was in the parameter. It was null and oracle returned error. I got that if argument is null, it should be sent as DBNULL
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;
--Stored procedure
ALTER PROCEDURE [dbo].[Test]
#USERID varchar(25)
AS
BEGIN
SET NOCOUNT ON
IF NOT EXISTS Select * from Users where USERID = #USERID)
BEGIN
INSERT INTO Users (USERID,HOURS) Values(#USERID, 0);
END
I have this stored procedure in sql server 2005 and want to pass userid from a C# application. How can I do that. Many Thanks.
This topic is extensively covered in MSDN here. See the section entitled "Using Parameters with a SqlCommand and a Stored Procedure" for a nice sample:
static void GetSalesByCategory(string connectionString,
string categoryName)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
// Create the command and set its properties.
SqlCommand command = new SqlCommand();
command.Connection = connection;
command.CommandText = "SalesByCategory";
command.CommandType = CommandType.StoredProcedure;
// Add the input parameter and set its properties.
SqlParameter parameter = new SqlParameter();
parameter.ParameterName = "#CategoryName";
parameter.SqlDbType = SqlDbType.NVarChar;
parameter.Direction = ParameterDirection.Input;
parameter.Value = categoryName;
// Add the parameter to the Parameters collection.
command.Parameters.Add(parameter);
// Open the connection and execute the reader.
connection.Open();
SqlDataReader reader = command.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
Console.WriteLine("{0}: {1:C}", reader[0], reader[1]);
}
}
else
{
Console.WriteLine("No rows found.");
}
reader.Close();
}
}