A Technical Resource for Microsoft .NET & Oracle
(Architect @IBM India Pvt, Ltd)
Monday, May 10, 2010
Oracle: Generate a CSV output of your SQL Query
Recently I have been asked to create a function that could generate a comma separated (CSV) output of a given SQL query. Here I am sharing the source code of that function with a hope that it could be useful to someone for sure. In order to achieve this I am using DBMS_SQL packages.
Dynamic SQL lets you create a procedure that operates on a table whose name is not known until runtime. Additionally, DBMS_SQL enables you to parse any data manipulation language (DML) or data definition language (DDL) statement. Therefore, you can parse DDL statements directly using PL/SQL.
NOTE: Before you start using DBMS_SQL, you need to make sure that it is installed and that the appropriate users have access to this package.
For more information on DBMS_SQL package: http://download.oracle.com/docs/cd/B10501_01/appdev.920/a96612/d_sql.htm
FUNCTION generate_csv( par_query CLOB ,
par_include_header NUMBER DEFAULT 1
) RETURN CLOB
IS
l_cursor PLS_INTEGER;_rows PLS_INTEGER;
l_col_cnt PLS_INTEGER;
l_desc_tab DBMS_SQL.desc_tab;
l_buffer CLOB;
l_row_data CLOB ;
BEGIN
l_cursor := DBMS_SQL.open_cursor;
DBMS_SQL.parse(l_cursor, par_query , DBMS_SQL.native);
DBMS_SQL.describe_columns (l_cursor, l_col_cnt, l_desc_tab);
FOR i IN 1 .. l_col_cnt LOOP
DBMS_SQL.define_column(l_cursor, i, l_buffer);
END LOOP;
l_rows := DBMS_SQL.execute(l_cursor);
-- Adding column header.
IF par_include_header = 1 THEN FOR i IN 1 .. l_col_cnt LOOP
l_buffer := l_desc_tab(i).col_name ;
l_row_data := l_row_data || l_buffer ;
IF i <> l_col_cnt THEN row_data := l_row_data || ',';
END IF ;
END LOOP;l_row_data := l_row_data || CHR(13) ; --Add carriage return
END IF;
-- Appending data.LOOPEXIT WHEN DBMS_SQL.fetch_rows(l_cursor) = 0;
FOR i IN 1 .. l_col_cnt LOOP --Loop through all columns DBMS_SQL.COLUMN_VALUE(l_cursor, i, l_buffer);
l_row_data := l_row_data || l_buffer ;
IF i <> l_col_cnt THEN
l_row_data := l_row_data || ',';
END IF ;
END LOOP;
l_row_data := l_row_data || CHR(13) ; --Add carriage return
END LOOP;RETURN l_row_data;
EXCEPTION
WHEN OTHERS THEN
IF DBMS_SQL.is_open(l_cursor) THEN
DBMS_SQL.close_cursor(l_cursor);
END IF;
RETURN 'Error :' || SQLERRM || CHR(13) || DBMS_UTILITY.FORMAT_ERROR_BACKTRACE ;
END generate_csv ;
Example:
SELECT generate_csv('SELECT object_id,object_name,object_type FROM user_objects WHERE ROWNUM <=20') data FROM DUAL;
Result :
OBJECT_ID,OBJECT_NAME,OBJECT_TYPE
74516,AA_CU_VW,VIEW
74517,AA_LC_VW,VIEW
89245,AA_PO,VIEW
89246,AA_PO1,VIEW
74336,ACTIVITY_ROLLFORWARD_SUMMARY,VIEW
73833,APPSCREENS,TABLE
73834,APPSCREENSSCREENNAME,INDEX
73835,APPUSERS,TABLE
73836,APPUSERSUSERNAME,INDEX
197790,BANK,TABLE
197791,BANKBANKNUM,INDEX
202243,BENEY,TABLE
202244,BENEYBENEYACCT,INDEX
195188,BIN$f9BuwtUHsjDgQ6wQEUKyMA==$0,INDEX
195189,BIN$f9BuwtUIsjDgQ6wQEUKyMA==$0,INDEX
195190,BIN$f9BuwtUJsjDgQ6wQEUKyMA==$0,INDEX
195191,BIN$f9BuwtUKsjDgQ6wQEUKyMA==$0,INDEX
195192,BIN$f9BuwtULsjDgQ6wQEUKyMA==$0,INDEX
195193,BIN$f9BuwtUMsjDgQ6wQEUKyMA==$0,INDEX
195194,BIN$f9BuwtUNsjDgQ6wQEUKyMA==$0,INDEX
No comments:
Post a Comment