Динамически выбирать столбцы, которые будут использоваться в операторе SELECT - PullRequest
7 голосов
/ 12 августа 2011

Мне бы хотелось иметь возможность использовать системные таблицы (в нашем случае Oracle), чтобы определить, какие поля используются в операторе SELECT. Что-то вроде:

SELECT 
(
select  column_name
from    all_tab_cols
where   table_Name='CLARITY_SER'
AND     OWNER='CLARITY'
AND     data_type='DATE'
) 
FROM CLARITY_SER

Этот синтаксис не работает, поскольку подзапрос возвращает несколько строк вместо одной строки с несколькими столбцами.

Можно ли динамически генерировать оператор SQL, запрашивая информацию о схеме таблицы, чтобы выбрать только определенные столбцы?

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

Ответы [ 4 ]

8 голосов
/ 12 августа 2011

Вы можете сделать это:

declare
  l_sql varchar2(32767);
  rc sys_refcursor;
begin
  l_sql := 'select ';
  for r in
  ( select  column_name
    from    all_tab_cols
    where   table_Name='CLARITY_SER'
    AND     OWNER='CLARITY'
    AND     data_type='DATE'
  )
  loop
    l_sql := l_sql || r.column_name || ',';
  end loop;
  l_sql := rtrim(l_sql,',') || ' from clarity_ser';
  open rc for l_sql;
  ...
end;
2 голосов
/ 12 августа 2011

Вы можете использовать динамический SQL. Создайте функцию, которая принимает имя таблицы, владельца, тип данных, выполняет внутренний запрос и возвращает разделенный запятыми список имен столбцов или таблицу массивов, если вы предпочитаете. Затем создайте внешний запрос и выполните его с execute immediate.

CREATE FUNCTION get_column_list(
      table_name IN varchar2,
      owner_name IN varchar2,
      data_type  IN varchar2) 
   RETURN varchar2 
   IS 
BEGIN 
...... (get columns and return comma-separated list)
 END;
/

Если ваша функция возвращает список через запятую, вы можете вставить его в строку:

execute immediate 'select ' || get_column_list(table_name, owner_name, datatype) || ' from ' || table_name

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

2 голосов
/ 12 августа 2011

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

1 голос
/ 13 августа 2011

В SQLPlus вы можете сделать это:

COLUMN cols NEW_VALUE cols

SELECT max( ltrim( sys_connect_by_path( column_name, ',' ), ',' ) )  cols
FROM
(
select rownum rn, column_name
from    all_tab_cols
where   table_Name='CLARITY_SER'
and     OWNER='CLARITY'
AND      data_type='DATE'
)
start with rn = 1 connect by rn = prior rn +1
;

select &cols from clarity.clarity_ser;
...