0

問題は次のとおりです。更新コマンドに { } を使用すると、次のようになります。

package require sqlite3
fileRepo eval {UPDATE uploads SET $col=$data WHERE rowid=$id}

中括弧内の変数を置き換えることはできません。すべてハードコーディングする必要があります。

ただし、次のように update コマンドに " " を使用すると、次のようになります。

fileRepo eval "UPDATE uploads SET $col='$data' WHERE rowid=$id"

二重引用符内の変数を置き換えることはできますが、SQL が 1 つの入力として認識するように、スペースを含むデータを入れるには ' ' を使用する必要があります。そうしないと、次のようなものを送信するとエラーが発生します

$data = "正当なスタック"

スペースがあるため、単一引用符で囲まれていない限り、SQL は次の単語を詰まらせます: Stack

したがって...

このデータを update コマンドに送信すると、次のようになります。

$col = description
$data = "Stack's Pet"

次のエラーが表示されます。

"s" の近く: "fileRepo eval "UPDATE uploads SET $col='$data' WHERE rowid=$id" の実行中に構文エラーが発生しました ...

したがって、これらのルールを考えると、一重引用符またはアポストロフィを更新コマンドに正常に渡す方法がわかりません。これを行う別の方法はありますか?

ありがとう!

4

2 に答える 2

4

一重引用符を 2 重にすることで (SQL では通常) エスケープできるのは事実ですが、コードを SQL インジェクション攻撃の危険にさらすことになります。

コードを 2 つの異なるステップに分割することをお勧めします。

  • で代用format {UPDATE uploads SET %s=$data WHERE rowid=$id} $col

  • sqlite3 マジック eval で$dataand$idを準備済みステートメントのバインドされた変数に変換します。

このようにして、すべてのデータではなく、変数をサニタイズするだけcolで、有効な列名だけが含まれていることを確認できます (簡単なはずです)。さらに、大きな値を頻繁にコピーする必要がないため、2 段階のアプローチの方がさらに高速です。バインド変数を使用したいことをより明確にするため:に、変数名の前に a を付けた別の構文を試してください。

package require sqlite3
set stmt [format {UPDATE uploads SET %s=:data WHERE rowid=:id} $col]
fileRepo eval $stmt

推奨読書:

于 2015-11-03T22:35:18.533 に答える
0

エスケープ アポストロフィを使用する必要があります。したがって、次のようになります。

$data = "Stack''s Pet"

于 2015-11-03T16:32:02.013 に答える