Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Subquery

59K
23 апреля 2010 года
rysak
4 / / 23.04.2010
Здравствуйте!

Как вытащить данные из таблицы, имя которой нужно взять из поля другой таблицы, в одном запросе? Я пробовал так, но не получилось:

SELECT t2.* FROM (SELECT t1.TableName FROM objecttypes t1 WHERE t1.ID=5) t2

В результирующем сэте всего одно поле "Table", которое содержит правильное имя таблицы. Но данных из этой таблицы нет.
385
23 апреля 2010 года
SomewherSomehow
477 / / 25.07.2004
Только используя динамический sql, иначе никак.
59K
23 апреля 2010 года
rysak
4 / / 23.04.2010
Вы имеете ввиду использование промежуточных переменных, т.е. только через хранимые процедуры?
253
23 апреля 2010 года
Proger_XP
1.5K / / 07.08.2004
Цитата: rysak
Вы имеете ввиду использование промежуточных переменных, т.е. только через хранимые процедуры?


Либо можно сделать два запроса: получить имя таблицы, а потом подставить во второй запрос (используя клиента на пхп или чём-то ещё).

Вообще, оптимальным вариантом может быть создание одной большой таблицы и ещё одного поля (типа table_id). Если повесить на него индекс, запросы будут проходить с приличной скоростью.
Тогда можно будет обойтись и одним запросом и не надо будет множества таблиц.

59K
23 апреля 2010 года
rysak
4 / / 23.04.2010
Ну, два запроса - это как бы не очень, со всех сторон... Если и делать два запроса, то уже, конечно, в хранимой процедуре.

По одной таблице - так оно и ест. Это дерево объектов, для каждого из которых есть родитель в этом же дереве. Одна таблица. Но типов объектов есть 10 штук разных. У каждого типа свой собственный набор полей. Но с точки зрения объектов дерева - они одинаковые. Их можно перемещать по дереву и т.д. Поэтому дополнительные поля лучше всего хранить в дополнительных связанных таблицах. Но поскольку список типов может дополняться в будущем, было бы правильнее создать отдельную таблицу для этого списка, в которой бы для каждого типа был линк на дополнительную таблицу custom-полей. Ну а у каждого объекта был бы линк на тип объекта. Вот и получаем двойной запрос. А иначе линк на дополнительную таблицу нужно хранит в самой таблице объектов, что противоречит главному принципу реляционности БД.

Но как я понял, вариантов нет, нужна хранимая процедура, так?
385
23 апреля 2010 года
SomewherSomehow
477 / / 25.07.2004
Я имел ввиду формирование запроса динамически.
А уж где его формировать - это зависит от архитектуры вашего по, ваших предпочтений и т.д. Хотите - формируйте на клиенте, как предложил Proger_XP, хотите - сделайте хранимку и формируйте все на сервере, как предложили вы сами, если например трехзвенка и есть сервер приложений, можно на нем..как угодно, главное в том, что придется сформировать строку запроса куда подставить имя вашей таблицы.
59K
23 апреля 2010 года
rysak
4 / / 23.04.2010
Да, я понял, что в одном запросе не получится. Спасибо всем за ответы!

P.S. Скорее всего оставлю таблицу типов объектов (для расширяемости через БД) и буду загружать ее при старте любого скрипта (все они будут работать с главной таблицей объектов). Меняться таблица типов будет раз в год, в крайнем случае. Поэтому такая схема подходит. А в запросах к главной таблице буду просто подставлять имя связанной таблицы уже из статического массива в памяти. Не очень элегантно, зато расширяемо, и вопрос с быстродействием снят. Кто что думает о таком подходе, плиз?
253
23 апреля 2010 года
Proger_XP
1.5K / / 07.08.2004
Честно говоря, ваше описание получилось очень абстрактным, по крайней мере мне трудно что-то добавить. Попробуйте описать задачу такой структуры, может что посоветуем...
385
23 апреля 2010 года
SomewherSomehow
477 / / 25.07.2004
Вообще конечно динамический sql не очень хорошая практика, если делать совсем реляционно, то вместо таблицы под каждый тип объектов, можно было бы создать таблицу которая описыват структуру каждого типа объектов и таблицу со значениями заполняющимися согласно структуре. Но у этого подхода тоже есть недостаток. При сильно разнородных данных и больших объемах могут возникнуть тормоза, даже при правильном использовании индексов, плюс возрастает сложность поддержки такого кода, этакая плата за универсальность.
но раз уж выбран подход с разными таблицами, расскажу как бы сделал я.

Я бы посоветовал прежде всего разделить запросы на запросы работы с таблицей с деревом объектов, и запросы работы с таблицами в которых хранятся атрибуты объекта в отдельности.
Например есть дерево разнородных объектов, допустим нечто вроде ActiveDirectory.

в нем разнородные объекты, например Принтер, Юзер, Компьютер.
У принтера есть название, расположение и т.д.
У юзера логин, права пользователя и т.д.
Так вот, я бы задал отдельно методы работы с каждым типом объектов, плюс методы работы с самим деревом объектов и получение типа узла дерева (объекта).

Типа такого:
Printer: GetPrinterByName, CreatePrinter, ..
User: GetUserByLogin, CreateUser, ..
...
ActiveDirTree: GetActiveDirTree, AddNode, RemoveNode, GetNodeType

Все эти методы я бы реализовал в виде хп на сервере (скорость, модульность, удобство поддержки), нежели запросов с клиента или application server-а, далее на клиенте или application server-е (том же веб-сервере к примеру) реализовал бы набор классов, базовый класс узел дерева, и набор классов, наследников от базового каждый из которых представлял бы собой соответвующий объект (т.е. Printer, User, ...) со своим набором методов.

В соответвующих методах этих объектов прописал бы вызовы соответсвующих процедур, там где надо переопределяя методы базового класса реализуя полиморфизм.

Таким образом работа с объектами дерева как с узлами и как с непосредственно объектами - получилась бы прозрачной для пользователей класса. Все процедуры БД лежат в одном месте, удобны для оптимизации отладки и прочего и никакого гемора с динамическим sql.

А, да, забыл уточнить самое главное-то =)
Весь гемор по выбору таблиц для запросов ложитсья на единственный метод построения дерева, который будет создавать объекты того или иного типа.
Конечно можнос казать, дескать при добавлении нового типа придется дописывать этот метод чтоб он умел работать с объектами новго типа, на что могу объективно возразить, что дописывать-то все-равно придется, т.к. для объектов этого типа вам все равно придется создавать таблицу, определять поля и свойства и методы работы с ней.

Пожалуй все.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог