oracle之spool详细使用总结(转)

今天实际项目中用到了spool,发现网上好多内容不是很全,自己摸索了好半天,现在总结一下。

一、通过spool 命令,可以将select 数据库的内容写到文件中,通过在sqlplus设置一些参数,使得按指定方式写到文件中

(1)常规使用spool方法,将set的一些命令和spool,select等放入.sql脚本中,然后再sqlplus中运行该脚本。以下为logmnr.sql脚本,

在sqlplus中执行@logmnr.sql就可以写入文件record3.txt中。不会再终端显示任何信息。但是,如果是在sqlplus中输入:

set termout off;

......

spool record3.txt

select ....... from .....;

spool off;

前面的设置是没有用的,还是会在终端中显示大量信息。

 1 set echo off;
 2 set heading off;
 3 set line 100;
 4 set long 2000000000;
 5 set longchunksize 255;
 6 set wra on;
 7 set newpage none;
 8 set pagesize 0;
 9 set numwidth 12;
10 set termout off;
11 set trimout on;
12 set trimspool on;
13 set feedback off;
14 set timing on;
15 execute dbms_logmnr.add_logfile(LogFileName=>'/oracle/app/oracle/logs/hrbfct_1_4156_748575599.arc',Options=>dbms_logmnr.new);
16 execute dbms_logmnr.add_logfile(LogFileName=>'/oracle/app/oracle/logs/hrbfct_2_6645_748575599.arc',Options=>dbms_logmnr.addfile);
17 execute dbms_logmnr.start_logmnr(DictFileName=>'/oracle/app/oracle/logs/dict.ora');
18 spool /oracle/app/oracle/logs/record3.txt;
19 select to_clob(sql_redo)||'|'||to_char(scn)||'|'||to_char(timestamp)||'|'||to_char(session_info)||'|'||to_char(table_name)||'|'||to_char(seg_owner)||'?'
20 from v$logmnr_contents;
21 spool off;
22 exit;

(2)那到底能否在shell脚本中运行还不显示这些信息呢,答案是有的。
例如

 1 #!/bin/ksh
 2 echo "set echo off;
 3 set heading off;
 4 set line 100;
 5 set long 2000000000;
 6 set longchunksize 255;
 7 set wra on;
 8 set newpage none;
 9 set pagesize 0;
10 set numwidth 12;
11 set termout off;
12 set trimout on;
13 set trimspool on;
14 set feedback off;
15 set timing on;
16 execute dbms_logmnr.add_logfile(LogFileName=>'/oracle/app/oracle/logs/hrbfct_1_4156_748575599.arc',Options=>dbms_logmnr.new);
17 execute dbms_logmnr.start_logmnr(DictFileName=>'/oracle/app/oracle/logs/dict.ora');
18 spool /oracle/app/oracle/logs/record3.txt;
19 select to_clob(sql_redo)||'|'||to_char(scn)||'|'||to_char(timestamp)||'|'||to_char(session_info)||'|'||to_char(table_name)||'|'||to_char(seg_owner)||'?'
20 from v\$logmnr_contents;
21 spool off;
22 " | sqlplus '/as sysdba'>/dev/null

这样就能利用shell脚本中执行spool方法,同时不会再终端中显示。注意,只有这种方法可以。

试过这种方法,结果证明是不行的。。。。  看着和上面echo进去很像,但事实就是不行,还是会显示大量的信息,两个!就是将中间内容发送到sqlplus中作为输入

 1 #!/bin/bash
 2 ......
 3 .....
 4 sqlplus oracleuser/user@SERVICE_NAME << !
 5 set ECHO off
 6 set heading off
 7 set pagesize 0
 8 set linesize 1000
 9 set term off
10 set trims on
11 set feedback off
12 spool $tmpfile
13 select owner||'.'||table_name||',' from all_tables where owner=upper('$owner_user') and table_name like 'DR%$exp_month%';
14 spool off
15 quit
16 !
17 .......

(2)spool通常会用到连接||,这里讲一下连接是怎么回事

SQL> SELECT LPAD('x',4000,'x') || LPAD('x',4000,'x')  || LPAD('x',4000,'x') FROM DUAL;
SELECT LPAD('x',4000,'x') || LPAD('x',4000,'x')  || LPAD('x',4000,'x') FROM DUAL
                                                                                                   *
ERROR at line 1:
ORA-01489: result of string concatenation is too long

这里简单先介绍下lpad和rpad是怎么回事:(l,r只是方向不同)rpad函数从右边对字符串使用指定的字符进行填充   rpad(string,padded_length,[pad_string])   string 表示:被填充的字符串   padded_length 表示:字符的长度,是返回的字符串的数量,如果这个数量比原字符串的长度要短,rpad函数将会把字符串截取成从左到右的n个字符;   pad_string 是个可选参数,这个字符串是要粘贴到string的右边,如果这个参数未写,lpad函数将会在string的右边粘贴空格。   例如:   rpad('tech', 7); 将返回'tech '   rpad('tech', 2); 将返回'te'   rpad('tech', 8, '0'); 将返回'tech0000'   rpad('tech on the net', 15, 'z'); 将返回 'tech on the net'   rpad('tech on the net', 16, 'z'); 将返回 'tech on the netz'

好了,现在回到上面的问题,为什么会出错呢,因为varchar2在oracle中,最多只支持到4000个字符,也就是32K,||的操作会把后面的放入到前面里,就是把后面4000个x放入到前一个4000个x里,作为varchar2,当然就超过了4000的界限。 
Problem Description:
The problem with this query is with the use of CONCAT operator (||).

e.g.: select char1 || char2 from dual
Concat operator returns char1 concatenated with char2. The string returned is in the
same character set as char1. So here concat operator is trying to return varchar2,
which has limit of 4000 characters and getting exceeded.

This problem may also come when we try to CONCAT a VARCHAR2 with CLOB.
e.g.: select char1 || clob from dual

So here we can simply convert its first string to CLOB and avoid this error.
After converting first string to CLOB, CONCAT operator will return string of CLOB type

Solution:
SELECT TO_CLOB(LPAD('x',4000,'x')) || LPAD('x',4000,'x')  || LPAD('x',4000,'x')
FROM DUAL所以问题解决了,只需要将连接的第一个转换成clob就可以。 

看我上面的logminer.sql,我将sql_redo用to_clob函数转换成了clob类型,如果不设置set long 20000000和set longchunksize 255;就会发现,在record3文档中每行只有前80个字符,剩下的都被截断了,这就是我上篇博客中的clob截断问题,所以用上篇博客的方法可以完美解决问题。欧耶!

(3)shell调用spool 的另一种方法, 那就是在shell中调用
selecttpmof03.txt

1 set heading off
2 set feedback off
3 set echo off
4 set newp none
5 set termout off
6 spool /home/orarun/scripts/date.txt
7 select a.REC_CREATOR||'|'||a.REC_CREATE_TIME||'|'||b.event_name||'|'||a.ORDER_NO||'|'||a.MAT_NO||'|'||a.MAT_STATUS||'|'||a.WT from tpmof03 a,tpmof21 b where (a.event_id=b.event_id and a.event_id in('52','6A','6B','6C','6D','5B'))and (a.rec_create_time>='20120101000000');
8 spool off;


1 #!/bin/sh
2
3 rm /home/orarun/scripts/date.txt
4
5 sqlplus tjc1/tjc10804@tjc1 << EOF
6
7 @selecttpmof03.txt                    #或者sqlplus 。。。。。。。。@logminer.sql
8
9 EOF


这种方法理论上也不会在终端上显示信息,不知道为啥上面那个用!的就不行,感觉差不多的样子

   (4)还有一种想法可以在shell脚本中编写出一个.sql脚本,然后去执行它。

    

 1 #!/bin/ksh
 2 record=/oracle/app/oracle/logs/dirct
 3 flag=0
 4 count=1
 5 echo "set echo off;
 6 set heading off;
 7 set line 100;
 8 set long 2000000000;
 9 set longchunksize 255;
10 set wra on;
11 set newpage none;
12 set pagesize 0;
13 set numwidth 12;
14 set termout off;
15 set trimout on;
16 set trimspool on;
17 set feedback off;
18 set timing on;" > logmnr.sql
19 echo "write config"
20 for file_i in `cat $record`;
21 do
22 flag=1
23 if [ $count -eq 1 ];then
24 sed -i '/'''$file_i'''/d' $record
25 echo "execute dbms_logmnr.add_logfile(LogFileName=>'/oracle/app/oracle/logs/$file_i',Options=>dbms_logmnr.new);">>logmnr.sql
26 count=0
27 else
28 sed -i '/'''$file_i'''/d' $record
29 echo "execute dbms_logmnr.add_logfile(LogFileName=>'/oracle/app/oracle/logs/$file_i',Options=>dbms_logmnr.addfile);">>logmnr.sql
30 fi
31 done
32 echo "execute dbms_logmnr.start_logmnr(DictFileName=>'/oracle/app/oracle/logs/dict.ora');">>logmnr.sql
33 if [ $flag -eq 1 ];then
34 echo "spool /oracle/app/oracle/logs/record3.txt;
35 select to_clob(sql_redo)||'|'||to_char(scn)||'|'||to_char(timestamp)||'|'||to_char(session_info)||'|'||to_char(table_name)||'|'||to_char(seg_owner)||'?'
36 from v\$logmnr_contents;
37 spool off;
38 exit;">>logmnr.sql
39 #sqlplus '/as sysdba' @logmnr.sql

 

 http://www.cnblogs.com/zmlctt/p/3721188.html

 

时间: 2025-01-30 15:34:58

oracle之spool详细使用总结(转)的相关文章

Oracle AWR报告详细分析 (文档 ID 1523048.1)

Oracle AWR报告详细分析  (文档 ID 1523048.1) AWR 是 Oracle  10g 版本 推出的新特性, 全称叫Automatic Workload Repository-自动负载信息库 AWR 是通过对比两次快照(snapshot)收集到的统计信息,来生成报表数据,生成的报表包括多个部分. WORKLOAD REPOSITORY report for  DB Name DB Id Instance Inst num Release RAC Host ICCI 13140

Oracle Partition 分区详细总结

原作者:    润明 2012-2-1  QQ:226399587  原帖地址:http://blog.csdn.net/runming918   此文从以下几个方面来整理关于分区表的概念及操作: 1.表空间及分区表的概念 2.表分区的具体作用 3.表分区的优缺点 4.表分区的几种类型及操作方法 5.对表分区的维护性操作. 一.表空间及分区表的概念表空间:是一个或多个数据文件的集合,所有的数据对象都存放在指定的表空间中,但主要存放的是表,所以称作表空间. 分区表:当表中的数据量不断增大,查询数据

Oracle中SPOOL命令使用方法详解

举例:test.sh  代码如下 复制代码 #! /bin/sh sqlplus -s scott/tiger<<EOF  set head off  set linesize 20000  set echo off  set feedback off  set pagesize 0  set termout off  set trimout on  set trimspool on   spool /home/test.txt    select empno || '|' || ename

深入剖析 - Oracle SCN机制详细解读

SCN介绍 SCN即系统改变号(System Change Number),是在某个时间点定义数据库已提交版本的时间戳标记. Oracle为每个已提交的事务分配一个唯一的SCN. SCN的值是对数据库进行更改的逻辑时间点. Oracle使用此编号记录对数据库所做的更改.在数据库中,SCN也可以说是无处不在,数据文件头,控制文件,数据块头,日志文件等等都标记着SCN.也正是这样,数据库的一致性维护和SCN密切相关.不管是数据的备份,恢复都是离不开SCN的. SCN是一个6字节(48bit)的数字,

ThinkPHP 连接Oracle数据库的详细教程[全]_php实例

一. 操作环境搭建 系统:Windows7 旗舰版 64位PHP环境:wampserver2.2e-php5.4.3-httpd2.2.22-mysql5.5.24  32位版下载地址:http://www.wampserver.com/en/ ThinkPHP:3.0正式版下载地址:http://thinkphp.cn/down.html Oracle:Orcale_11gR2  32位版下载地址:http://www.oracle.com/technetwork/cn/indexes/dow

CentOS系统上安装配置Oracle数据库的详细教程_oracle

一.基本配置   1.硬盘剩余空间:10G以上     虽然Oracle 10g的安装文件只有800多MB,但安装后的oracle+oraInventory目录会用差不多4G空间,再加上安装时Oracle生成的临时文件(/tmp目录需要至少400MB). 2.内存1.5G以上     官方文档说512M内存也可以安装.为了避免不必要的麻烦,请把内存加多一些. 3.Swap交换区2G 二.CenOS6 上安装Oracle 10g 1.准备安装在安装Oracle之前执行以下命令: yum insta

ThinkPHP 连接Oracle数据库的详细教程(2)

其实根据以前问题我做了几天调试,找到了问题所在,并成功在我自己一个小项目练习中使用正常,那么现在就将我的经验分享给大家. 1,数据库的连接及配置文件的内容我就不说了, 上面已经做了解释.我这里只根据一个数据表的例子来说明我的操作. 2,表结构如下: 3,这个表中有3个字段,ID主键,用户名username和密码password,因为oracle数据库把表名和字段都是转成大写的,同时不支持ID主键自增,我只有使用另外的方法来实现这个功能,比如:ID自动序列+触发器实现ID自增. 4,    Thi

oracle中to_date详细用法示例(oracle日期格式转换)_oracle

TO_DATE格式(以时间:2007-11-02 13:45:25为例) 1. 日期和字符转换函数用法(to_date,to_char) 复制代码 代码如下: select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') as nowTime from dual;   //日期转化为字符串  select to_char(sysdate,'yyyy')  as nowYear   from dual;   //获取时间的年  select to_char(sys

linux安装oracle

目 录 一.硬件要求 二.软件 三.系统安装注意 四.安装Oracle前的系统准备工作 五.安装Oracle,并进行相关设置 六.升级Oracle到patchset 10.2.0.4 七.使用rlwrap调用sqlplus中历史命令 一.硬件要求 1.内存 & swap Minimum: 1 GB of RAM Recommended: 2 GB of RAM or more 检查内存情况 # grep MemTotal /proc/meminfo # grep SwapTotal /proc/