Plsql 使用PL/SQL过程提取Oracle模式的所有表

Plsql 使用PL/SQL过程提取Oracle模式的所有表,plsql,Plsql,我使用PL/SQL过程将特定模式的Oracle表提取为csv格式。我通过以下命令执行该过程: exec dump_table_to_csv ( 'schema.tablename', 'directory', 'tablename.csv'); CREATE DIRECTORY <directory_name> AS '<operating_system_path>'; 使用以下命令创建目录: exec dump_table_to_csv ( 'schema.ta

我使用PL/SQL过程将特定模式的Oracle表提取为csv格式。我通过以下命令执行该过程:

exec dump_table_to_csv ( 'schema.tablename',  'directory',  'tablename.csv');
CREATE DIRECTORY <directory_name> AS '<operating_system_path>';
使用以下命令创建目录:

exec dump_table_to_csv ( 'schema.tablename',  'directory',  'tablename.csv');
CREATE DIRECTORY <directory_name> AS '<operating_system_path>';

但是,当表格增加时,此过程会花费太长时间。我的问题是如何修改代码,以便处理模式表列表并将其放入文件中,然后该过程将处理文件中列出的所有表?如果这种方法不快速或不可行,那么还有什么其他方法可以在一次运行中处理提取,而不必对每个表执行该过程?

我猜您的性能影响来自这里的逐行处理

       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 || l_columnValue );
               l_separator := ',';
           end loop;
           utl_file.new_line( l_output );
       end loop;
我会鼓励你考虑让它更加基于场景,它会提高速度。在旧的互联网站上快速搜索发现了这一点。作者在一个特定的sql语句中处理所有的列分隔

我理解如果你想留下这个泛型,这样你就可以运行所有的表。如果是这样,我鼓励您考虑使用一些脚本,而不仅仅是PLSQL。这里有几个例子。。。这里有一个很好的起点:

。。。它们都处理到excel的导出,但您可以轻松地转换为csv

最后,如果这只是一个偶然的事情,你可能想考虑用这个(免费)工具抓取SqDeReald-你可以从一个简单的右击菜单导出任何表格。 希望这有助于

还有什么其他方法可以在一次运行中处理提取,而不必为每个表执行该过程

您可以按如下方式自动运行当前过程:

create or replace procedure dump_table_to_csv( p_tname in varchar2,
                                                   p_dir   in varchar2,
                                                   p_filename in varchar2 )
    is
        l_output        utl_file.file_type;
        l_theCursor     integer default dbms_sql.open_cursor;
        l_columnValue   varchar2(4000);
        l_status        integer;
        l_query         varchar2(1000)
                       default 'select * from ' || p_tname;
       l_colCnt        number := 0;
       l_separator     varchar2(1);
       l_descTbl       dbms_sql.desc_tab;
   begin
       l_output := utl_file.fopen( p_dir, p_filename, 'w', 32760);
       execute immediate 'alter session set nls_date_format=''dd-mon-yyyy hh24:mi:ss'' ';

       dbms_sql.parse(  l_theCursor,  l_query, dbms_sql.native );
       dbms_sql.describe_columns( l_theCursor, l_colCnt, l_descTbl );

       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 );

       l_status := dbms_sql.execute(l_theCursor);

       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 || l_columnValue );
               l_separator := ',';
           end loop;
           utl_file.new_line( l_output );
       end loop;
       dbms_sql.close_cursor(l_theCursor);
       utl_file.fclose( l_output );

       execute immediate 'alter session set nls_date_format=''dd-MON-yy'' ';
   exception
       when others then
           execute immediate 'alter session set nls_date_format=''dd-MON-yy'' ';
           raise;
   end;
   /
begin
   for r in (select table_name from all_tables where owner = 'SCHEMA') loop
      dump_table_to_csv 
         ('schema.'||r.table_name, 'directory', r.table_name||'.csv');
   end loop;
end;
或者,您可以重新编写要作为以下方式运行的过程:

exec dump_schema_to_csvs ('schema', 'directory')
i、 e.将我的第一个示例中的FOR循环放入过程中


但是,这两种方法的运行速度都不可能比当前方法快。

看看DBMS_作业-这将允许您提交每个表提取作为后台作业并行运行,直到您的机器资源

所以你可以从一个程序开始

begin
   for table_rec in (select table_name from user_tables) loop
      submit_dump_to_csv(
           schema_var||'.'||table_rec.table_name,
           'directory',
           table_rec.table_name||'.csv);
   end loop;
end;
SET HEADING OFF PAGES 0 
SET COLSEP ","
SPOOL tablename.csv
SELECT * FROM tablename
SPOOL OFF
其中submit_dump_to_csv将调用dump_table_to_csv打包,并将其传递给DBMS_作业

您可能希望在一个表中记录提交和完成的作业,并可能在任务完成时使用DBMS_MAIL或DBMS_SMTP发送电子邮件,因为作业将在服务器上的后台执行

这不会加快任何单个表的提取速度,只允许并行提取不同的表

为了加快单个提取的速度,我将更改您的代码,这样就不用使用方法4 dynamic SQL提取所有列,然后在pl/SQL中连接它们,而是使用所有的\u TAB\u列来构建一个返回单个连接字符串的l\u查询版本

然后,您应该能够使用更简单的本机动态SQL语法在动态查询上循环,为返回的每一行调用UTL_文件

或者

如果使用SQL*Plus,可以执行以下操作

begin
   for table_rec in (select table_name from user_tables) loop
      submit_dump_to_csv(
           schema_var||'.'||table_rec.table_name,
           'directory',
           table_rec.table_name||'.csv);
   end loop;
end;
SET HEADING OFF PAGES 0 
SET COLSEP ","
SPOOL tablename.csv
SELECT * FROM tablename
SPOOL OFF
如果您对tablename-&tablename使用SQLPlus变量,这将适用于任何表,并且您可以轻松地编写另一个由user_tables驱动的脚本,为要提取的每个表调用该脚本(使用shell脚本,或者编写SQLPlus,对输出文件进行假脱机,然后调用假脱机的输出文件)