Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ORA-01008 with all variables bound

I'm using System.Data.OracleClient which does parameter-binding by name and are verifying that CommandText and Parameters are in sync:

    public string CommandText { get; set; }
    public IEnumerable<OracleParameter> Parameters { get; set; }

    private void VerifyThatAllParametersAreBound()
    {
        var variableNames = Regex.Matches(CommandText, ":\\w+")
            .Cast<Match>().Select(m => m.Value).ToArray();
        var parameteterNames = Parameters.Select(p => p.ParameterName).ToArray();

        var unboundVariables = variableNames.Except(parameteterNames).ToArray();
        if (unboundVariables.Length > 0)
        {
            throw new Exception("Variable in CommandText missing parameter: "
                + string.Join(", ", unboundVariables) + ".");
        }

        var unboundParameters = parameteterNames.Except(variableNames).ToArray();
        if (unboundParameters.Length > 0)
        {
            throw new Exception("Parameter that is not used in CommandText: "
                + string.Join(", ", unboundParameters) + ".");
        }
    }

Still one query throws ORA-01008: not all variables bound. When manually inserting the parameter-values into the offending CommandText the query runs, so the CommandText and Parameters-values should be ok. I'm using : as prefix both for variables and parameternames and it's working for the other queries.

How can I pinpoint the cause of this exception?

like image 861
Grastveit Avatar asked Apr 15 '11 15:04

Grastveit


3 Answers

The mistake was not specifing DBNull.Value for null-values. So

new OracleParameter(":Foo", item.Foo)

had to preplaced with

item.Foo == null 
    ? new OracleParameter(":Foo", DBNull.Value) 
    : new OracleParameter(":Foo", item.Foo)

I think it was working earlier with ODT.NET without null-checks, but have not confirmed it. Apparently System.Data.OracleClient is dropping parameters with null-value.

like image 172
Grastveit Avatar answered Oct 07 '22 00:10

Grastveit


If you pass null as parameter value, you get "Not all variables bound" If you pass DBNull.Value you get runtime error somewhere in the OracleClient. To pass NULL, use string.Empty, OracleClient converts it to NULL for any database type.

like image 22
Yaro Avatar answered Oct 07 '22 01:10

Yaro


If you have more than one parameter, you need to set BindByName to true. For example:

OracleCommand cmd = con.CreateCommand();

cmd.BindByName = true;

cmd.Parameters.Add(new OracleParameter("parameter1", parameter1));
cmd.Parameters.Add(new OracleParameter("parameter2", parameter2));
like image 31
Donal Avatar answered Oct 07 '22 01:10

Donal