How to call an Oracle Procedure from C# - c#

From C# Code, I'm trying to call a PACKAGE.PROCEDURE() from Oracle. In this simple example I should get one value from the procedure call, but all I get is error:
wrong number or types of arguments in call to 'RETURN_NUM'
The procedure is declared as follows:
PROCEDURE return_num(xNum OUT NUMBER) AS
BEGIN
xNum:= 50;
dbms_output.put_line('hello world ' || xNum);
END;
C# code:
Oraclecon.Open();
OleDbCommand myCMD = new OleDbCommand("TEST.return_num", Oraclecon);
myCMD.CommandType = CommandType.StoredProcedure;
myCMD.Parameters.Add("xNum", OleDbType.Numeric);
OleDbDataReader myReader;
myReader = myCMD.ExecuteReader();
Can some one please point out what I'm doing wrong. Then in a real scenario I would like to call a procedure that returns a set of values from a custom Type, such as:
TYPE r_interface_data IS RECORD
(
object_id VARCHAR2(16),
obj_type VARCHAR2(32)
);
TYPE t_interfase_data IS TABLE OF r_interface_data;
How can I approach that. Thanks!
UPDATE: In my particular case I ended-up doing the following approach
using (OleDbCommand cmd = new OleDbCommand("PACKAGE.procedure_name"))
{
cmd.CommandType = CommandType.StoredProcedure;
SqlManager sqlManager = new SqlManager();
return sqlManager.GetDataSet(cmd);
}

I don't think you're that far off... try this:
OracleCommand cmd = new OracleCommand("return_num", Oraclecon);
cmd.Parameters.Add(new OracleParameter("xNum", OracleDbType.Decimal,
ParameterDirection.Output));
cmd.CommandType = CommandType.StoredProcedure;
cmd.ExecuteNonQuery();
OracleDecimal d = (OracleDecimal)cmd.Parameters[0].Value;
double result = d.ToDouble();
result now contains the out parameter from the procedure.
I think your problem is you were attempting to use a DbDataReader on a stored procedure. DbDataReader is for queries.
Also, I used ODP.net -- that may or may not have contributed to your issue, that you were using Ole.

Related

sending parameters to stored procedure error [duplicate]

I am fairly new to C# and I'm trying to set up call to a stored procedure in my database which takes one parameter.
I get the error "Procedure or function 'SP_getName' expects parameter '#username', which was not supplied. "
My Stored procedure works ok when I supply it with the parameter and I run it via SQL management studio.
GO
DECLARE #return_value int
EXEC #return_value = [dbo].[SP_getName]
#username = 'bob101'
SELECT 'Return Value' = #return_value
GO
However when I try and call it the error is with how I'm passing the parameter in, but I can't spot what the issue is.
//create a sql command object to hold the results of the query
SqlCommand cmd = new SqlCommand();
//and a reader to process the results
SqlDataReader reader;
//Instantiate return string
string returnValue = null;
//execute the stored procedure to return the results
cmd.CommandText = "SP_getName";
//set up the parameters for the stored procedure
cmd.Parameters.Add("#username", SqlDbType.NVarChar).Value = "bob101";
cmd.CommandType = CommandType.Text;
cmd.Connection = this.Connection;
// then call the reader to process the results
reader = cmd.ExecuteReader();
Any help in spotting my error would be greatly appreciated!
I've also tried looking at these two posts, but I haven't had any luck:
Stored procedure or function expects parameter which is not supplied
Procedure or function expects parameter, which was not supplied
Thanks!
You have stated:
cmd.CommandType = CommandType.Text;
Therefore you are simply executing:
SP_getName
Which works because it is the first statement in the batch, so you can call the procedure without EXECUTE, but you aren't actually including the parameter. Change it to
cmd.CommandType = CommandType.StoredProcedure;
Or you can change your CommandText to:
EXECUTE SP_getName #username;
As a side note you should Avoid using the prefix 'sp_' for your stored procedures
And a further side note would be to use using with IDisposable objects to ensure they are disposed of correctly:
using (var connection = new SqlConnection("ConnectionString"))
using (var cmd = new new SqlCommand("SP_getName", connection))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#username", SqlDbType.NVarChar).Value = "bob101";
connection.Open();
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
// Do something
}
}
}
I had this problem, but it wasn't about parameter name of Command Type.
My problem was that when C# calls SP, for each parameter that has no value passes 'default' keyword (i found it in SQL Profiler):
... #IsStop=0,#StopEndDate=default,#Satellite=0, ...
in my case my parameter Type was DateTime :
#StopEndDate datetime
. I Solved my problem by seting default value to this parameter in Stored Procedure :
#StopEndDate datetime=null
Try remove #:
cmd.Parameters.Add("username", SqlDbType.NVarChar).Value = "bob101";

Can't supply stored procedure parameter

OpenSqlConnection();
SqlCommand cmd = new SqlCommand("ReturnCharacterInfo", Con);
cmd.Parameters.AddWithValue("#CharacterID", CharacterID);
SqlDataReader dr = cmd.ExecuteReader();
When I run code you can see above, it throws exception
Procedure or function 'ReturnCharacterInfo' expects parameter '#CharacterID', which was not supplied.
but as you can see at the code, I'm suppying #CharacterID parameter and it's not empty or null.
Stored procedure:
[ReturnCharacterInfo] #CharacterID int
as
select
CharacterName, characterSurname, CharacterIsMale, CharacterAge,
CharacterMood, CharacterHealth, CharacterInCity, CharacterInLocation,
Cities.CityName, Locales.LocaleTitle
from
Characters
INNER JOIN
Cities on Cities.CityID = Characters.CharacterInCity
INNER JOIN
Locales on Locales.LocaleID = Characters.CharacterInLocation
Where
CharacterID = #CharacterID
Any suggestions?
I would try to explicitly specifying the type of the parameter - especially important if the value is null:
SqlCommand cmd = new SqlCommand("ReturnCharacterInfo", Con);
// added as per CodeNaked's comment - thanks! You've nailed it right on the head!
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#CharacterID", SqlDbType.Int).Value = CharacterID;
Also: do you have a typo anywhere?? Triple-check all occurrences of CharacterID - do you happen to have CharachterID or something like that somewhere in your code??
As CodeNaked pointed out, you need to set the command type of the SqlCommand. The SqlCommand object needs to be told it's a stored procedure because of the way that stored procedures are executed.
OpenSqlConnection();
SqlCommand cmd = new SqlCommand("ReturnCharacterInfo", Con);
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#CharacterID", CharacterID);
SqlDataReader dr = cmd.ExecuteReader();

expects parameter '#ID', which was not supplied?

I am sending ID as outparameter but its giving error
System.Data.SqlClient.SqlException: Procedure or function
'usp_ClientHistoryItem' expects parameter '#ID', which was not
supplied.
Code
using (SqlCommand cmd = new SqlCommand("dbo.usp_ClientHistoryItem", conn))
{
SqlParameter parameterID = new SqlParameter("#ID", oReservation.Id);
parameterID.Direction = ParameterDirection.Output;
cmd.Parameters.Add(parameterID);
cmd.Parameters.Add(new SqlParameter("#PhoneNo", oReservation.ClientPhone));
cmd.Parameters.Add(new SqlParameter("#UserId", oReservation.UserID));
cmd.Parameters.Add(new SqlParameter("#Description", oReservation.Description));
cmd.Parameters.Add(new SqlParameter("#TestId", oReservation.TestId));
cmd.Parameters.Add(new SqlParameter("#StartDate", oReservation.StartDate));
cmd.ExecuteNonQuery();
returnValue = Convert.ToInt32(cmd.Parameters["#ID"].Value);
return returnValue;
}
You seem to be calling a stored procedure - yet you've never defined your SqlCommand to be a stored procedure:
using (SqlCommand cmd = new SqlCommand("dbo.usp_ClientHistoryItem", conn))
{
cmd.CommandType = CommandType.StoredProcedure; // add this line to tell ADO.NET it's a stored procedure!!
If you forget that line, then ADO.NET will try to interpret your stuff as an ad-hoc SQL statement....
this one solve my problem
may be it may helpful
cmd.CommandType = CommandType.StoredProcedure;
Your ID parameter in the stored procedure must be set as OUTPUT parameter. You are just setting it in code not in stored procedure.
Hy guys.
You have to set the property CommandType for the Command to StoredProcedure if that's the case. Otherwise it woun't detect the parameters.
One other reason this error is thrown is when the variable names don't match in your stored procedure and code because the code fails to find the parameter to which the value must be passed. Make sure they match:
Stored procedure:
create procedure getEmployee
#ID
as
Begin
select *
from emp
where id = #ID
End
Code:
SqlParameter p = new SqlParameter("#ID", id);
cmd.Parameter.Add(p);
The parameter #ID must match in both code and stored procedure
If you use dapper, you can use this construction
int id = 1;
var parameters = new DynamicParameters();
parameters.Add("#id", id, DbType.Int32, ParameterDirection.Input);
string sqlQuery = "[dbo].[SomeStoredProcedure]";
using (IDbConnection db = new SqlConnection(ConnectionString))
{
var result = await db.QueryAsync<SpResult>(sqlQuery, parameters, commandType: CommandType.StoredProcedure);
}

ASP.NET and Oracle Stored Procedure Error

I am VERY new when it comes to stored procedures and .NET, so I apologize in advance. I have a stored procedure that I am trying to use and I keep getting this error..."wrong number or types of arguments in call to 'COPY_ACCOUNT'". I am not sure why. Below is my stored procedure code followed by my C#.NET code. Any help is GREATLY appreciated. PLEASE.
create or replace procedure abstract_names.copy_account(r_rows_copied out int,
ar_old_acct in abn_headings.acct_no%type,
ar_new_acct in abn_headings.acct_no%type)
is
cnt int := 0;
begin
r_rows_copied := 0;
for r in (select heading from abn_headings where acct_no = ar_old_acct) loop
copy_heading(cnt, ar_old_acct, r.heading, ar_new_acct);
r_rows_copied := r_rows_copied + cnt;
end loop;
dbms_output.put_line('called abstract_names.copy_account '||to_char(r_rows_copied));
return; end;
Then my C#.NET code...
using System.Data.OracleClient;
try
{
conn.Open();
OracleCommand cmd = new OracleCommand();
cmd.Parameters.Add("r_rows_copied", OracleType.Int32).Direction = ParameterDirection.Output;
cmd.Parameters.Add("ar_from_acct", OracleType.VarChar).Value = accountNumberDropDownList.SelectedValue.ToString();
cmd.Parameters.Add("ar_to_acct", OracleType.VarChar).Value = copyAccountDDL.SelectedValue.ToString();
cmd = new OracleCommand("abstract_names.copy_account", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.ExecuteNonQuery();
conn.Close();
/*
abstract_names.copy_account(r_rows_copied out int,
ar_from_acct in abn_headings.acct_no%type,
ar_to_acct in abn_headings.acct_no%type)
*/
}
finally
{
if (conn != null)
conn.Close();
}
My connection string is correct because I use it else where in my code and it works. The commented section is the stored procedure i am trying to use obviously. Please help me!
Just looking at your code and not being familiar with this OracleCommand object, it looks like you're creating parameters and then creating a new object in the middle wiping out all your parameter additions. Create a new object from the connection and then add your parameters. Attempting a stab at better code below. Also I would use using statements for any conneciton,commnand objects to ensure they get closed and disposed.
Edit: Didn't look too deep, my fault. It looks like the parameter names weren't matching up in the stored procedure and the .net code. Also since you're returning a value, I would use the ExecuteScalar method, ExeuteNonQuery won't return any data.
cmd = new OracleCommand("abstract_names.copy_account", conn);
cmd.Parameters.Add("r_rows_copied", OracleType.Int32).Direction = ParameterDirection.Output;
cmd.Parameters.Add("ar_old_acct ", OracleType.VarChar).Value = accountNumberDropDownList.SelectedValue.ToString();
cmd.Parameters.Add("ar_new_acct", OracleType.VarChar).Value = copyAccountDDL.SelectedValue.ToString();
cmd.CommandType = CommandType.StoredProcedure;
object value = cmd.ExecuteScalar();
conn.Close();
You assign a new instance to your cmd variable, then you lose reference to what you had done.
Here:
cmd.Parameters.Add("ar_to_acct", OracleType.VarChar).Value = copyAccountDDL.SelectedValue.ToString();
cmd = new OracleCommand("abstract_names.copy_account", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.ExecuteNonQuery();
conn.Close();
This is the wrong line:
cmd = new OracleCommand("abstract_names.copy_account", conn);
Just by looking at your code, I think you should simply remove that line and it should be OK.

Run stored procedure in C#, pass parameters and capture the output result

This is a simple task that I want to acheive but ASP.NET makes it quite difficult, next to impossible. I followed this question
Running a Stored Procedure in C# Button but found out ExecuteNonQuery does not return the output from query.
I tried this other approach but can't seem to pass the paremeters in this way
SqlConnection myConnection = new SqlConnection(myconnectionString);
SqlCommand myCommand = new SqlCommand();
myCommand.CommandType = CommandType.StoredProcedure;
myCommand.CommandText = "usp_GetCustomer";
myCommand.SelectParameter <-- does not exist
Can someone write this simple code, how can I implement it? Basically I am passing a #username and #month (both character strings) to stored procedure and it returns a number that I want to capture and assign to a label control.
Thank you
The output from my query is this. It runs a complex query, create a temp table and then it runs
select ##rowcount
and I am capturing that.
Don't use SqlCommand.ExecuteNonQuery() if you actually want data from a result set.
Make sure your procedure uses set nocount on
Then use SqlCommand.ExecuteScalar()
return (int)myCommand.ExecuteScalar(); // value of select ##rowcount
Edit: As for your parameters:
myCommand.Parameters.AddWithValue("#username","jsmith");
myCommand.Parameters.AddWithValue("#month","January");
I prefer using linq-to-sql to handle stored procedures. Create a linq-to-sql model, where you add the SP you want to call. This will expose the SP as a function on the generated data context, where the parameters are ordinary C# functions. The returned values will be exposed as a collection of C# objects.
If you have multiple results from the SP things get a bit more complicated, but still quite straight forward.
Use the Parameters collection of the command to set the parameters, and the ExecuteScalar to run the query and get the value from the single-row single-column result.
Use using blocks to make sure that the connection and command are closed and disposed properly in any situation. Note that you have to provide the connection to the command object:
int result;
using (SqlConnection connection = new SqlConnection(myconnectionString)) {
using (SqlCommand command = new SqlCommand(connection)) {
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "usp_GetCustomer";
command.Parameters.Add("#username", SqlDbType.VarChar).Value = username;
command.Parameters.Add("#month", SqlDbType.VarChar).Value = month;
connection.Open();
result = (int)myCommand.ExecuteScalar();
}
}
using(SqlConnection myConnection = new SqlConnection(myconnectionString))
{
SqlCommand myCommand = new SqlCommand();
myCommand.CommandType = CommandType.StoredProcedure;
myCommand.CommandText = "usp_GetCustomer";
myCommand.Parameters.Add("#USER_NAME", SqlDbType.VarChar).Value = sUserName; // user name that you pass to stored procedure
myCommand.Parameters.Add("#Month", SqlDbType.VarChar).Value = iMonth; // Month that you pass to stored procedure
// to get return value from stored procedure
myCommand.Parameters.Add("#ReturnValue", SqlDbType.Int).Direction = ParameterDirection.ReturnValue;
myConnection .Open();
myCommand.ExecuteScalar();
// Returnvalue from stored procedure
return Convert.ToInt32(command.Parameters["#ReturnValue"].Value);
}
Simple code to get return value from SQL Server
SqlConnection myConnection = new SqlConnection(myconnectionString);
SqlCommand myCommand = new SqlCommand();
myCommand.CommandType = CommandType.StoredProcedure;
myCommand.CommandText = "usp_GetCustomer";
myCommand.Parameters.Add("#USER_NAME", SqlDbType.VarChar).Value = sUserName; // user name that you pass to the stored procedure
myCommand.Parameters.Add("#Month", SqlDbType.VarChar).Value = iMonth; //Month that you pass to the stored procedure
// to get return value from the stored procedure
myCommand.Parameters.Add("#ReturnValue", SqlDbType.Int).Direction = ParameterDirection.ReturnValue;
myConnection .Open();
myCommand.ExecuteScalar();
// Returnvalue from the stored procedure
int iReturnValue = Convert.ToInt32(command.Parameters["#ReturnValue"].Value);

Categories

Resources