0

ユーザーがWebページを介して対話するデータベースを実装している大学の割り当てがあります。目標は、いくつかの基準を指定して書籍を検索することです。これは、より大きなプロジェクト内の 1 つのモジュールです。

ユーザーが必要な基準と順序を選択できるようにしたいのですが、次のようには機能しないようです。

cursor.execute("SELECT * FROM Books WHERE ? REGEXP ? ORDER BY ? ?", [category, criteria, order, asc_desc])

理由がわからない、なぜなら私が行くとき

cursor.execute("SELECT * FROM Books WHERE title REGEXP ? ORDER BY price ASC", [criteria])

完全な結果が得られます。インジェクションに頼らずにこれを修正する方法はありますか?

データは書籍の ISBN が主キーであるテーブルに編成され、各行には書籍のタイトル、著者、発行者などの多くの列があります。ユーザーはこれらの列のいずれかを選択して検索を実行できる必要があります。 .

4

1 に答える 1

1

一般に、SQL エンジンはのパラメーターのみをサポートし、テーブルや列などの名前ではサポートしません。これは、sqlite 自体と Python の sqlite モジュールに当てはまります。

この背後にある理論的根拠の一部は歴史的なものです (従来の不器用なデータベース API にbindは、どの列番号とどの型のどの値をバインドするかを指定する必要がある明示的な呼び出しがありました) が、主に値をパラメーター化する正当な理由があまりないためです。 .

一方では、テーブル名と列名の引用符や型変換について心配する必要はありません。一方、エンドユーザーが作成したテキストでテーブルまたは列を指定できるようになると、それらが他にどのような害を及ぼす可能性があるかを理解するのは困難です。

また、パフォーマンスの観点から (また、sqlite のドキュメント(セクション 3.0 を参照) を読むと、安全性の問題ではなく、パフォーマンスの問題としてパラメーター バインディングに焦点を当てていることに気付くでしょう)、データベース エンジンは、準備された最適化されたクエリを再利用できます。異なる値を指定した場合は計画しますが、異なる列を指定した場合は計画しません。


それで、これについて何ができますか?

SQL 文字列を動的に生成することは 1 つのオプションですが、唯一のオプションではありません。

まず、この種のことは、多くの場合、さらに一歩正規化する必要がある壊れたデータ モデルの兆候です。たぶんBookMetadata、それぞれにフィールド名と値を持つ多くの行があるテーブルが必要Bookですか?

第 2 に、このコードに関する限り概念的には正規化されているが、実際には非正規化されているもの (効率のため、または他のコードに対して正規化されるべきではないため) が必要な場合は、関数が最適です。create_functionラッパーであり、その関数にパラメーターを渡すことができますexecute

于 2013-11-06T00:15:53.830 に答える