Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pl/SQL- Get column names from a query

Tags:

sql

oracle

plsql

I'm using Pl/SQL with Oracle Database 11g.

I'm writing a function that takes in a select statement as a parameter (varchar2). The function uses a for loop to go over the rows and apply formatting to specific columns, and output the whole thing. Basically, I need some way to get the column names so that I can display them at the top. I know there are various ways to do this for tables, but since this query is passed in, all columns may not have been selected, aliases may have been used, etc.

Is there a way I can select out the column names from this query?
Ideally something like:
select column_names from (subquery)

like image 672
bobroxsox Avatar asked Aug 02 '13 14:08

bobroxsox


People also ask

How do I get a list of column names in PL SQL?

Best AnswerSELECT owner, column_nameFROM all_tab_columnsWHERE table_name = 'YOUR_TABLE_HERE'ORDER BY owner, table_name; You may wnat to add "AND owner =..." as the above query will return all tables/views that have the table_name 'YOUR_TABLE_HERE'. i.e. more than one owner can have a table/view of the same name.

How do I get a list of all columns in a database?

You can use following query to list all columns or search columns across tables in a database. USE AdventureWorks GO SELECT t.name AS table_name, SCHEMA_NAME(schema_id) AS schema_name, c.name AS column_name FROM sys. tables AS t INNER JOIN sys. columns c ON t.


2 Answers

I believe you can use DESCRIBE_COLUMNS to do this. Just pass in the cursor and the other required parameters.

http://docs.oracle.com/cd/B19306_01/appdev.102/b14258/d_sql.htm#i1026120

declare
    v_sql varchar2(32767) := 'select 1 column1, 2 column2 from dual';
    v_cursor_id integer;
    v_col_cnt integer;
    v_columns dbms_sql.desc_tab;
begin
    v_cursor_id := dbms_sql.open_cursor;
    dbms_sql.parse(v_cursor_id, v_sql, dbms_sql.native);
    dbms_sql.describe_columns(v_cursor_id, v_col_cnt, v_columns);

    for i in 1 .. v_columns.count loop
        dbms_output.put_line(v_columns(i).col_name);
    end loop;

    dbms_sql.close_cursor(v_cursor_id);
exception when others then
    dbms_sql.close_cursor(v_cursor_id);
    raise;
end;
/

Output:
COLUMN1
COLUMN2
like image 53
dseibert Avatar answered Sep 24 '22 01:09

dseibert


Based on dseibert's answer, I created function for usage:

create type cols_name
    as table of varchar2(32767)
/

CREATE OR REPLACE FUNCTION GET_COLUMNS_NAME(p_selectQuery IN VARCHAR2) RETURN cols_name PIPELINED IS
    v_cursor_id integer;
    v_col_cnt integer;
    v_columns dbms_sql.desc_tab;
begin
    v_cursor_id := dbms_sql.open_cursor;
    dbms_sql.parse(v_cursor_id, p_selectQuery, dbms_sql.native);
    dbms_sql.describe_columns(v_cursor_id, v_col_cnt, v_columns);

    for i in 1 .. v_columns.count loop
        pipe row(v_columns(i).col_name);
    end loop;

    dbms_sql.close_cursor(v_cursor_id);
    return;
exception when others then
    dbms_sql.close_cursor(v_cursor_id);
    raise;
end;
/

Using it:

select * from TABLE(get_columns_name('select 1 column1, 2 column2 from dual'));

Results:

**COLUMN_VALUE**
COLUMN1
COLUMN2
like image 40
Phi Avatar answered Sep 23 '22 01:09

Phi