如何将 table 的每条记录加载到单独的文件中?
How to load every record of a table into separate file?
示例:如果下面的查询
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'
您需要执行以下操作
- 创建 n 个文件,因为您希望每条记录都保存在它自己的每个文件中
- 运行遍历所有记录
将每条记录的数据保存在自己的文件中并关闭文件
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;
这是其中一个选项。您只需为 table 中的每一行生成一个包含 select 语句的文件,然后执行它。
这里我有一个名为 T1
的 table,其中包含 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
将table名称作为参数传入
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
假设:
- 忽略列的第一行headers
- 给定
emp
记录的所有数据都位于一行中(例如,数据中没有嵌入回车符 returns,数据不跨越多行)
- 测试数据在名为
emp.raw
的文件中
awk
是一个有效选项(OP 标记为 linux
、unix
和 ksh
)
样本内容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
1行awk
解决方案:
$ awk '!/^EMPNO/ { print > "."}' 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
示例:如果下面的查询
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'
您需要执行以下操作
- 创建 n 个文件,因为您希望每条记录都保存在它自己的每个文件中
- 运行遍历所有记录
将每条记录的数据保存在自己的文件中并关闭文件
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;
这是其中一个选项。您只需为 table 中的每一行生成一个包含 select 语句的文件,然后执行它。
这里我有一个名为 T1
的 table,其中包含 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
将table名称作为参数传入
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
假设:
- 忽略列的第一行headers
- 给定
emp
记录的所有数据都位于一行中(例如,数据中没有嵌入回车符 returns,数据不跨越多行) - 测试数据在名为
emp.raw
的文件中
awk
是一个有效选项(OP 标记为linux
、unix
和ksh
)
样本内容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
1行awk
解决方案:
$ awk '!/^EMPNO/ { print > "."}' 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