2015-04-18 2 views
2

Давайте предположим, что (для простоты), у меня есть две таблицы:Динамический запрос со столбцами и имен таблиц из нескольких таблиц с помощью SQL или PL/SQL

Product 
product_id 
CreatedDate 
LastEditedBy 
EditedDate 

Entity 
entity_id 
CreatedDate 
LastEditedBy 
EditedDate 

Обе таблицы имеют одинаковые имена столбцов, но только столбец ID имеет другое имя. Я хотел бы запустить запрос, чтобы, когда я запускаю его из SQL plus, просто даю ему параметр и он получает данные из одной из таблиц. В приведенном выше примере я мог выполнить запрос, как этот

@archiveHistory.sql product 
@archiveHistory.sql entity 

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

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

define identifier = '&1' 

Select * from (
Select case lower('&identifier') 
    when product then product_id 
    when entity then entity_id 
    end ID, CreatedDate, LastEditedBy, EditedDate 
From &identifier 
) 

Я думаю, что это будет работать, если список столбцов в операторе CASE, были все из той же таблицы.

Вопросы

  • Что мне нужно сделать запрос игнорирует столбец, который не имеет значения то игнорировать product_id, если аргумент объект

  • Я думал об использовании анонимного PL/SQL block (т.е. Begin End), но я не уверен, как я могу отобразить вывод без использования dbms_output.put_line.

ответ

2

В данном конкретном случае, я думаю, что следующий SQL-единственное решение может работать лучше:

SELECT product_id AS the_field 
    , CreatedDate, LastEditedBy, EditedDate 
FROM Product 
WHERE LOWER('&identifier') = 'product' 
UNION ALL 
SELECT entity_id AS the_field 
    , CreatedDate, LastEditedBy, EditedDate 
FROM Entity 
WHERE LOWER('&identifier') = 'entity' 

Планировщик запросов будет предварительно оценить ваши '&identifier' = ... предикаты, что предотвращает выполнение ненужных накидной подзапроса ,

Если это не вариант (потому что ваш реальный вариант использования является гораздо более сложным), есть много ответов на переполнение стека уже относительно выполнения динамического SQL из PL/SQL:

Вы можете использовать динамический SQL для вставки данных в временную таблицу, а затем просто SELECT * FROM temp_table

+0

OP говорит, что мы должны предположить, что у них есть две таблицы «для простоты». Я подозреваю, что в реальной жизни их гораздо больше. – APC

+0

@ APC: Я согласен, и я начал с * «Для этого конкретного случая» * :-), но если этого отказа не было («для простоты»), это было бы полезным ответом на более общий вопрос, который люди найдут, когда у них Google такая тема. Таким образом, даже если это может быть не полезно для OP, это может быть полезно для других. –

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