2011-08-12 50 views
7

我希望能夠使用系統表(本例中爲Oracle)來驅動SELECT語句中使用的字段。例如:動態選擇要在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語句以僅選擇某些列?

**編輯** 如果可能,請不要使用函數或過程。

+1

我編輯您的文章添加一個問題,應該有希望是相當交代。雖然人們可以暗示你在問什麼,但我認爲最好是明確的。 –

+0

你的意思是不借助編程語言來構造SQL語句嗎? – paulmorriss

+0

這樣做的原因是什麼? –

回答

2

不,不可能在SQL中動態指定列列表。您需要使用過程語言來運行第一個查詢,使用它來構造第二個查詢,然後運行第二個查詢。

6

你可以這樣做:

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

你可以使用動態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打得那麼我可能有點過,但我敢確定這是相當可行的。

1

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

這將在Oracle的SQL Developer中工作嗎? – craig

+0

@craig,我不這麼認爲,因爲我不認爲在那裏支持COLUMN命令。它可能有其他的方式。 –