[DB-SIG] Re: cx_Oracle - passing unnecessary bind variables
Paul Moore
pf_moore at yahoo.co.uk
Sun Nov 23 14:31:55 EST 2003
Anthony Tuininga <anthony at computronix.com> writes:
> On Thu, 2003-11-20 at 14:01, Paul Moore wrote:
>> The problem is that this doesn't work - it returns an Oracle error,
>> cx_Oracle.DatabaseError: ORA-01036: illegal variable name/number.
>>
>> OK, this is to some extent a limitation of Oracle (or maybe of
>> cx_Oracle, I don't know how Oracle OCI works at this low a level) -
>> I'm passing bind variables which aren't used by the SQL statement. But
>
> This is definitely a limitation of Oracle. Oracle does not allow you to
> specify variables that are not part of the statement. As far as I know
> there is no way around this. Oracle does provide a way of returning to
> you the bind variable names once the statement is prepared but cx_Oracle
> does not (currently) provide that information. I have another workaround
> for now but if you really think this would be helpful, feel free to ask
> me for it -- this is definitely beyond the scope of the DB API but I
> have long since stopped feeling restricted by the limitations of the API
> (which has to accommodate each of the different database management
> systems out there).
The behaviour of cursor.execute(sql, parameters) when there are
variables specified in `parameters` which are not needed by `sql` is
undefined in the DB-API. However, the more I think about it, the more
I feel that ignoring "extra" parameters is the more user-friendly
option.
The cons:
* It's potentially harder for module authors to implement (as you
pointed out for Oracle)
* It may be slower in cases where it's not needed.
* It could hide typos (but they'd have to be pretty obscure - include
an extra, misspelled, variable, but still include the variable by
its "correct" name as well)
The pros:
* Supports using the same parameter dictionary for multiple SQL
statements.
* There is no easy way to do this in user code (you can't get the
list of bind variables used by a cursor, so you have to work
around it by making the user pass the variables, like we said).
* This is DB-API compliant (if not mandated). It's only relevant for
paramstyles of 'named' and 'pyformat', so it doesn't apply to all
of the modules out there.
I checked a few of the modules I could find, mostly by just
looking at the documented paramstyle:
Module Paramstyle Notes
---------- ---------- -----------------------------
mxODBC qmark not relevant
DCOracle2 numeric not relevant [1]
pysqlite pyformat ignores extra arguments
adodbapi qmark not relevant
psycopg pyformat ignores extra arguments [2]
pyPgSQL pyformat ignores extra arguments [2]
Sybase named can't test
Ingres ? can't test
[1] It's a pity DCOracle2 uses numeric arguments, as this is the
closest equivalent to cx_Oracle (in terms of what is needed for
implementation, at least).
[2] I don't have Postgres to test, but scanning the implementation, it
seems to use the normal Python % operations to build the SQL from
the arguments, so it should ignore extra arguments.
Does anyone have any thoughts? Obviously, I'm not in any position to
insist that things work this way. If I knew more about OCI coding, I'd
try to supply a patch (I may see what I can do anyway - I assume it's
OCIStmtGetBindInfo() that's relevant here?)
Paul.
PS Actually, on reflection, there's a comparable question for
positional styles - can you have a parameter sequence that's longer
than needed? I don't think this is as important, though - but that
may just reflect my personal view that named bindings are far more
useful than positional ones. [FWIW, though, I did a quick check and
mxODBC, at least, rejects parameter lists of the wrong length]
--
This signature intentionally left blank
More information about the DB-SIG
mailing list