Petapoco - Getting return from Oracle function

Eddie Shipman
Eddie Shipman used Ask the Experts™
on
I'm running into the same problem as outlined in this post:  
http://stackoverflow.com/questions/35113140/executing-oracle-function-and-getting-back-a-return-value 

I can do this in my Toad client successfully:
declare result varchar2(30);
BEGIN 
  result:=WEBUSER.F_UpdateParticipant(json input_goes here);
  dbms_output.put_line(result); 
END;

Open in new window

and get the return value shown in dbms_output.
This function returns:
{"Success":true} 

or 

{"Success":false} 

Open in new window

But I cannot get the output returned to Petapoco. I've also tried using output params like this:
var result = new Oracle.ManagedDataAccess.Client.OracleParameter("result",Oracle.ManagedDataAccess.Client.OracleDbType.Varchar2, System.Data.ParameterDirection.Output);
var sql = "DECLARE result VARCHAR2(30);" + 
          "BEGIN "+
          "    @0:=WEBUSER.F_UpdateParticipant(@1);" +
          "END;";
_db.db.Execute(sql, result, json);
res = result.ToString();

Open in new window

AND
var result = new Oracle.ManagedDataAccess.Client.OracleParameter("result",Oracle.ManagedDataAccess.Client.OracleDbType.Varchar2, System.Data.ParameterDirection.Output);
var sql = "DECLARE result VARCHAR2(30);" + 
          "BEGIN "+
          "    @result:=WEBUSER.F_UpdateParticipant(@1);" +
          "END;";
_db.db.Execute(sql, result, json);
res = result.ToString();

Open in new window

Yes, used both Execute and ExecuteScalar with same results.  
I don't really want to go back to the ADO way of doing these types of queries.
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Guy Hengel [angelIII / a3]Billing Engineer
Most Valuable Expert 2014
Top Expert 2009

Commented:
I think you can make your life much simpler ...
select WEBUSER.F_UpdateParticipant(@1) from dual;

Open in new window



and don't use the parameter stuff, but a plain "ExecuteScalar" method in "db", though I don't know what "_db" and "_db.db" objects are ...

object res = _db.db.ExecuteScalar(sql, json);

Open in new window

Eddie ShipmanAll-around developer

Author

Commented:
Guy,
The @0 is the first parameter in the parameters list in the function call, which is json, If I use @1, I get this error: Specified argument was out of the range of valid values.
I have already tried this this way too, but I MUST get the return value from the function call.
Doing it like above (with @0) returns this error: ORA-00911: invalid character

_db.db is the PetaPoco Db connector.

Do you have any other suggestions?
Eddie ShipmanAll-around developer

Author

Commented:
Ok, I've been able to get it to successfully update the record, however, I cannot get the return value at all.
string sql = "DECLARE res VARCHAR2(30); BEGIN return WEBUSER.F_UpdateParticipant(@0); END;";
object res  = _db.db.ExecuteScalar<string>(sql, json);

Open in new window


But res is null because I cannot return anything from the "procedure", I get this if I try:
ORA-06550: line 1, column 33:
PLS-00372: In a procedure, RETURN statement cannot contain an expression
ORA-06550: line 1, column 33:
PL/SQL: Statement ignored
Ensure you’re charging the right price for your IT

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden using our free interactive tool and use it to determine the right price for your IT services. Start calculating Now!

Guy Hengel [angelIII / a3]Billing Engineer
Most Valuable Expert 2014
Top Expert 2009

Commented:
this should do:
string sql = "select WEBUSER.F_UpdateParticipant(@0) FROM DUAL";
string res  = _db.db.ExecuteScalar<string>(sql, json);

Open in new window

Eddie ShipmanAll-around developer

Author

Commented:
Not exactly... Besides an Update, there is also an insert in the function so we get the cannot perform a DML operation inside a query exception.
Guy Hengel [angelIII / a3]Billing Engineer
Most Valuable Expert 2014
Top Expert 2009

Commented:
Eddie ShipmanAll-around developer

Author

Commented:
I'll have to ask our Oracle developer about this one, for sure...
Eddie ShipmanAll-around developer

Author

Commented:
Ok, after adding that to the function, I'm getting this:
ORA-06519: active autonomous transaction detected and rolled back
ORA-06512: at "WEBUSER.F_UPDATEPARTICIPANT", line 153

Open in new window

I'm going to talk to the Oracle developer about how to rewrite this function to work correctly as it is, in my opinion, kind of clunky and stupid in the way it was written.
All-around developer
Commented:
Ok, Guy, I have a solution. I thought I had tried it before from looking at my previous posts. However, when I wrote the SQL, I included the wrapped version and that is what caused the exception, the wrapped sql. If the SQL is written like below, it works, perfectly.

public string UpdateParticipant(ParticipantUpdate Participant)
{
    string ret = "";
    IsoDateTimeConverter dt = new IsoDateTimeConverter();
    dt.DateTimeFormat = "MM-dd-yyyy"; // we must have this format for our dates
    string json = JsonConvert.SerializeObject(Participant, dt);
    // Creating this output parameter is the key to getting the info back.
    var result = new OracleParameter
    {
        ParameterName = "RESULT",
        Direction = System.Data.ParameterDirection.InputOutput,
        Size = 100,
        OracleDbType = OracleDbType.Varchar2
    };
    // Now, setting the SQL like this using the result as the output parameter is what does the job.
    string sql = $@"DECLARE result varchar2(100); BEGIN  @0 := WEBUSER.F_UpdateParticipant(@1); END;";
    var res = _db.db.Execute(sql, result, json);

    // Now return the value of the Output parameter!!

    ret = result.Value.ToString();
    return ret;
}

Open in new window

Guy Hengel [angelIII / a3]Billing Engineer
Most Valuable Expert 2014
Top Expert 2009

Commented:
interesting ...
Eddie ShipmanAll-around developer

Author

Commented:
Yes, for some reason, I kept getting some stupid error from Oracle about invalid character "". so I rewrote the SQL without the wrapping and viola!!
Well, I also redid the output parameter creation, too.
Eddie ShipmanAll-around developer

Author

Commented:
Self-answered

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial