Installation guide
mxODBC - Python ODBC Database Interface
statement with embedded literal parameters to a normalized form and then find
that it already has an access plan.
If you plan to run the same statement over and over again or use
cursor.executemany(), then the ODBC driver only has to pass the SQL
statement and the list of parameters to the database, rather than build and send
hundreds of statements across the wire to the database.
Security is better since the ODBC driver or database backend based building of
the final SQL statement prevents the popular SQL injection attack on applications.
With this attack method, an attacker tries to trick an application into inserting a
specially prepared SQL statement string sequence into an application defined SQL
statement template. Say the application uses
"SELECT * FROM MyTable WHERE
A=%s"
. An attacker could then try to send the parameter value "1; DROP TABLE
MyTable"
to the application, which would then result in the SQL statement
"SELECT * FROM MyTable WHERE A=1; DROP TABLE MyTable" to be executed
- in case the application doesn't very carefully check, parse and quote the
parameter value for A.
8.1.1 Parameter Binding Styles
mxODBC uses the ODBC parameter style as binding parameter marker style per
default. This style is called
'qmark' because it uses positional question mark
markers (
'?') to locate the parameters, e.g. 'SELECT * FROM MyTable WHERE
A=?'.
Starting with mxODBC 3.2, mxODBC also provides a way to adjust the parameter
style on a per connection and per cursor basis. In addition of the
'qmark'
parameter style, mxODBC also supports the Oracle style
'named' parameter
style.
The default style is still the
'qmark' style, but you can set the
connection.paramstyle to 'named' to have all new cursors created on the
connection default to the
'named' style. The default cursor.paramstyle is set
to the value
connection.paramstyle of the connection on which the cursor was
created.
It is also possible to adjust existing cursors to use the
'named' parameter style for
all subsequent
cursor.execute*() method calls by simply setting
cursor.paramstyle to 'named'. This has no affect on other cursors created on
the same connection.
Example:
cursor.paramstyle = 'qmark'
cursor.execute("SELECT * FROM MyTable WHERE A=? AND B=?",
(1, 2))
print cursor.fetchall()
cursor.paramstyle = 'named'
cursor.execute("SELECT * FROM MyTable WHERE A=:a AND B=:b",
{'a': 1, 'b': 2})
140