2017-02-17 19 views
1
cursor.execute("SELECT * FROM t WHERE c1=:2 AND c2=:1", (1, 2)) 

によって数字を無視し、私は予想通りPythonのcx_oracleは、位置バインド変数

SELECT * FROM t WHERE c1=1 AND c2=2 

代わりに

SELECT * FROM t WHERE c1=2 AND c2=1 

として実行されます。どうして?

実際には全て:番号は完全に無視され

sql = ":5, :0, :0, :2, :1, :3" 

sql = ":1, :2, :3, :4, :5, :6" 

と同じように、これは意図やバグによるもので解釈されますか?

+0

私はcx_oracleがそれらのバインディングを常に同じ方法でカウントしていると思いますが、1から始まります。ただし、名前付きバインディングも使用できます。私はそれらもはるかに明確であることがわかります。 – MKesper

答えて

1

cx_Oracleはこの動作を持つOCIを使用しています。彼らが発生した順に左から右への効果的なOracleのスキャン

http://www.oracle.com/technetwork/database/database-technologies/php/whatsnew/building-best-drivers-131920.pdf

をして、変数をバインドする位置番号を割り当てます。あなたはこのホワイトペーパー(14ページと15ページの最上部の下部)でそれについて読むことができます。代わりに、この潜在的な混乱を避けるために、名前付きのバインド変数を使用できます。

+0

Anthonyありがとうございました。この危険な動作が少なくともcx_Oracleのドキュメントに記載されていると思います。 – Tibco

+0

私はこの動作を危険なものと呼ぶのかどうかはわかりませんが、cx_Oracleのドキュメントにこれに関するメモを入れておいて、あなたのように他の人が驚くことはありません! –

+0

最後に、私はチェックマークがあることに気付きました。私はこのために私のミニORMを書き直すことで数週間を過ごしました。残念ながら、SQL Developerはこれらの位置番号をキーワード引数として扱っているため、この「バグ」を最後に認識しています。私はPythonの文字列形式と同じように動作すると期待していましたが、これは私にとっては自然なことです。 – Tibco