【问题标题】:How to load every record of a table into separate file?如何将表的每条记录加载到单独的文件中?
【发布时间】:2017-11-29 05:33:09
【问题描述】:

例子:如果下面的查询

Select * from emp;

获取了 30 条记录.. 输出为:

EMPNO   ENAME    JOB        MGR     HIREDATE    SAL     COMM  DEPTNO

7499     ALLEN   SALESMAN    7698    20-FEB-81   1600    300    30

7521     WARD    SALESMAN    7698    22-FEB-81   1250    500    30

.....(more 28 records)........

每条记录都应保存在一个单独的文件中,文件名为“Empno.Ename”

【问题讨论】:

  • 问题被标记为linuxunixksh,所以我发布了awk 解决方案;如果解决方案必须完全在 (PL/)SQL 中执行,则应更新帖子以说明这一点(并删除linux/unix/ksh 标签)

标签: linux oracle unix plsql ksh


【解决方案1】:

假设:

  • 忽略列标题的第一行
  • 给定emp 记录的所有数据都位于一行中(例如,数据中没有嵌入回车,数据不跨越多行)
  • 测试数据在一个名为emp.raw的文件中
  • awk 是一个有效选项(OP 被标记为 linuxunixksh

示例emp.raw的内容:

EMPNO   ENAME    JOB         MGR     HIREDATE    SAL     COMM   DEPTNO
7499     ALLEN   SALESMAN    7698    20-FEB-81   1600    300    30
7521     WARD    SALESMAN    7698    22-FEB-81   1250    500    30

单行awk解决方案:

$ awk '!/^EMPNO/ { print > $1"."$2}' emp.raw

结果:

$ ls -1
7499.ALLEN
7521.WARD
emp.raw

$ for f in 7*
> do
> echo "+++++++++++++ $f"
> cat $f
> done
+++++++++++++ 7499.ALLEN
7499     ALLEN   SALESMAN    7698    20-FEB-81   1600    300    30
+++++++++++++ 7521.WARD
7521     WARD    SALESMAN    7698    22-FEB-81   1250    500    30

【讨论】:

  • 数据来自数据库表而不是文件:)
  • @SudiptaMondal:当然,数据来自数据库表,但在某些时候可以将数据写入文件;或者,select 的输出可以通过管道传输到awk 解决方案中;如果 OP 想要一个纯粹的 (PL/)SQL 解决方案,那么应该将其添加到帖子中
【解决方案2】:

您需要执行以下操作

  1. 创建 n 个文件,因为您希望将每条记录保存在自己的每个文件中
  2. 遍历所有记录
  3. 将每条记录的数据保存在自己的文件中并关闭文件

    DECLARE
    file_name VARCHAR2(30) := NULL;
    out_file UTL_FILE.file_type;
    dir_path VARCHAR2(100) := NULL; -- Give the directory alias, where you want to store file
    BEGIN
    
    FOR record IN
    (
        SELECT *
        FROM emp
    )
    LOOP
        file_name := TO_CHAR(record.empno) || '.' || TO_CHAR(record.ename);
        out_file  := UTL_FILE.fopen (i_chr_dir_path, file_name, 'W', 32767);
        UTL_FILE.put_line(out_file, record.empno || ',' || record.ename || ',' || record.job
        -- more fields
        );
    
        IF UTL_FILE.is_open (out_file) THEN
            UTL_FILE.fclose (out_file);
    
        END IF;
    
    END LOOP;
    END;
    

【讨论】:

  • 您现在可以更新它以反映文件名的格式为“Empno.Ename”的附加要求
  • @TonyAndrews ?
【解决方案3】:

这是其中一种选择。您只需为表中的每一行生成一个带有 select 语句的文件,然后执行它。

这里我有一个名为T1 的表,其中包含 7 条记录。该文件(我们将其命名为tabletofiles.sql)如下所示:

set feedback off;
set termout off;
set heading off;
set verify off;
set sqlblanklines on;

# temp file with statements
spool /tmp/tmpfile.sql

# specify column names you want to fetch explicitly
select 'spool /tmp/file_' || to_char(rownum) || ';' || chr(10) ||
       'select c1
            from (select q.*
                      , rownum as rn
                    from &1 q )
           where rn = ' || to_number(rownum) || ';' ||
       chr(10) || 'spool off;'
  from &1;

spool off;

@@tmpfile.sql
#clean up after ourselfs
!rm -I /tmp/tmpfile.sql

将表名作为参数传入

SQL> @/tmp/tabletofiles.sql t1

执行完成后,tmpfile.sql 包含以下内容:

spool /tmp/file_1;
select c1
            from (select q.*
                      , rownum as rn
                    from t1 q )
           where rn = 1;
spool off;

spool /tmp/file_2;
select c1
            from (select q.*
                      , rownum as rn
                    from t1 q )

           where rn = 2;
spool off;

...

每个select 语句的结果被假脱机到不同的文件中。

这是我们的最终文件:

 82 Jun 26 11:28 file_1.lst
 82 Jun 26 11:28 file_2.lst
 82 Jun 26 11:28 file_3.lst
 82 Jun 26 11:28 file_4.lst
 82 Jun 26 11:28 file_5.lst
 82 Jun 26 11:28 file_6.lst
 82 Jun 26 11:28 file_7.lst

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-06
    • 2019-02-14
    • 1970-01-01
    • 2013-08-13
    • 1970-01-01
    • 2015-12-09
    • 1970-01-01
    • 2011-10-20
    相关资源
    最近更新 更多