DEV Community

QueryWrangler
QueryWrangler

Posted on

The ORA-01008 Trap: Why Your Oracle .NET Bind Variables Keep Failing

If you've worked with Oracle.ManagedDataAccess in .NET and hit ORA-01008: not all variables bound on a query that looks completely correct, you're not alone. This one cost me hours across a service with two dozen separate database calls — and the fix, once you see it, is almost embarrassingly simple.

The symptom

You write a query like this:

var cmd = connection.CreateCommand();
cmd.CommandText = "SELECT * FROM MY_TABLE WHERE ID = :p_id AND STATUS = :p_status";
cmd.Parameters.Add(new OracleParameter("p_id", id));
cmd.Parameters.Add(new OracleParameter("p_status", status));
Enter fullscreen mode Exit fullscreen mode

It looks right. The parameter names match the bind variables. And yet: ORA-01008: not all variables bound.

The wrong assumption

The natural assumption is that Oracle matches parameters to bind variables by position — same as it would with a plain ADO.NET provider talking to SQL Server. So if you've added your parameters in the same order they appear in the SQL, you'd expect it to just work.

Oracle.ManagedDataAccess doesn't default to that behavior.

The actual cause

By default, OracleCommand in Oracle.ManagedDataAccess binds parameters by position, not by name — but only if you don't explicitly say otherwise. The moment your parameter count or order drifts even slightly from the SQL text (which happens easily once queries get edited, reordered, or grow additional conditions over time), the binding silently breaks, and you get ORA-01008.

The fix

Set BindByName = true explicitly on every command:

var cmd = connection.CreateCommand();
cmd.CommandText = "SELECT * FROM MY_TABLE WHERE ID = :p_id AND STATUS = :p_status";
cmd.BindByName = true; // <-- this line saves you hours
cmd.Parameters.Add(new OracleParameter("p_id", id));
cmd.Parameters.Add(new OracleParameter("p_status", status));
Enter fullscreen mode Exit fullscreen mode

Once BindByName = true is set, Oracle matches parameters to bind variables by their names, not their position — which matches how everyone actually reads and writes the SQL. Order stops mattering.

The broader lesson

If you're working with Oracle.ManagedDataAccess in any non-trivial .NET application, make BindByName = true a non-negotiable line in every single command — consider wrapping it into a base helper or extension method so it's impossible to forget. One missed instance in a codebase with dozens of Oracle calls is all it takes to lose an afternoon to a cryptic error that has nothing to do with your actual SQL.

Top comments (0)