@gvg1

Как передать имя таблицы как параметр?

Пока хватало типа такого:
$s='SELECT a, b FROM t WHERE a=:a';
$q=$pdo->prepare($s);
$q->bindParam(':a',$a,PDO::PARAM_STR);
$q->execute();
$m=$q->fetchAll(PDO::FETCH_ASSOC);


Но таблиц стало много и неопределённо много.
Захотелось сделать так:
$s='SELECT a, b FROM :t WHERE a=:a';
$q=$pdo->prepare($s);
начало цикла по t
$q->bindParam(':t',$t,PDO::PARAM_STR);
$q->bindParam(':a',$a,PDO::PARAM_STR);
$q->execute();
$m=$q->fetchAll(PDO::FETCH_ASSOC);
конец цикла

Ожидаемо получил
Syntax error or access violation: 1064 You have an error in your SQL syntax

Можно сделать так:
начало цикла по t
$s='SELECT a, b FROM '.$t.' WHERE a=:a';
$q=$pdo->prepare($s);
$q->bindParam(':a',$a,PDO::PARAM_STR);
$q->execute();
$m=$q->fetchAll(PDO::FETCH_ASSOC);
конец цикла


Как выкрутиться, чтобы prepare выполнять только один раз?
  • Вопрос задан
  • 160 просмотров
Решения вопроса 1
alexey-m-ukolov
@alexey-m-ukolov Куратор тега PHP
Никак.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 4
@Akina
Сетевой и системный админ, SQL-программист.
Но таблиц стало много и неопределённо много.

Вижу два варианта.

Первый - таблицы принципиально различаются. Просто запросы к ним внешне весьма похожи. В этом случае подобное объединение логически несвязанных запросов в один на основании всего лишь текстового подобия - как минимум бессмысленное, а по большому счёту и вредное, действие.

Второй - таблицы имеют идентичную структуру. В таком случае возникает вполне обоснованный вопрос - а почему это несколько таблиц, а не одна? возможно, вместо отдельной таблицы просто с дополнительным полем, идентифицирующим группу.

Отдельно стоИт вариант, который является подвариантом первого, с той лишь особенностью, что тексты запросов абсолютно совпадают. В этом случае возможным решением может служить хранимая процедура, куда передаётся в виде параметров и имя таблицы, и значение критерия, а внутри выбирается либо строится с помощью CASE текст запроса, выполняемый потом динамическим SQL.
Поясню вариант "строится" - имя таблицы передаётся как параметр хранимой процедуры, там он сравнивается с набором предопределённых литералов, и уже этот предопределённый литерал, а не переданный параметр, участвует в построении текста запроса.

На строго в рамках PDO - полностью согласен с предыдущим оратором. Никак.
Ответ написан
ipatiev
@ipatiev Куратор тега PHP
Потомок старинного рода Ипатьевых-Колотитьевых
В 99% случаев, необходимость подставлять таблицу в запрос динамически говорит о говнокоде.
А в данном случае даже гадать не нужно - этот цикл и "неопределённо много таблиц" - это уже стопроцентнтный говнокод из палаты мер и весов.

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

Как выкрутиться, чтобы prepare выполнять только один раз?

Prepare подготавливает план, нельзя подготовить план без таблицы.
Тем не менее, prepare будет выполняться 1 раз, но для каждой запрошенной таблицы.

А в чем собственно сложность? Prepared statements это всегда как минимум на 2 запроса больше, чем без них, если просто считать запросы. Хотя колво запросов и скорость не везде зависимы. Да и pdo по-умолчанию предпочитает их не использовать, заменяя своей эмуляцией.
Ответ написан
Комментировать
@arturka_v_10
раздели на модели

<?php

namespace app\models;

class Limits extends \app\base\Model {
    
    public $table = 'db_limits';
    
    public function getLimits($lim = 1) {
        $sql = "SELECT * "
                . "FROM {$this->table} "
                . "ORDER BY id DESC "
                . "LIMIT {$lim}";
        return $this->findBySql($sql);
    }
	
	public function updateCurrs($a,$b,$id=1) {
		$sql = "UPDATE {$this->table} SET $a = '$b' WHERE id = ?";
        $this->query($sql, [$id]);
    }

}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы