2011-06-03 5 views
1

Ruby Sqlite3ライブラリを使用してレコードをデータベースに挿入しています。私は以下の文を動作させる問題を抱えています(投稿されたすべての変種を試しました)。 SQLite3::RangeException - bind or column index out of range:例外が発生します。複数のパラメータを挿入するとSQLite3 :: RangeExceptionが返されます

値がハードコードされていればクエリが機能します...どうしたら間違っていますか?

statement = db.prepare("insert into IntegrationLogin (Username, Password, ProjectID) values (\"?1\", \"?2\", 1)") 
    statement.execute [params['username'], params['password']] 

    statement = db.prepare("insert into IntegrationLogin (Username, Password, ProjectID) values (\"?1\", \"?2\", 1)") 
    statement.execute params['username'], params['password'] 

    statement = db.prepare("insert into IntegrationLogin (Username, Password, ProjectID) values (\"?\", \"?\", 1)") 
    statement.execute params['username'], params['password'] 

答えて

2

あなたの問題は、パラメータインジケータ(?)を引用符で囲んでみることにあります。これは、ドライバが文字列パラメータを引用符で囲み、クエリを実行する前に追加のエスケープ処理を実行するため、不要です。引用符を削除すると、クエリの例が正常に実行されました。

あなたの余分な見積もりが何らかの形でパラメータインジケータをエスケープしていて、ドライバが表示していないようです。

これを使用して:

statement = db.prepare("insert into IntegrationLogin (Username, Password, ProjectID) values (?, ?, 1)")

あなたはそれがために必要なよりも、この困難を作っていました。この種のパラメータバインディングは、余分な引用符を付けなくてもSQLインジェクションを完全に防ぐことができます。

+1

「準備」ステートメントを複数回使用しないでください。あなたがそうした場合、あなたはそれをまったく使用する目的を破ります。 prepareメソッドは、クエリを構築するオーバーヘッドを処理します。これは、一度だけ行うだけです。その後、準備したステートメントを何度でも実行して、オーバーヘッドを1回だけ実行するというパフォーマンスを得ることができます。 –