5

Is it possible to correctly pass an OracleParameter to a boolean parameter in a pl/sql stored procedure?

haymansfield
  • 5,419
  • 4
  • 34
  • 51

2 Answers2

10

I used the following workaround to bypass this limitation:

  1. Wrap the function call using an anonymous block.
  2. Return an output variable containing 1 or 0.
  3. Read the output variable and cast it to boolean.

Here is some sample code:

using (var connection = new OracleConnection("<connection string>"))
{
    var command = new OracleCommand();
    command.Connection = connection;
    command.CommandText = 
        "declare v_bool boolean;" + 
        "begin " +
        "v_bool := auth_com.is_valid_username (:username); "+
        "if (v_bool = TRUE) then select 1 into :v_result from dual; end if; " +
        "if (v_bool = FALSE) then select 0 into :v_result from dual; end if; " +
        "end;";

    command.Parameters.Add(new OracleParameter { ParameterName = "username", OracleDbType = OracleDbType.NVarchar2, Size=512, Direction = ParameterDirection.Input });
    command.Parameters.Add(new OracleParameter { ParameterName = "v_result", OracleDbType = OracleDbType.Decimal, Direction = ParameterDirection.Output });     

    try
    {
        connection.Open();
        command.ExecuteNonQuery();
    }
    finally
    {
        connection.Close();
    }

    bool success = Convert.ToBoolean(((OracleDecimal)command.Parameters["v_result"].Value).ToInt32());
}

EDIT:

Alex Keh from Oracle, october 2013:

We're planning on supporting ODP.NET Boolean in the managed provider in the near term, possibly in the middle of next year.

Kiquenet
  • 14,494
  • 35
  • 148
  • 243
JCallico
  • 1,446
  • 18
  • 25
  • Maybe functions package diutil: sys.diutil.int_to_bool and sys.diutil.bool_to_int. Requires permissions in schema. – Kiquenet Oct 30 '13 at 13:59
4

You can not use boolean parameters in SQL. So calling an stored procedure that takes or returns a boolean value won't work in SQL. There is no problem using such a procedure from within a pl/sql block.

ADDED from JCallico answer:

I used the following workaround to bypass this limitation:

  1. Wrap the function call using an anonymous block.
  2. Return an output variable containing 1 or 0.
  3. Read the output variable and cast it to boolean.

Here is some sample code:

using (var connection = new OracleConnection("<connection string>"))
{
    var command = new OracleCommand();
    command.Connection = connection;
    command.CommandText = 
        "declare v_bool boolean;" + 
        "begin " +
        "v_bool := auth_com.is_valid_username (:username); "+
        "if (v_bool = TRUE) then select 1 into :v_result from dual; end if; " +
        "if (v_bool = FALSE) then select 0 into :v_result from dual; end if; " +
        "end;";

    command.Parameters.Add(new OracleParameter { ParameterName = "username", OracleDbType = OracleDbType.NVarchar2, Size=512, Direction = ParameterDirection.Input });
    command.Parameters.Add(new OracleParameter { ParameterName = "v_result", OracleDbType = OracleDbType.Decimal, Direction = ParameterDirection.Output });     

    try
    {
        connection.Open();
        command.ExecuteNonQuery();
    }
    finally
    {
        connection.Close();
    }

    bool success = Convert.ToBoolean(((OracleDecimal)command.Parameters["v_result"].Value).ToInt32());
}

EDIT:

Alex Keh from Oracle, october 2013:

We're planning on supporting ODP.NET Boolean in the managed provider in the near term, possibly in the middle of next year.

Kiquenet
  • 14,494
  • 35
  • 148
  • 243
Rene
  • 10,391
  • 5
  • 33
  • 46