db_query()で変数を使用してテーブルを選択するにはどうすればよいですか?


7

ユーザーの送信から取得された変数に基づいて、テーブルからレコードを検索しようとしています。これは私のクエリです:

$field = t('field_data_' . variable_get('tabbed_content_field'));
$fieldValue = t(variable_get('tabbed_content_field') . '_value');
$query = db_query('SELECT :fieldValue FROM {:field}', array(':field' => $field, ':fieldValue' => $fieldValue));

ただし、このクエリを実行するたびに次のエラーが発生します。

PDOException:SQLSTATE [42000]:構文エラーまたはアクセス違反:1064 SQL構文にエラーがあります。2行目の '' field_data_field_news_release_date ''付近で使用する正しい構文については、MySQLサーバーのバージョンに対応するマニュアルを確認してください。SELECT:fieldValue FROM {:field}; 配列([:field] => field_data_field_news_release_date [:fieldValue] => field_news_release_date_value)

私はレコードを正常に取得できます:

$query = db_query('SELECT ' . $fieldValue . ' FROM { ' . $field . '}');

しかし、私が理解しているように、これは安全ではありません。

最初のクエリが機能しない理由を誰かが知っていますか?


2
補足として、t()翻訳する必要のない文字列には使用しません。データベーステーブルまたはデータベースフィールドの名前は、翻訳する必要があるものではありません。「ノード」テーブルは、サイトで現在有効になっている言語とは無関係に、常に「ノード」テーブルです。
kiamlaluno

@kiamlalunoああそうだね。
スティーブンヤング

回答:


6

これがDrupal 7に新しいクエリビルダーが存在する理由の1つなので、クエリの一部を動的に置き換えることができます。

$table_name = 'the_table';
$field_name = 'a_field';
$query = db_select($table_name)->fields($table_name, array($field_name));

使用db_query()すると、パラメータ置換のみが取得されます。これは、WHERE条件の置換にのみ適用されます。これは、db_query()テーブル名、選択したフィールドの名前など、WHERE条件のみの置き換えには使用できないことを意味します。

db_select()動的クエリに条件を追加する方法など、より詳細な例については、ドキュメントをご覧ください。


クライブに感謝します-それは私にとってうまくいきました。db_select関数は、潜在的に悪意のあるデータエントリを自動的にサニタイズしますか?
スティーブンヤング

1
@StephenYoungそれは、Drupalデータベースレイヤーが本質的にPDOのラッパーであるため、パラメーター化されたクエリのすべての良さをすぐに組み込むことができます。安全にそれを使用する唯一の方法は、質問の2番目の例のようなものです。悪用される可能性があります。
クライブ

@StephenYoungデータベースAPIに渡されるデータはサニタイズされます。
kiamlaluno
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.