#sql #oracle #ora-00904
#sql #Oracle #ora-00904
Вопрос:
Table Meta:
-------------------------------------
type tab_name
new tab_news
sports tab_sps
Table tab_news
------
id
Table tab_sps
-------------------
id
xx
Теперь я хочу использовать
SELECT id
FROM (SELECT tab_name
FROM Meta
WHERE type = 'news');
Но это не работает, есть идеи?
Комментарии:
1. @OMG Ponies — Операционная система хочет получить все данные из таблицы tab_news. Вместо этого OP получает единственную запись из Meta-таблицы.
2. Привет, я обновляю сообщение, «BiggsTRC» правильно, я хочу получить записи таблицы tab_news. И ошибка «ошибка ora: 09004, недопустимый идентификатор «id»);
3. @OMG Ponies — Да, если вы хотели сделать это во время разработки. Однако операционная система хочет выполнить поиск данных из разных таблиц на основе значения в таблице. Например, при следующем запуске запроса вместо этого может быть указано перейти к таблице tab_sps. OP хочет, чтобы запрос изменялся во время выполнения на основе информации в базе данных.
4. Поддерживает ли oracle динамический sql?
5. @Conrad Frix: Да, Oracle поддерживает динамический SQL. Подробности смотрите в моем ответе.
Ответ №1:
SQL не поддерживает переменную / etc для имени таблицы — единственное средство поддержки того, что вы запрашиваете, — это использование динамического SQL:
FOR i IN (SELECT tab_name
FROM META m
WHERE m.type = ?) LOOP
EXECUTE IMMEDIATE 'SELECT * FROM '|| i.tab_name ||'';
END LOOP;
Комментарии:
1. Ошибка ORA-00904 связана с тем, что вы не можете ссылаться на столбцы, которые не существуют в таблице или производной таблице / встроенном представлении.
Ответ №2:
Синтаксическая структура, которую вы пытаетесь использовать, не выполняет то, что вы хотите. То, что появляется в предложении FROM, является набором данных. Это может быть таблица или представление. В вашем случае набор данных является подмножеством «Meta»; в частности, столбец «tab_name» для строк с типом «новости».
SELECT id
FROM (SELECT tab_name
FROM Meta
WHERE type = 'news');
SQL в основном ориентирован на множество. Кажется, вы хотите, чтобы «tab_name» возвращал «указатель» или ссылку на набор данных. Это предполагает более объектно-ориентированный подход. Вместо имя_таблицы функция select from Meta будет возвращать экземпляры объекта, а оболочка будет использовать метод для этого объекта для извлечения деталей. Это было бы скорее
SELECT tab_name.getId()
FROM Meta
Where type = 'news';
Но мне нужно более подробное описание проблемы в терминах бизнеса, прежде чем пытаться угадать, как могут выглядеть структуры объектов.
Ответ №3:
Я не верю, что то, чего вы пытаетесь достичь, возможно. Если вы работаете с языком программирования с этими данными, вы могли бы сначала вернуть значение подзапроса, а затем создать новую инструкцию SQL для нужного вам запроса. Однако построение динамического запроса внутри SQL подобным образом представляется невозможным.
Я думаю, вам нужно сделать шаг назад и посмотреть на логику вашей базы данных. Должен быть другой способ сделать это. Например, поскольку каждая таблица должна была иметь одинаковый макет, возможно, вы могли бы объединить все, а затем отфильтровать данные только для того, что вам действительно нужно. Вы могли бы сделать это во время выполнения с помощью подзапроса. Процесс будет иметь значительные накладные расходы, если он будет масштабироваться слишком сильно, но это может решить вашу основную проблему. В принципе, переосмыслите свой дизайн. Есть способ достичь вашей конечной цели, но он не по этому пути.
Комментарии:
1. Да, я пробовал это раньше, и в итоге я использовал именно этот подход. SQL возвращает объект, а не обычную текстовую строку, которая, как я полагаю, принимает только обычный текст в имени таблицы
Ответ №4:
Попробуйте изменить псевдоним подзапроса.
select * from (select tab_name from Meta where type='news') as my_sub_query;
Комментарии:
1. Это не дало бы желаемых результатов. В нем все равно будет указана только одна запись из Meta-таблицы вместо таблицы, которую хотел OP.