Calling an Oracle stored procedure in Dapper - oracle

I have an application that was calling an Oracle stored procedure by passing a string with the parameters in the string, i.e.
string Query = "CALL MySP(" + Variable1 + ", " + Variable2 + ")";
This worked, or at least the last time I tried it it worked.
I need to rewrite the query using DynamicParameters.
However when I do an Execute(Query, Parms, commandType: CommandType.StoredProcedure), I get errors.
Here is an example of what I tried:
using(OracleConnection conn = new OracleConnection(myConnectionString)
{
string Query = "CALL MySP(:Var1, :Var2)";
DynamicParameters parms = new DynamicParameters();
parms.Add("Var1", Variable1, DbType.String, ParameterDirection.Input);
parms.Add("Var2", Variable2, DbType.String, ParameterDirection.Input);
var results = connection.Execute(Query, parms, commandType: CommandType.StoredProcedure);
}
When I run it with the above query, I get this error:
ORA-06550: line 1, column 12:
PLS-00103: Encountered the symbol "MySP" when expecting one of the following:
:= . ( # % ;
The symbol ":=" was substituted for "MySP" to continue.
If I remove the CALL statement:
Query = "MySP(:Var1, :Var2);
then I get this error message:
ORA-01008: not all variables bound
Can anyone see what I am doing wrong?

The problem is that I keep looking on the C# and Dapper side of the equation. Our Oracle DBA set the permissions on the Stored Procedure and it ran.
However I could not tell Dapper that the CommandType was Stored Procedure and my string to call the stored procedure had to look like:
string Query = "CALL MySP(:Var1, :Var2)";
If I removed "CALL" I got an error. If I added "commandType: CommandType.StoredProcedure" to the Dapper Execute function I got a binding error.
Our DBA said he was going to look more into it to see what he can find out on his end so that we can call the stored procedure using the CommandType.StoreProcedure parameter in the Execute function.

Related

dapper and running stored procedure ctx_ddl.sync_index

I need to execute the stored procedure ctx_ddl.sync_index on an Oracle database. In a query program this works;
EXECUTE ctx_ddl.sync_index('MyIndex');
When I try to run in dapper with the following;
using var connect = new OracleConnection(conString);
var results = connect.Execute("ctx_ddl.sync_index", "MyIndex", commandType: CommandType.StoredProcedure);
It gives me the following error:
ORA-06550: line 1, column 7: PLS-00306: wrong number or types of
arguments in call to 'SYNC_INDEX'
What am I doing wrong?
Instead of passing "MyIndex" as a string, try this:
using var connect = new OracleConnection(conString);
var p = new OracleDynamicParameters();
p.Add("THENAMEOFYOURPARAMETER", dbType: OracleDbType.THETYPEOFYOURPARAMETER, direction: ParameterDirection.Input);
var results = connect.Execute("ctx_ddl.sync_index", param:p, commandType: CommandType.StoredProcedure);

DB2 returning keys in insert not working

I'm having a problem while returning generated keys when insert a row with jdbc in a DB2 database (version 10.1). I tried several ways to do it, but no one works fine.
Method 1:
stmt = con.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);
When executing this line, I get this exception:
com.ibm.db2.jcc.am.SqlSyntaxErrorException: ILLEGAL SYMBOL "". SOME SYMBOLS THAT MIGHT BE LEGAL ARE:. SQLCODE=-104, SQLSTATE=42601, DRIVER=3.61.75
Method 2:
stmt = con.prepareStatement(query, pkMapper.getPkFieldNames());
List<Object> params = getInsertParams(object, pkMapper);
for (int i = 0; i < params.size(); i++) {
Object param = params.get(i);
stmt.setObject(i+1, param);
}
pkMapper.getPkFieldNames() returns an array of string with PK column names. When executing stmt.setObject(i+1, param); I get an exception like this:
com.ibm.db2.jcc.am.SqlSyntaxErrorException: ILLEGAL SYMBOL "". SOME SYMBOLS THAT MIGHT BE LEGAL ARE:. SQLCODE=-104, SQLSTATE=42601, DRIVER=3.61.75
Method 3:
stmt = con.prepareStatement(query);
With this form, insert is executed fine, but no keys are returned with stmt.getGeneratedKeys();
Has anyone any idea of what is happening?

Debugging runtime pl/sql errors

I’m new in pl/sq.
So, I’m trying to call pl/sql stored procedure from Java, but appears error:
wrong number or types of arguments in call to ‘searchuser’.
Where can I find most specific exception?
Is there some error logs or errors table in oracle? How can I debug these kind of problems?
Thanks!
one thing is if you call stored procedures from java: don't forget to register the function result. Example Java code:
CallableStatement cstmt = connection.prepareCall("{? = call xxx.checkArea(?,?)}");
// the 1st Parameter is the result of the function checkArea
cstmt.registerOutParameter(1, Types.INTEGER); // Function Return
cstmt.setInt(2, status); // Parameter 1 (in)
cstmt.registerOutParameter(3, Types.INTEGER); // Parameter 2 (out)
// execute the call
cstmt.execute();
// check the results
sessionId = cstmt.getInt(1); // Session-ID
rows = cstmt.getInt(3); // Rows
The PL/SQL Function is declared as following:
function checkArea(pi_area in number,
po_rows out number) return number;

How to call an Oracle function with a Ref Cursor as Out-parameter from C#?

I'm using a product that provides a database API based on Oracle functions and I'm able to call functions via ODP.NET in general. However, I can't figure out, how to call a function that includes a Ref Cursor as Out-parameter. All the samples I found so far either call a procedure with Out-parameter or a function with the Ref Cursor as return value. I tried to define the parameters similiarly, but keep getting the error that the wrong number or type of parameters is supplied.
Here is the function header (obviously obfuscated):
FUNCTION GetXYZ(
uniqueId IN somepackage.Number_Type,
resultItems OUT somepackage.Ref_Type)
RETURN somepackage.Error_Type;
These are the type definitions in "somepackage":
SUBTYPE Number_Type IS NUMBER(13);
TYPE Ref_Type IS REF CURSOR;
SUBTYPE Error_Type IS NUMBER;
And this is the code that I have tried:
string sql = "otherpackage.GetXYZ";
var getXYZCmd = OracleCommand oracleConnection.CreateCommand(sql);
getXYZCmd.CommandType = CommandType.StoredProcedure;
getXYZCmd.Parameters.Add("uniqueId", OracleDbType.Int32).Value = uniqueExplosionId;
getXYZCmd.Parameters.Add("resultItems", OracleDbType.RefCursor).Direction = ParameterDirection.Output;
getXYZCmd.Parameters.Add("return_value", OracleDbType.Int32).Direction = ParameterDirection.ReturnValue;
The I tried the following different ways to call the function (of course only one at a time):
var result = getXYZCmd.ExecuteNonQuery();
var reader = getXYZCmd.ExecuteReader();
var scalarResult = getXYZCmd.ExecuteScalar();
But each of them fails with the error message:
Oracle.DataAccess.Client.OracleException: ORA-06550: line 1, column 15:
PLS-00306: wrong number or types of arguments in call to 'GETXYZ'
ORA-06550: line 1, column 15:
PLS-00306: wrong number or types of arguments in call to 'GETXYZ'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored.
So is it generally possible to call a function with a Ref Cursor as Out-parameter from C# with ODP.NET? I can call a function with the same structure with a Varchar2-Out-parameter instead of the Ref Cursor without problems...
Btw, I'm using ODP.NET version 2.112.2.0 from C#.NET 3.5 in Visual Studio 2008.
Thanks in advance for your help!
You sure can. There are a few gotchas to be wary of but here is a test case
create or replace function testodpRefCursor(
uniqueId IN NUMBER
,resultItems OUT NOCOPY SYS_REFCURSOR) RETURN NUMBER
IS
BEGIN
OPEN resultItems for select level from dual connect by level < uniqueId ;
return 1;
END testodpRefCursor;
I have found that
functions likes to have the
ReturnValue as THE FIRST param
in the collection
BindByName is by default FALSE, so it defaults to BIND BY POSITION
Otherwise it is quite straight forward:
OracleCommand cmd = new OracleCommand("TESTODPREFCURSOR", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.BindByName = true;
// Bind
OracleParameter oparam = cmd.Parameters.Add("ReturnValue", OracleDbType.Int64);
oparam.Direction = ParameterDirection.ReturnValue ;
OracleParameter oparam0 = cmd.Parameters.Add("uniqueId", OracleDbType.Int64);
oparam0.Value = 5 ;
oparam0.Direction = ParameterDirection.Input;
OracleParameter oparam1 = cmd.Parameters.Add("resultItems", OracleDbType.RefCursor);
oparam1.Direction = ParameterDirection.Output;
// Execute command
OracleDataReader reader;
try
{
reader = cmd.ExecuteReader();
while(reader.Read() ){
Console.WriteLine("level: {0}", reader.GetDecimal(0));
}
} ...
Now for more samples go to your Oracle Home directory and look # the Ref cursor samples in ODP.NET
for instance:
%oracle client home%\odp.net\samples\4\RefCursor
hth

what are the OleDbTypes associated with Oracle Number and varchar2 when calling a function

I'm trying to map OleDb parameters to an Oracle Function. I was able to do this using the System.Data.Oracle namespace but then found that this is depricated, so I thought i would re-write it as OldDb to avoid installing the Oracle Provider.
I have defined the following oracle function as an example:
create function GetImagePath (AIRSNumber in number)
return varchar2
is
begin
return '\\aiimg524\images\Ofndrtrk\2010\01\0kvrv1p000lcs74j';
end;
and I'm calling it using the following code:
using (var command = new OleDbCommand())
{
command.Connection = con;
command.CommandText = ConfigurationManager.AppSettings[OTRAK_PHOTO_FUNC];
command.CommandType = CommandType.StoredProcedure;
string parm = ConfigurationManager.AppSettings[OTRAK_PHOTO_PARM];
command.Parameters.Add(parm, OleDbType.Decimal); // maps to oracle Number
command.Parameters[parm].Direction = ParameterDirection.Input;
command.Parameters[parm].Value = airsNumber;
command.Parameters.Add(RETURN_VALUE, OleDbType.Variant); // maps to Oracle varchar2
command.Parameters[RETURN_VALUE].Direction = ParameterDirection.ReturnValue;
try
{
con.Open();
command.ExecuteNonQuery();
path = command.Parameters[RETURN_VALUE].Value.ToString();
}
I tried a bunch of different OleDB types for the parameter and the return value. the current attempt is from a mapping table i found on the web that said number = decimal and varchar2 = variant. I'm about to try every permutation of types in the enum and wanted to ask for help. the not so useful error message i get is:
[System.Data.OleDb.OleDbException] = {"ORA-06550: line 1, column 7:\nPLS-00306: wrong number or types of arguments in call to 'GETIMAGEPATH'\nORA-06550: line 1, column 7:\nPL/SQL: Statement ignored"}
This actually had nothing to do with the type of the parameters but the order. Using the OleDb provider for Oracle does not respect the names of the parameters in the parameter collection but rather the order that the parameters are added. Wwhen calling an oracle function, the return value is a free parameter that must be declared first. by adding my return value parameter and then the actual function parameter things started working.
using the command.Parameters.AddWithValue(parm, value) also simplifies things a bit.

Resources