2011-08-12 22 views
7

Chciałbym móc używać tabel systemowych (w tym przypadku Oracle) do kierowania, które pola są używane w instrukcji SELECT. Coś takiego:Dynamicznie wybierz kolumny, które będą używane w instrukcji SELECT

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

Ta składnia nie działa, ponieważ podzapytanie zwraca wiele wierszy zamiast jednego wiersza z wieloma kolumnami.

Czy możliwe jest dynamiczne generowanie instrukcji SQL poprzez zapytanie do informacji o schemacie tabeli w celu wybrania tylko niektórych kolumn?

** edycja ** Wykonaj tę czynność bez użycia funkcji lub procedury, jeśli to możliwe.

+1

I edycji posta, aby dodać pytanie, które powinno być dość nadzieją odpowiedzialny. Chociaż ludzie mogą sugerować to, o co prosisz, pomyślałem, że najlepiej jest być wyraźnym. –

+0

Masz na myśli bez konieczności używania języka programowania do konstruowania instrukcji SQL? – paulmorriss

+0

Jaki jest tego powód? –

Odpowiedz

2

Nie, nie można dynamicznie określać listy kolumn w SQL. Aby uruchomić pierwsze zapytanie, musisz użyć języka proceduralnego, użyj go do skonstruowania drugiego zapytania, a następnie uruchom drugie zapytanie.

6

Można to zrobić:

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; 
1

Można użyć dynamicznego SQL. Utwórz funkcję, która pobiera nazwę tabeli, właściciela, typ danych, wykonuje zapytanie wewnętrzne i zwraca rozdzielaną przecinkami listę nazw kolumn lub tabelę tablic, jeśli wolisz. Następnie skonstruuj zapytanie zewnętrzne i wykonaj je przy pomocy 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; 
/

Jeśli funkcja zwraca listę oddzielonych przecinkami można go inline:

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

Wprawdzie to dawno grałem z wyroczni więc może być trochę off, ale jestem dość na pewno jest to wykonalne.

1

W SQLPLUS można to zrobić:

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; 
+0

Czy to działałoby w programistach SQL firmy Oracle? – craig

+0

@ craig, nie sądzę, ponieważ nie sądzę, że polecenie COLUMN jest obsługiwana. Może mieć inny sposób na zrobienie tego. –

Powiązane problemy