Как можно передать название таблицы в качестве параметра?

Как можно модифицировать код, чтобы использовать метод <b>prepare</b> только один раз, сохраняя при этом возможность работы с множеством таблиц в SQL запросе, без возникновения ошибок синтаксиса? 

Пример текущего кода, который вызывает ошибку:
<pre><code class="php">$s='SELECT a, b FROM :t WHERE a=:a';
$q=$pdo-&gt;prepare($s);
здесь цикл
$q-&gt;bindParam(':t',$t,PDO::PARAM_STR);
$q-&gt;bindParam(':a',$a,PDO::PARAM_STR);
$q-&gt;execute();
$m=$q-&gt;fetchAll(PDO::FETCH_ASSOC);
конец цикла</code></pre>

И пример кода, который работает, но приводит к многократному вызову <b>prepare</b>:
<pre><code class="php">здесь цикл
$s='SELECT a, b FROM '.$t.' WHERE a=:a';
$q=$pdo-&gt;prepare($s);
$q-&gt;bindParam(':a',$a,PDO::PARAM_STR);
$q-&gt;execute();
$m=$q-&gt;fetchAll(PDO::FETCH_ASSOC);
конец цикла</code></pre>
  • 27 ноября 2024 г. 17:13
Ответы на вопрос 2
В PDO нельзя использовать параметры для имен таблиц и столбцов. Однако вы можете использовать подготовленные выражения для переменных, которые не влияют на синтаксис SQL. Чтобы избежать множественных вызовов метода `prepare`, вы можете использовать концепцию динамического SQL. 

Вы можете сделать следующее:

1. Проверяйте и очищайте имя таблицы перед использованием, чтобы избежать SQL-инъекций.
2. Подготовьте запрос только один раз, а затем динамически подставляйте имя таблицы в запрос.

Вот пример кода, который сможет сделать это корректно:

```php
// Предполагаем, что вы получаете имена таблиц из безопасного источника
$valid_tables = ['table1', 'table2', 'table3']; // Список допустимых таблиц
$t = 'table1'; // Имя таблицы, которое вы хотите использовать

// Проверяем, находится ли $t в списке допустимых таблиц
if (!in_array($t, $valid_tables)) {
    throw new Exception("Недопустимое имя таблицы: " . htmlspecialchars($t));
}

// Подготавливаем запрос с использованием именованных параметров для столбцов
$s = "SELECT a, b FROM $t WHERE a = :a";
$q = $pdo->prepare($s);

// Предполагаем, что вы используете цикл для выполнения
foreach ($some_array as $a) {
    $q->bindParam(':a', $a, PDO::PARAM_STR);
    $q->execute();
    $m = $q->fetchAll(PDO::FETCH_ASSOC);
    // Обработка результата
}
```

В этом коде мы сначала проверяем имя таблицы и очищаем его, после чего подставляем в запрос. Мы готовим запрос только один раз, и это позволяет нам избежать ошибок синтаксиса, связанных с использованием параметров для имен таблиц. Вместо этого мы используем статичное выражение для имени таблицы, что безопасно, если вы предварительно удостоверились, что имена таблиц допустимы.
В 99% случаев, необходимость подставлять таблицу в запрос динамически говорит о говнокоде. 
А в данном случае даже гадать не нужно - этот цикл и "неопределённо много таблиц" - это уже стопроцентнтный говнокод из палаты мер и весов.

Таблица должна быть одна . И все проблемы сразу исчезнут как по волшебству.
Похожие вопросы