Dynamically select the columns to be used in a SELECT statement

可紊 提交于 2020-01-13 09:01:53

问题


I would love to be able to use the system tables (Oracle in this case) to drive which fields are used in a SELECT statement. Something like:

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

This syntax doesn't work, as the subquery returns multiple rows, instead of one row with multiple columns.

Is it possible to generate a SQL statement dynamically by querying the table schema information in order to select only certain columns?

** edit ** Do this without using a function or procedure, if possible.


回答1:


You can do this:

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:


No, it's not possible to specify a column list dynamically in SQL. You'll need to use a procedural language to run the first query, use that to construct a second query, then run the second query.




回答3:


You could use dynamic SQL. Create a function that takes the table name, owner, data type, executes the inner query and returns a comma-separated list of column names, or an array table if you prefer. Then construct the outer query and execute it with 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;
/

If your function returns a comma-separated list you can inline it:

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

Admittedly it's a long time since I played with oracle so I may be a bit off but I'm pretty sure this is quite doable.




回答4:


In SQLPlus you could do this:

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;


来源:https://stackoverflow.com/questions/7041553/dynamically-select-the-columns-to-be-used-in-a-select-statement

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!