Search code examples
c#oracleoraclecommand

Get 'PL\SQL Table' returned from a function with OracleCommand in C#


I'm new to using OracleCommand in C# to return results from Oracles procedures\functions, I've been able to get most of my storedProcedure executions working but I'm in need of advise on the following.

Below is a function that returns a table I created off a record type

create or replace
function return_table return t_nested_table AS

v_ret   t_nested_table;

begin
  v_ret  := t_nested_table();

  v_ret.extend;
  v_ret(v_ret.count) := t_col(1, 'one');

  v_ret.extend;
  v_ret(v_ret.count) := t_col(2, 'two');

  v_ret.extend;
  v_ret(v_ret.count) := t_col(3, 'three');

  return v_ret;
end return_table;

The type were created as follows

create or replace
type t_col as object (
  i number,
  n varchar2(30)
);

The table from t_col record

create or replace
type t_nested_table as table of t_col;

Now when I wanted to execute the function in C#, I tried the following but realised OracleDbType has no enum for PL\SQL Table.

using (OracleConnection conn = new OracleConnection(connection))
            using (OracleCommand cmd = new OracleCommand())
            {
    cmd.Connection = conn;
    cmd.BindByName = true;
    cmd.CommandText = "return_table";
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.Parameters.Add("\"v_ret\"", OracleDbType.Object, DBNull.Value, ParameterDirection.ReturnValue);
    conn.Open();
    try
    {
        cmd.ExecuteNonQuery();
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

But this just throws an error:

Invalid parameter binding
Parameter name: "v_ret"

I've tried other ways but so far nothing has worked.

I'm hoping there is a way to fix this in my C# code only because there are allot of existing function that I won't be able to edit.

I also had look at similar questions to mine but was not able to fine the answer from them.


Solution

  • This C# code may be useful to you, it worked for me with your own defined Oracle type:

    using (OracleCommand cmd = new OracleCommand())
    {
        cmd.Connection = conn;
        cmd.CommandText = "select * from table(return_table())";
        cmd.CommandType = CommandType.Text;
        conn.Open();
        OracleDataReader rdr = cmd.ExecuteReader();
        while (rdr.Read())
        {
            Console.WriteLine(rdr.GetOracleDecimal(0));
            Console.WriteLine(rdr.GetOracleString(1));
        }
        conn.Close();
    }