準備されたステートメント: SELECT クエリでの動的列名の処理
課題:
準備されたステートメントは、SELECT
クエリ内の動的な列名に対応できますか?
シナリオ:
ユーザーが MySQL と Java の例を示しました:
<code class="language-java">String columnNames = "d,e,f"; // From user input String tableName = "some_table"; // From user input String query = "SELECT a,b,c,? FROM " + tableName + " WHERE d=?"; //...</code>
パラメータを columnNames
文字列に置き換えると、次のようになります。
<code class="language-sql">SELECT a,b,c,'d,e,f' FROM some_table WHERE d='x'</code>
ただし、意図された結果は次のとおりです。
<code class="language-sql">SELECT a,b,c,d,e,f FROM some_table WHERE d='x'</code>
解決策:
動的列名に準備されたステートメントを直接使用することは実現できません。 準備されたステートメントは、列識別子ではなく、値をパラメータ化します。
代替戦略:
最も効果的な解決策には、データベース スキーマの変更が含まれます。 データを多数の列に分散させる代わりに、動的に名前が付けられた列を保持する単一の列を導入します。 この列には、各行の列名のリストを表すシリアル化された文字列が含まれます。
これには、SQL インジェクションを防ぐために厳密な入力サニタイズが必要になります。 String#replace()
を使用して引用符をエスケープし、その後サニタイズされた列名を SQL クエリ文字列に連結することが実行可能な方法です。 可能な場合はセキュリティ上の利点を維持するために、クエリの他の部分にパラメータ化されたクエリを使用することを検討してください。
以上が準備されたステートメントは SELECT クエリの動的な列名を処理できますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。