Cannot retrieve out parameters from oracle stored procedure using OracleManagedDataAccess - oracle

I m writing my issue here after lot of struggle and trying all the available options online.
Here is my issue. I am using ODP.Net, oracleManagedDataAccess library to connect to the oracle database.I have a stored procedure with in and out parameters which works fine when I test it from pl/sql but when I am trying to execute it from my .net code and retrieve the out parameters they return null and if I see the status of each out parameter, its false and value is "Null Fetched" and also the size of the parameter is showing up as 0, though I set the size of the parameter to 4000 for a string type. Please see my code below. Please help. As I told you earlier, my stored proc works just fine from pl/sql.
connection = new OracleConnection(DBHelper.ConnectionString);
connection.Open();
command = new OracleCommand();
command.Connection = connection;
command.CommandType = System.Data.CommandType.StoredProcedure;
command.CommandText = DBConstants.PROC_GETBORROWERSEQNO;
//Input
command.Parameters.Add("password", OracleDbType.Varchar2, 4000, password, ParameterDirection.Input);
command.Parameters.Add("userid", OracleDbType.Varchar2, 4000, userID, ParameterDirection.Input);
command.Parameters.Add("ipaddress", OracleDbType.Varchar2,4000, iPAddress, ParameterDirection.Input);
//Output
command.Parameters.Add("shawcustno", OracleDbType.Decimal).Direction = ParameterDirection.Output;
command.Parameters.Add("emailid", OracleDbType.Varchar2,4000).Direction = ParameterDirection.Output;
command.Parameters.Add("contr_phase", OracleDbType.Varchar2, 4000).Direction = ParameterDirection.Output;
command.Parameters.Add("source_seqno", OracleDbType.Decimal,15).Direction = ParameterDirection.Output;
command.Parameters.Add("borrower_seqno", OracleDbType.Decimal,15).Direction = ParameterDirection.Output;
command.Parameters.Add("pag_phone", OracleDbType.Varchar2, 4000).Direction = ParameterDirection.Output;
command.Parameters.Add("pag", OracleDbType.Varchar2, 4000).Direction = ParameterDirection.Output;
//InputOutput
command.Parameters.Add("sessionseqno", OracleDbType.Decimal).Direction = ParameterDirection.InputOutput;
sequenceNumber = command.ExecuteNonQuery();
customer = new Customer();
customer.Company = command.Parameters["company"].Value.ToString();
customer.Pag = command.Parameters["pag"].GetString();
customer.PagPhone = command.Parameters["pag_phone"].GetString();
customer.BorrowerSeqNo = command.Parameters["borrower_seqno"].IsDBNull() ? 0 : command.Parameters["borrower_seqno"].GetInt32();
customer.SourceSeqNo = command.Parameters["source_seqno"].IsDBNull() ? 0 : command.Parameters["source_seqno"].GetInt32();
customer.EmailID = command.Parameters["emailid"].GetString();
customer.ShawCustNo = command.Parameters["shawcustno"].GetString();
customer.SessionSeqNo = command.Parameters["sessionseqno"].IsDBNull() ? 0 : command.Parameters["sessionseqno"].GetInt32();
}

finally found the answer, the order of the arguments has to be exactly the same as that declared in the stored procedure. I missed that order.

Related

.net core call oracle function put returned value in first parameter

.net core 3.1
nuget: Oracle.ManagedDataAccess.Core 2.19.91
Oracle function:
create or replace NONEDITIONABLE FUNCTION GET_TOTAL_SALES
(
PARAM1 IN VARCHAR2,
PARAM2 IN VARCHAR2
)
RETURN VARCHAR2 AS
BEGIN
RETURN 'abc';
END GET_TOTAL_SALES;
.net core code:
var cmdText = "GET_TOTAL_SALES";
using (var connection = new OracleConnection(connStr))
{
using (var command = new OracleCommand(cmdText, connection))
{
connection.Open();
command.CommandType = CommandType.StoredProcedure;
var param1 = new OracleParameter("PARAM1", OracleDbType.Varchar2);
param1.Direction = ParameterDirection.Input;
param1.Value = "param1Value";
command.Parameters.Add(param1);
var param2 = new OracleParameter("PARAM2", OracleDbType.Varchar2);
param2.Direction = ParameterDirection.Input;
param2.Value = "param2Value";
command.Parameters.Add(param2);
var returnValue = new OracleParameter("returnValue", OracleDbType.Varchar2);
returnValue.Direction = ParameterDirection.ReturnValue;
command.Parameters.Add(returnValue);
command.ExecuteNonQuery();
Console.WriteLine(returnValue.Value); //""
Console.WriteLine(param1.Value); //"abc"
}
}
The result is that the returned value is putted into the first parameter (param1) and not into the returnValue. Why? Help!
I asked Oracle and got a reply:
"This is expected behavior. The first parameter bound for a function must be the return value. From the doc:
https://docs.oracle.com/en/database/oracle/oracle-data-access-components/19.3.2/odpnt/featOraCommand.html
I know, it is crazy.
We can also use binding by name:
command.BindByName = true;
and then order doesn't matter.

C# Core, OracleDataReader with hasRows as false while select all rows in a table that has data

I am testing Oracle database. I wrote some code but my datareader has no rows, why? My "carros" table has data and I am selecting all of them but I am getting an empty result set it seems.
string constr = "Data Source=localhost:1521/XE;User Id=System;Password=password;";
OracleConnection con = new OracleConnection(constr);
OracleCommand oracleCommand = new OracleCommand();
oracleCommand.Connection = con;
oracleCommand.CommandText = "select preco from carro";
con.Open();
OracleDataReader oracleDataReader = oracleCommand.ExecuteReader();
string resultado = String.Empty;
//My test, I got hasRows as false
if (oracleDataReader.HasRows == false)
{
resultado = "no results";
}
//never enters this loop.
while (oracleDataReader.Read())
{
resultado += (string)oracleDataReader["preco"];
}
// Close and Dispose OracleConnection
con.Close();
con.Dispose();
return resultado;
If HasRows is false after ExecuteReader, the problem is simply that the query is returning no rows so Read will return false as well. Perhaps the someValue variable is not set correctly.
From you description, it seems that your table is named carros while your query has used carro. Try to use
oracleCommand.CommandText = "select preco from carros";
A path towards solving this can include a scattering of logging commands that write to the file system.
System.IO.File.AppendAllText(#"\\server\\C\\log.txt", "put error message here" + "\r\n");
Or for printing a variable:
System.IO.File.AppendAllText(#"\\server\\C\\log.txt", ex.ToString() + "\r\n");
Pepper variations of this command throughout your script to see where failures are happening and to validate variable values.

calling oracle stored procedure in c#

I am trying to call a oracle stored procedure in c# like this
OdbcDataAdapter da = new OdbcDataAdapter();
da.SelectCommand = new OdbcCommand();
da.SelectCommand.Connection = con;
da.SelectCommand.Connection.Open();
da.SelectCommand.CommandText = "KAMRAN.ATTN";
da.SelectCommand.CommandType = CommandType.StoredProcedure;
da.SelectCommand.ExecuteNonQuery();
da.SelectCommand.Connection.Close();
Label3.Text = "Attendance Posted Successfully";
But I am showing this error
ERROR [42000] [Oracle][ODBC][Ora]ORA-00900: invalid SQL statement
Please any One Can tell what exactly i am missing to call this procedure.plz help !
You could try to inverse the statements:
da.SelectCommand.CommandType = CommandType.StoredProcedure;
da.SelectCommand.CommandText = "KAMRAN.ATTN";
Also, maybe try to add:
da.SelectCommand.Parameters.Clear();
before
da.SelectCommand.CommandType = CommandType.StoredProcedure;
da.SelectCommand.CommandText = "KAMRAN.ATTN";
I think that you should also use a DataTable
DataTable dt = new DataTable();
da.Fill(dt);
return dt;
Maybe that it should also be an Oracle Data Adapter:
OracleDataAdapter da = new OracleDataAdapter();
da.SelectCommand = new OracleCommand();
So you should have:
OracleDataAdapter da = new OracleDataAdapter();
da.SelectCommand = new OracleCommand();
da.SelectCommand.Connection = con;
da.SelectCommand.Connection.Open();
da.SelectCommand.Parameters.Clear();
da.SelectCommand.CommandType = CommandType.StoredProcedure;
da.SelectCommand.CommandText = "KAMRAN.ATTN";
DataTable dt = new DataTable();
da.Fill(dt);
return dt;
da.SelectCommand.Connection.Close();
I hope this helps in any way.

DbContext stored procedures oracle 11g

I am attempting to execute a stored procedure that has several in/out parameters. This is what the expected way of doing this with SQLServer would be.
using (Context)
{
const string xml = "<test><testc>testing</testc></test>";
var userIdParam = new SqlParameter { ParameterName = "I_USER_ID", Value = user.ID };
var dtsParam = new SqlParameter { ParameterName = "I_DTS", Value = DateTime.Now };
var timeoutParam = new SqlParameter { ParameterName = "I_TIMEOUT", Value = DateTime.Now };
var xmlParam = new SqlParameter { ParameterName = "I_XML", Value = xml };
var sessionIdParam = new SqlParameter { ParameterName = "O_SESSION_ID", Value = "", Direction = ParameterDirection.Output };
var result =
Context.Database.SqlQuery<string>(
"DALLEN.SP_INSERT_SESSION I_USER_ID, I_DTS, I_TIMEOUT, I_XML, O_SESSION_ID out",
userIdParam,
dtsParam,
timeoutParam,
xmlParam,
sessionIdParam);
}
Unfortunately this does not work with oracle. I understand that ref cursors might be used in place of out parameters but that is not my own issue. Is there a good way of passing parameters to the stored procedure using dbcontext.database.sqlquery?
EDIT
Error message received when the query attempts to execute. It explains that it doesn't accept sqlParamters so I changed them to OracleParamters and that didn't work either.
"Unable to cast object of type 'System.Data.SqlClient.SqlParameter' to type 'Oracle.DataAccess.Client.OracleParameter'."
Procedure:
CREATE OR REPLACE PROCEDURE DALLEN.SP_INSERT_SESSION (
I_USER_ID IN NUMBER,
I_DTS IN DATE,
I_TIMEOUT IN DATE,
I_XML IN VARCHAR2,
O_SESSION_ID OUT NUMBER
)
AS
BEGIN
SELECT S_SESSION.NEXTVAL
INTO O_SESSION_ID
FROM DUAL;
INSERT INTO DALLEN.SYS_SESSION
(ID, USER_ID, DTS, TIMEOUT, XML)
VALUES (O_SESSION_ID, I_USER_ID, I_DTS, I_TIMEOUT, I_XML);
END;
Thank you in advance!

How do I call an Oracle function to insert data using ODP.NET and a dataset? (specific example)

We're really lost on this one, having read the ODP.NET 2 Day+ developer guide hasn't helped. I've provided the function definition (stored in a package), I don't understand what we have to cast the dataset to or what to pass the function. Here is the function definition:
FUNCTION ins (
rec_data IN OUT schema.table%ROWTYPE,
p_rowid OUT ROWID,
p_execution_ts IN schema.table.update_ts%TYPE)
RETURN NUMBER
Here is what we have done (which does nothing):
// inserts data
public void insertData(DataSet Data)
{
string connStr = "DATA SOURCE=someValidConnString";
OracleConnection conn = new OracleConnection(connStr);
string rowID = String.Empty;
Int32 rtnVal = 0;
try
{
conn.Open();
OracleCommand insCmd = new OracleCommand("PACKAGE.ins", conn);
insCmd.CommandType = CommandType.StoredProcedure;
OracleParameter outParam2 = new OracleParameter("retVal", OracleDbType.Varchar2, rtnVal,
ParameterDirection.ReturnValue);
insCmd.Parameters.Add(outParam2); //return value
OracleParameter inParam1 = new OracleParameter("rec_data", OracleDbType.NVarchar2, dsACCTData.Tables
[0].Rows[0], ParameterDirection.InputOutput);
OracleParameter outParam = new OracleParameter("p_rowid", OracleDbType.Varchar2, rowID,
ParameterDirection.Output);
OracleParameter inParam2 = new OracleParameter("p_execution_ts", OracleDbType.Date,
Oracle.DataAccess.Types.OracleDate.GetSysDate(), ParameterDirection.Input);
insCmd.Parameters.Add(inParam1); //first in out parameter
insCmd.Parameters.Add(outParam); //second out parameter
insCmd.Parameters.Add(inParam2); //third in parameter
insCmd.ExecuteNonQuery();
conn.Close();
}
catch (OracleException ee)
{
throw ee;
}
finally
{
conn.Dispose();
}
}
I know this is a vry specific question but I'm really lost. Let's assume the Oracle function ins works (it does), in this instance we simply don't know how to call it correctly using ODP.NET
Many thanks for any help.
edit: here is the error message:
ORA-06550: line 1, column 15:
PLS-00306: wrong number or types of arguments in call to 'INS'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
Kind regards,
Fugu
maybe this could help:
http://www.c-sharpcorner.com/UploadFile/john_charles/CallingOraclestoredproceduresfromMicrosoftdotNET06222007142805PM/CallingOraclestoredproceduresfromMicrosoftdotNET.aspx
I'm looking for the same answer and I think I found something. There is example of the output variable in second row.
objCmd.Parameters.Add("pin_deptno", OracleType.Number).Value = 20;
objCmd.Parameters.Add("pout_count", OracleType.Number).Direction = ParameterDirection.Output;
Hope that link will do any good.
Regards, M
Every thing looks good. But you have to check all attribute name and attribute types.
In your example have bad data type OracleDbType.Varchar2, because your function return Number (in your Oracle Function definition)
OracleParameter outParam2 = new OracleParameter("retVal", OracleDbType.Varchar2, rtnVal,
ParameterDirection.ReturnValue);
insCmd.Parameters.Add(outParam2); //return value

Resources