动态选择要在SELECT语句中使用的列

时间:2011-08-12 14:27:54

标签: sql oracle oracle10g subquery

我希望能够使用系统表(在本例中为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 个答案:

答案 0 :(得分:7)

你可以这样做:

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 :(得分:2)

不,不可能在SQL中动态指定列列表。您需要使用过程语言来运行第一个查询,使用它来构造第二个查询,然后运行第二个查询。

答案 2 :(得分: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以来已经有很长一段时间了,所以我可能会有点休息,但我很确定这是非常可行的。

答案 3 :(得分: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;