1

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.

2 Answers 2

1

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();
}
Sign up to request clarification or add additional context in comments.

Comments

1

I don't think you can return a user-defined object to Oracle Data Provider. But you can return a RefCursor:

create or replace
function return_table return SYS_REFCURSOR AS

v_ret   t_nested_table;
res SYS_REFCURSOR;

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');

  OPEN res for SELECT * from TABLE(v_ret);
  RETURN res;
end return_table;

Then in C# it would be like this:

cmd.Parameters.Add("v_ret", OracleDbType.RefCursor, ParameterDirection.ReturnValue);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.