2010-09-29 3 views
2

Я пытаюсь создать дизайн класса наследования для продуктов.Есть ли способ сделать динамическое имя таблицы в запросе?

Существует базовая таблица, содержащая все общие поля. Затем для каждого типа продукта есть отдельная таблица, содержащая только поля, которые относятся только к этому типу продукта.

Итак, чтобы получить все данные для продукта, мне нужно, чтобы JOIN базовый стол с любой таблицей, которая коррелирует с product_type перечисленных в базовой таблице. Есть ли способ, чтобы этот запрос включался в таблицу динамически?

Вот запрос, чтобы попытаться проиллюстрировать то, что я пытаюсь сделать:

SELECT * FROM product_base b 
INNER JOIN <value of b.product_type> t 
    ON b.product_base_id = t.product_base_id 
WHERE b.product_base_id = :base_id 

Есть ли способ сделать это?

ответ

9

Нет, нет никакого способа сделать это. Имя таблицы должно быть известно во время разбора запроса, поэтому анализатор может определить, существует ли таблица, и что он содержит столбцы, которые вы ссылаетесь. Также оптимизатор должен знать таблицу и ее индексы, поэтому он может составить план того, какие индексы использовать.

Что вы запрашиваете для определения таблицы во время выполнения на основе данных, найденных по очереди. Для РСУБД не известно, что во время разбора все значения данных соответствуют реальным таблицам.

Нет причин, по которым вы сделаете это, чтобы реализовать Class Table Inheritance. CTI поддерживает истинные ссылки между таблицами.

Вы описываете antipattern Полиморфных ассоциаций.

+0

+1 для антипаттерн. –

1

Сделать 2 запросы:
Сначала выберите < значение b.product_type>, а затем использовать его во второй (тот, что у вас есть, но заменить < значение b.product_type> с результатом от первого).

0

Нет. Было бы мало смысла, даже если бы это было возможно, поскольку оптимизатор запросов не смог бы составить план, ничего не зная о правой стороне соединения.

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

0

Вы можете создать процедуру, которая принимает имя таблицы в качестве аргумента и создает запрос динамического SQL. Но, вероятно, это проще сделать в вашем серверном коде (PHP). Но вместо того, чтобы превращать его в переменную (и, как было предложено, уязвимы для инъекционных атак), создайте отдельные классы для разных комбинаций соединений. Используйте другой класс (например, диспетчер), чтобы определить правильный класс для создания экземпляра.

Смежные вопросы