4

私は昨日のほとんどをここやウェブで質問を見て過ごしましたが、何が欠けているのかまだわかりませんでした. 本当にばかげたものに違いないと確信していますが、今では燃え尽きています。

したがって、コード:

temp_table_name = 'COMPTEMP.i'+todo_name+'_MSGRUN'
sql_create_table = "CREATE TABLE "+temp_table_name+" (CL VARCHAR2(255)) NOLOGGING NOCOMPRESS NOCACHE NOPARALLEL MONITORING"
DB_GATEWAY.execute(sql_create_table)

(これは問題なく作成されます)

sql_fill_table_header = """INSERT INTO """+temp_table_name+""" (CL) VALUES (:1)"""
sql_fill_table_build = []
sql_fill_table_build = ['1', '2', '3', '4', '55']

DB_GATEWAY.executemany(sql_fill_table_build, sql_fill_table_header)

(これは現在、セッション プール ガードに送​​られ、最終的には以下になります)

def executemany( self, db_operation, db_prepare ):
    self.cursor_.prepare(db_prepare)
    self.cursor_.executemany(None, db_operation)

これを実行すると、次のエラーが表示されます

OracleException:  ORA-01036: illegal variable name/number

リストから値「55」を削除すると、他のすべてが正常に挿入されるため、1 文字の長さの値のみを受け入れているように見えます。

execute() だけで各ステートメントを実行すると、ステートメントが挿入されます。コードまたはOracleが位置引数を処理する方法のいずれかで何かを行う必要があると確信していますが、今では迷っています。

助けてくれてありがとう!

4

1 に答える 1

4

executemany()のシーケンスが必要です。挿入された行がそれぞれ 1 つの値だけで構成されている場合でも、リスト内のエントリ自体がパラメーターのシーケンスである必要があります。

sql_fill_table_build = [('1',), ('2',), ('3',), ('4',), ('55',)]

またはリストを使用します。

sql_fill_table_build = [['1'], ['2'], ['3'], ['4'], ['55']]

文字列のフラット リストから'55'エントリを引いたものだけで機能する理由は、文字列もシーケンスであるが'55'、長さ 2 のシーケンスだからです。したがって、最後のエントリは と の2 つのパラメーターを挿入しよう'5'とし'5'ますが、クエリは 1 つのパラメーターしか想定していません。

一部の API がフラット リストのみを提供する場合、挿入時にリスト内包表記を使用してフラット リストをネストされたシーケンスに変換できます。

DB_GATEWAY.executemany(sql_fill_table_build, [(v,) for v in sql_fill_table_header])

でこれをテストしていませんcx_Oracleが、一部のデータベース アダプターは iterable も受け入れるため、ジェネレーター式の方が効率的である可能性があります。

DB_GATEWAY.executemany(sql_fill_table_build, ((v,) for v in sql_fill_table_header))

cx_Oracleしかし、それはシーケンスを要求する可能性があります。

于 2013-12-05T12:53:13.417 に答える