我正在使用Oracle 12c。
我有一个雇员表,看起来像这样:
EMPLOYEE_NAME | DEPARTMENT_NAME
--------------|----------------
Jim | Sales
Barb | Marketing
Paul | Sales
Frank | Sales
Cindy | Accounting
Carl | Marketing
... and so on ...
如果PL / SQL允许,我想做这样的事情:
FOREACH dept IN (SELECT DISTINCT DEPARTMENT_NAME FROM EMPOLYEES) DO
SPOOL 'list_' || :dept || '.txt';
SELECT EMPLOYEE_NAME
FROM EMPLOYEES
WHERE DEPARTMENT_NAME = :dept;
SPOOL OFF;
DONE;
这将导致一组文件如下:
list_Sales.txt:
Jim
Paul
Frank
list_Marketing.txt
Barb
Carl
list_Accounting.txt
Cindy
...等等...
关于如何实现此目标的任何想法?
谢谢。
答案 0 :(得分:3)
spool
是一个客户端命令,在PL / SQL块中没有任何意义;并且您无法从PL / SQL向客户端计算机上的文件写入文件。您可以使用utl_file
写到服务器(如@kfinity所建议,@BarbarosÖzhan所演示的那样),但这可能不适合您的情况。
如果您要坚持后台处理到客户端计算机,并且不想将输出后处理成多个文件(如@KaushikNayak建议),则可以使用其他级别的后台处理来生成脚本,例如:
spool temp_script.sql
select distinct 'spool list_' || department_name || '.txt' || chr(10)
|| 'select employee_name from employees where department_name = '''
|| department_name || ''' order by employee_name;' || chr(10)
from employees;
spool off
@temp_script.sql
作为使用默认HR模式的employee和department表的更详尽的示例:
set pages 0
set lines 500
set trimspool on
set feedback off
set echo off
spool temp_script.sql
prompt set pages 0
prompt set lines 500
prompt set trimspool on
prompt set feedback off
prompt set echo off
select distinct 'spool list_' || department_name || '.txt' || chr(10)
|| 'select employee_name from employees where department_name = '''
|| department_name || ''' order by employee_name;' || chr(10)
from employees;
prompt spool off
spool off
@temp_script.sql
在这种情况下,temp_script.sql
的内容最终类似于:
set pages 0
set lines 500
set trimspool on
set feedback off
set echo off
spool list_Administration.txt
select first_name || ' ' || last_name from employees where department_id = 10 order by last_name, first_name;
spool list_Marketing.txt
select first_name || ' ' || last_name from employees where department_id = 20 order by last_name, first_name;
spool list_Purchasing.txt
select first_name || ' ' || last_name from employees where department_id = 30 order by last_name, first_name;
...
spool list_Payroll.txt
select first_name || ' ' || last_name from employees where department_id = 270 order by last_name, first_name;
spool off
,每个部门一个文件,例如list_Accounting.txt
:
William Gietz
Shelley Higgins
和list_Executive.txt
:
Lex De Haan
Steven King
Neena Kochhar
等在此示例中,有几个空文件,但是如果我使初始查询联接两个表,则不会。当您查询单个表时也不会发生。
答案 1 :(得分:1)
您可以使用
utl_file
软件包以生成@kfinity指出的生成操作系统流文件
1)在Oracle中创建要写入文件的目录。该目录/路径必须可以从数据库服务器访问和写入。
CREATE DIRECTORY UTL_FILE_DIR AS '/scratch/data/file_data';
2) 现在获得对该目录的读写权限。
grant READ, WRITE on UTL_FILE_DIR to <reporting_user>;
3)将生成文件的代码。
declare
v_outfile utl_file.file_type;
v_file varchar2(100);
v_path varchar2(100) := 'UTL_FILE_DIR';
-- alias for the directory where your text files generated at OS.
begin
for d in ( select distinct department_name as dept from employees )
loop
v_file := 'list_'||d.dept||'.txt';
v_outfile := utl_file.fopen(v_path, v_file, 'w');
for c in ( select employee_name from employees where department_name = d.dept )
loop
begin
utl_file.put_line(v_outfile,c.employee_name);
end;
end loop;
utl_file.fclose(v_outfile);
end loop;
end;