登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

轨迹

做自己忠实的记录者

 
 
 
 
 

日志

 
 

Oracle 查询结果导出为csv格式  

2011-07-19 23:51:35|  分类: 工作学习 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

Oracle 查询结果导出为csv格式

目录

.. 1

预备知识:... 2

SQL_TO_CSV 存储过程... 2

一个表的查询结果导出... 4

方案一:用数组存放表名... 4

方案二:用文件存表名... 5

 

 

oracle plussql语句导出查询结果,导出文件格式为csv格式

预备知识:

1.   Oracle的存储过程知识

2.   Oracle Utl_filedirectory知识

3.   隐含知识点:plussql中表名用变量代替如何实现

假设要执行查询语句: select * from student;  这里想将student 用变量代理,那怎么处理呢?

定义一个变量 v_tablename

student表名赋值给变量 v_tablename:=student

拼接sql语句: v_sql=’select * from ’||v_tablename;

执行sql语句:execute immediate v_sql;

所有代码块如下

declare

  v_tablename varchar2(100);

  v_sql varchar2(100);

begin

  v_tablename:='student';

  v_sql:='select * from '||v_tablename;

  execute immediate v_sql;

 end;

 

SQL_TO_CSV 存储过程

从网络上找来一个存储过程,实现了将查询结果导出生成csv文件,

存储过程代码如下  

CREATE OR REPLACE PROCEDURE SQL_TO_CSV

    (

        P_QUERY IN VARCHAR2,                        -- PLSQL

        P_DIR IN VARCHAR2,                          -- 导出的文件放置目录

        P_FILENAME IN VARCHAR2                      -- CSV

)

IS

        L_OUTPUT UTL_FILE.FILE_TYPE;

        L_THECURSOR INTEGER DEFAULT DBMS_SQL.OPEN_CURSOR;

        L_COLUMNVALUE VARCHAR2(4000);

        L_STATUS INTEGER;

        L_COLCNT NUMBER := 0;

        L_SEPARATOR VARCHAR2(1);

        L_DESCTBL DBMS_SQL.DESC_TAB;

        P_MAX_LINESIZE NUMBER := 32000;

BEGIN

        --OPEN FILE

        L_OUTPUT := UTL_FILE.FOPEN(P_DIR, P_FILENAME, ‘W’, P_MAX_LINESIZE);

 

        --DEFINE DATE FORMAT

        EXECUTE IMMEDIATE ‘ALTER SESSION SET NLS_DATE_FORMAT=’’YYYY-MM-DD HH24:MI:SS’’’;

 

        --OPEN CURSOR

        DBMS_SQL.PARSE( L_THECURSOR, P_QUERY, DBMS_SQL.NATIVE );

        DBMS_SQL.DESCRIBE_COLUMNS( L_THECURSOR, L_COLCNT, L_DESCTBL );

 

        --DUMP TABLE COLUMN NAME

        FOR I IN 1 .. L_COLCNT LOOP

            UTL_FILE.PUT( L_OUTPUT, L_SEPARATOR || ‘”’ || L_DESCTBL(I).COL_NAME || ‘”’ );

            DBMS_SQL.DEFINE_COLUMN( L_THECURSOR, I, L_COLUMNVALUE, 4000 );

            L_SEPARATOR := ‘,’;

        END LOOP;

        UTL_FILE.NEW_LINE( L_OUTPUT );

 

        --EXECUTE THE QUERY STATEMENT

        L_STATUS := DBMS_SQL.EXECUTE(L_THECURSOR);

 

        --DUMP TABLE COLUMN VALUE

        WHILE ( DBMS_SQL.FETCH_ROWS(L_THECURSOR) > 0 ) LOOP

            L_SEPARATOR := ‘’;

            FOR I IN 1 .. L_COLCNT LOOP

                DBMS_SQL.COLUMN_VALUE( L_THECURSOR, I, L_COLUMNVALUE );

                UTL_FILE.PUT( L_OUTPUT, L_SEPARATOR || ‘”’ ||

                TRIM(BOTH ‘ ‘ FROM REPLACE(L_COLUMNVALUE,’”’,’””’)) || ‘”’);

                L_SEPARATOR := ‘,’;

            END LOOP;

            UTL_FILE.NEW_LINE( L_OUTPUT );

        END LOOP;

 

        --CLOSE CURSOR

        DBMS_SQL.CLOSE_CURSOR(L_THECURSOR);

 

        --CLOSE FILE

        UTL_FILE.FCLOSE( L_OUTPUT );

EXCEPTION

        WHEN OTHERS THEN

        RAISE;

END;

上述存储过程 SQL_TO_CSV 需要了解oracle中的utl_fieldirectory 的知识

下面调用  SQL_TO_CSV 存储过程的 前提就是定义一个directory

定义语句如下: create or replace directory MYDIR as 'c:\';

一个表的查询结果导出

下面就开始调用 存储过程 SQL_TO_CSV,将 select * from cus_event 的查询结果,导出为example.csv并放在MYDIR所代表的C:\

declare

 fhandle utl_file.file_type;

 begin

    sql_to_csv('select * from cus_event ','MYDIR','example.csv');

 end;

【评论】上面是导出一个表,查询语句可以直接写,那么如果导出是多个表呢,那又该如果操作呢。既然是多个表,显然我们就要拼接sql语句,是sql语句动态变化,且导出的文件名也要动态变化。有两种方案,一将表名放在数组中,逐个调用;二是将表名放在文件中,逐个读取

方案一:用数组存放表名

从数组中取出表名,拼接sql语句,构造导出的csv文件名 

declare

 v_tablename varchar2(100);  -----用来存表名

 v_sql varchar2(1000);       -----用来存组合起来查询的sql语句

 type my_email is varray(200) of varchar2(40);--定义数组

 tables_arr my_email;--定义一个数组变量

 v_filename varchar2(100);  ---用来存放构造的文件名

begin

 tables_arr:=my_email('cus_grp_info','cus_event');-- 给数组变量赋值

 

 for i in 1..2 loop

 dbms_output.put_line(tables_arr(i));

  v_tablename:=tables_arr(i);

  v_sql:='select * from '||v_tablename;  -----构造查询的sql语句

           dbms_output.put_line(v_sql);

  v_filename:=v_tablename||'.csv';  -----构造查询导出后的文件名

           dbms_output.put_line(v_filename);

 sql_to_csv(v_sql,'MYDIR',v_filename); ----调用存储过程,将查询结果导出  这里是核心部分

 end loop;

 end;

【评论】上述方案简单,但必须将表名手动放入数组中,例子中只到处两个表cus_grp_info,cus_event,但如果我们这里有上百张表,显然这种方法不太方便。我们通过会将表名存放在文件中。执行时从文件中读取表名,这样再多的表我们也能操作,且表的内容还可以随时方便的改变

方案二:用文件存表名

从文件中取出表名,拼接sql语句,构造导出的csv文件名 

declare

 v_tablename varchar2(100);  -----用来存表名

 v_sql varchar2(1000);       -----用来存组合起来查询的sql语句

 v_filename varchar2(100);  ---用来存放构造的文件名

 fhandle utl_file.file_type; -- 文件句柄

begin

  fhandle:=utl_file.fopen('MYDIR','tablelist.txt','r');   --获得tablelist的文件句柄

  ---这里tablelist.txt 就存放中将要查询的表的表名,txt文件放在MYDIR代表的c:\ 目录下

  loop

  begin

    utl_file.get_line(fhandle,v_tablename); ---从文件中一条一条读取表名,并存放在v_tablename

         dbms_output.put_line(v_tablename);

    v_sql:='select * from '||v_tablename;  ---拼接查询语句

         dbms_output.put_line(v_sql) ;

    v_filename:=v_tablename||'.csv';       ---构造导出的csv文件名

         dbms_output.put_line(v_filename); 

    exception

       when no_data_found then               ----直到文件末尾,即找不到数据了再停止

       exit;

    end ;

  sql_to_csv(v_sql,'MYDIR',v_filename); ----调用存储过程,将查询结果导出。这里核心部分

 end loop;

 end;

 

 

 

  评论这张
 
阅读(10231)| 评论(1)

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018