今天实际项目中用到了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通常会用到连接||,这里讲一下连接是怎么回事

  1. SQL> SELECT LPAD('x',4000,'x') || LPAD('x',4000,'x') || LPAD('x',4000,'x') FROM DUAL;
  2. SELECT LPAD('x',4000,'x') || LPAD('x',4000,'x') || LPAD('x',4000,'x') FROM DUAL
  3. *
  4. ERROR at line 1:
  5. ORA-01489: result of string concatenation is too long
  6.  
  7. 这里简单先介绍下lpadrpad是怎么回事:(lr只是方向不同)
    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'
  8.  
  9. 好了,现在回到上面的问题,为什么会出错呢,因为varchar2oracle中,最多只支持到4000个字符,也就是32K,||的操作会把后面的放入到前面里,就是把后面4000x放入到
    前一个4000x里,作为varchar2,当然就超过了4000的界限。
  1. Problem Description:
  2. The problem with this query is with the use of CONCAT operator (||).
  3.  
  4. e.g.: select char1 || char2 from dual
  5. Concat operator returns char1 concatenated with char2. The string returned is in the
  6. same character set as char1. So here concat operator is trying to return varchar2,
  7. which has limit of 4000 characters and getting exceeded.
  8.  
  9. This problem may also come when we try to CONCAT a VARCHAR2 with CLOB.
  10. e.g.: select char1 || clob from dual
  11.  
  12. So here we can simply convert its first string to CLOB and avoid this error.
  13. After converting first string to CLOB, CONCAT operator will return string of CLOB type
  14.  
  15. Solution:
  16. SELECT TO_CLOB(LPAD('x',4000,'x')) || LPAD('x',4000,'x') || LPAD('x',4000,'x')
  17. FROM DUAL
    所以问题解决了,只需要将连接的第一个转换成clob就可以。
  18.  
  19. 看我上面的logminer.sql,我将sql_redoto_clob函数转换成了clob类型,如果不设置set long 20000000set longchunksize 255;就会发现,在record3文档中每行只有
    80个字符,剩下的都被截断了,这就是我上篇博客中的clob截断问题,所以用上篇博客的方法可以完美解决问题。欧耶!
  20.  
  21. 3shell调用spool 的另一种方法,
    那就是在shell中调用
  1. 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('','6A','6B','6C','6D','5B'))and (a.rec_create_time>='');
  8. spool off;
  1.  
  1. 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
  1.  

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

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

  1. #!/bin/ksh
  2. record=/oracle/app/oracle/logs/dirct
  3. flag=
  4. count=
  5. echo "set echo off;
  6. set heading off;
  7. set line ;
  8. set long ;
  9. set longchunksize ;
  10. set wra on;
  11. set newpage none;
  12. set pagesize ;
  13. set numwidth ;
  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=
  23. if [ $count -eq ];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=
  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 ];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
  1.  

oracle之spool详细使用总结的更多相关文章

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

    今天实际项目中用到了spool,发现网上好多内容不是很全,自己摸索了好半天,现在总结一下. 一.通过spool 命令,可以将select 数据库的内容写到文件中,通过在sqlplus设置一些参数,使得 ...

  2. Oracle Merge into 详细介绍

    Oracle Merge into 详细介绍 /*Merge into 详细介绍MERGE语句是Oracle9i新增的语法,用来合并UPDATE和INSERT语句.通过MERGE语句,根据一张表或子查 ...

  3. [Oracle] SQL*Loader 详细使用教程(2)- 命令行参数

    sqlldr工具   SQL*Loader的客户端工具是sqlldr,在操作系统的命令行下输入sqlldr,后面不接任何参数,将显示帮助信息如下所示(所有命令行参数的简单描述及其默认值),所以你并不需 ...

  4. [Oracle] SQL*Loader 详细使用教程(3)- 控制文件

    控制文件是SQL*Loader里最重要的文件,它是一个文本文件,用来定义数据文件的位置.数据的格式.以及配置数据加载过程的行为,在sqlldr中以control参数指定控制文件.   在控制文件里配置 ...

  5. [Oracle] Data Pump 详细使用教程(4)- network_link

    [Oracle] Data Pump 详细使用教程(1)- 总览 [Oracle] Data Pump 详细使用教程(2)- 总览 [Oracle] Data Pump 详细使用教程(3)- 总览 [ ...

  6. [Oracle] Data Pump 详细使用教程(5)- 命令交互模式

    [Oracle] Data Pump 详细使用教程(1)- 总览 [Oracle] Data Pump 详细使用教程(2)- 总览 [Oracle] Data Pump 详细使用教程(3)- 总览 [ ...

  7. 安装64位Oracle 10g超详细教程

    安装64位Oracle 10g超详细教程 1. 安装准备阶段 1.1 安装Oracle环境 经过上一篇博文的过程,已经完成了对Linux系统的安装,本例使用X-Manager来实现与Linux系统的连 ...

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

    这篇文章主要介绍了oracle中to_date详细用法示例,包括期和字符转换函数用法.字符串和时间互转.求某天是星期几.两个日期间的天数.月份差等用法 TO_DATE格式(以时间:2007-11-02 ...

  9. Oracle的Spool导出数据

    出自:http://wallimn.iteye.com/blog/472182 实践 只能在一个终端上的一个窗口中进行操作 第一步:连接oracle数据库     sqlplus qkp/mm_eft ...

随机推荐

  1. [HTML]marquee标签属性详解

    请大家先看下面这段代码:<marquee direction=upbehavior=scrollloop=3scrollamount=1 scrolldelay=10align=topbgcol ...

  2. x86与x64与x86_64

    x86是指intel的开发的一种32位指令集,从386开始时代开始的,一直沿用至今,是一种cisc指令集,所有intel早期的cpu,amd早期的cpu都支持这种指令集,ntel官方文档里面称为“IA ...

  3. Python的进程间通信

    进程间通讯有多种方式,包括信号,管道,消息队列,信号量,共享内存,socket等 1.共享内存 Python可以通过mmap模块实现进程之间的共享内存 mmap文件对象既像一个字符串也像一个普通文件对 ...

  4. MapReduce多表连接

    多表关联 多表关联和单表关联类似,它也是通过对原始数据进行一定的处理,从其中挖掘出关心的信息.下面进入这个实例. 1 实例描述 输入是两个文件,一个代表工厂表,包含工厂名列和地址编号列:另一个代表地址 ...

  5. 【toplink】 位居第一的Java对象关系可持续性体系结构

    TopLink,是位居第一的Java对象关系可持续性体系结构,原署WebGain公司的产品,后被Oracle收购,并重新包装为Oracle AS TopLink.TOPLink为在关系数据库表中存储 ...

  6. 9.MVC框架开发(关于ActionResult的处理)

    1.在Action处理之后,必须有一个返回值,这个返回值必须继承自ActionResult的对象 2.ActionResult,实际就是服务器端响应给客户端的结果 ViewResult(返回视图结果) ...

  7. java学习:用反射构造bean

    先贴一些反射的基本知识:-------------------------------------------------------------------- 一.什么是反射:反射的概念是由Smit ...

  8. SendKeys总结

    1.SendKeys中特殊字符的键代码BACKSPACE {BACKSPACE}.{BS} 或 {BKSP} BREAK {BREAK} CAPS LOCK {CAPSLOCK} DEL 或 DELE ...

  9. cocos2dx Tab选项卡控件的实现

    选项卡控件在游戏和应用中很是常见,但是cocostudio里并没有实现好的选项卡控件,于是自己封装了 一个,效果如下: 代码: TabUiControl.h #pragma once //std #i ...

  10. 使用自定义 URL 实现控制器之间的跳转-b

    一个app往往有很多界面,而界面之间的跳转也就是对应控制器的跳转,控制器的跳转一般有两种情况 push 或者 modal,push 和 modal 的默认效果是系统提供的 文章配图 1. 概述 系统提 ...