在sqlplus中为Oracle数据库假脱机

时间:2018-01-21 14:40:21

标签: database oracle oracle11g oracle-sqldeveloper sqlplus

我的.sql文件有100个Oracle查询,所以在假脱机时,所有100个查询的结果都被写入一个文件,但是我想要为每个查询创建一个文件,对于100个查询应该有100个文件的特定查询结果。

2 个答案:

答案 0 :(得分:0)

难道不是很明显吗?在SELECT之前设置SPOOL,在它之后设置SPOOL OFF。因为每个SPOOL都应该拥有自己的文件名,因此需要输入很多内容。

也许您可以创建一个可以为您完成此操作的脚本。使用UTL_FILE,您可以逐行读取并创建通用假脱机文件名(例如Q1.TXT,Q2.TXT,...),将所有内容写回新的大型SQL文件。

这是一个例子。我的LARGE.SQL包含几个SELECT语句:

select count(*) from tab;

select department_name from departments
where department_id < 100;

select sysdate 
from dual;

以下脚本创建了一个LARGE_W.SQL,它在每个SELECT:

之间插入了SPOOL命令
SQL> declare
  2    l_file_r utl_file.file_type;  -- read large.sql
  3    l_file_w utl_file.file_type;  -- write large_2.sql
  4    l_text   varchar2(32767);     -- read line by line
  5    i        number := 1;         -- counter
  6  begin
  7    l_file_r := utl_file.fopen('EXT_DIR', 'large.sql'  , 'r');
  8    l_file_w := utl_file.fopen('EXT_DIR', 'large_w.sql', 'w');
  9
 10    begin
 11      loop
 12        utl_file.get_line(l_file_r, l_text, 32767);
 13
 14        if regexp_substr(trim(upper(l_text)), '^\w+') = 'SELECT' then
 15           -- the first word is SELECT
 16           utl_file.put_line(l_file_w, 'SPOOL OFF');
 17           utl_file.put_line(l_file_w, 'SPOOL Q' || to_char(i) ||'.TXT');
 18           i := i + 1;
 19        end if;
 20        -- lines different than 1st in this SELECT section
 21        utl_file.put_line(l_file_w, l_text);
 22      end loop;
 23    exception
 24      when no_data_found then
 25        utl_file.put_line(l_file_w, 'SPOOL OFF');
 26        null;
 27    end;
 28
 29    utl_file.fclose(l_file_r);
 30    utl_file.fclose(l_file_w);
 31  end;
 32  /

PL/SQL procedure successfully completed.

SQL>

结果是LARGE_W.SQL

SPOOL OFF
SPOOL Q1.TXT
select count(*) from tab;

SPOOL OFF
SPOOL Q2.TXT
select department_name from departments
where department_id < 100;

SPOOL OFF
SPOOL Q3.TXT
select sysdate 
from dual;
SPOOL OFF

运行时,会创建3个Qn.TXT文件:

SQL> @c:\temp\large_w.sql
not spooling currently

  COUNT(*)
----------
        40


DEPARTMENT_NAME
------------------------------
Administration
Marketing
Purchasing
Human Resources
Shipping
IT
Public Relations
Sales
Executive

9 rows selected.


SYSDATE
--------
16:09:42

SQL> $dir q*.txt
 Volume in drive C is OSDisk
 Volume Serial Number is 7635-F892

 Directory of C:\Users\lf

21.01.2018.  16:09               250 Q1.TXT
21.01.2018.  16:09               926 Q2.TXT
21.01.2018.  16:09               250 Q3.TXT
               3 File(s)          1.426 bytes
               0 Dir(s)  351.802.810.368 bytes free

SQL> $type q1.txt

  COUNT(*)
----------
        40


SQL>

这只是一个想法;当然,它可能需要改进(暗示:子查询),但现在你已经有了一些东西可以让你开始。

答案 1 :(得分:0)

如果在UNIX环境中运行sqlplus,可以使用像这样的awk命令将每个分号转换为具有唯一输出文件的假脱机命令。最后一个是额外的,你可以消除(或修改awk!)

awk '{gsub(";",";\nspool outputfile_"NR,$0);print}' yoursqlfile.sql >newsqlfile.sql

这会转换

等文件
spool file1
select 1 FROM DUAL;
select 2 FROM DUAL;
select 3 FROM
(select 4 FROM DUAL);
SELECT 5 FROM
DUAL;

TO

spool file1
select 1 FROM DUAL;
spool outputfile_2
select 2 FROM DUAL;
spool outputfile_3
select 3 FROM
(select 4 FROM DUAL);
spool outputfile_5
SELECT 5 FROM
DUAL;
spool outputfile_7