ITPub博客

首页 > 数据库 > Oracle > [20191104]sqlplus 管道文件 过滤.txt

[20191104]sqlplus 管道文件 过滤.txt

原创 Oracle 作者:lfree 时间:2019-11-04 11:41:39 0 删除 编辑

[20191104]sqlplus 管道文件 过滤.txt

--//前一段时间知道链接https://connor-mcdonald.com/2019/05/28/dbms_job-the-joy-of-transactions/
--//里面pr.sql脚本如何实现的.
--//实际上受限sqlplus的显示限制,有时候确实需要某种过滤功能.比如如果显示信息太多,使用pr.sql脚本查看也是不是很方便.
--//实际上mysql就有这个功能,通过定义pager实现过滤.
--//很久以前我写过一篇链接:http://blog.itpub.net/267265/viewspace-1062965/=>[20131211]mysql pager定义=vim.txt
--//我一直很想在sqlplus实现类似的功能,链接:
--//http://blog.itpub.net/267265/viewspace-2285749/=>[20181219]script使用小技巧.txt
--//http://blog.itpub.net/267265/viewspace-2375095/=>[20190108]rlwrap sqlplus tee相关问题.txt
--//http://blog.itpub.net/267265/viewspace-2375436/=>[20190110]rlwrap sqlplus tee相关问题3.txt
--//今天测试看看是否通过管道实现,最大的问题就是缓存的问题.通过例子说明:

1.环境:
SCOTT@book> @ ver1
PORT_STRING                    VERSION        BANNER
------------------------------ -------------- --------------------------------------------------------------------------------
x86_64/Linux 2.4.xx            11.2.0.4.0     Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production

2.测试
$ mknod  /tmp/oop.pipe p
$ ls -l /tmp/oop.pipe
prw-r--r-- 1 oracle oinstall 0 2019-11-04 10:44:02 /tmp/oop.pipe

--//seesion 1:
SCOTT@book> spool /tmp/oop.pipe
SCOTT@book> select * from dept ;
    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS
        30 SALES          CHICAGO
        40 OPERATIONS     BOSTON

--//seesion 2:
$ tail -f /tmp/oop.pipe

--//你可以发现seesion 2并没有输出.缓存的作用.必须执行spool off,session 2 的tail -f才会输出.

3.利用这个特性可以执行如下:

--//seesion 1:
spool /tmp/oop.pipe
select * from v$database
@ prxx
spool off

--//seesion 2:
$ tail -f /tmp/oop.pipe | grep SUPP
SUPPLEMENTAL_LOG_DATA_MIN     : YES
SUPPLEMENTAL_LOG_DATA_PK      : NO
SUPPLEMENTAL_LOG_DATA_UI      : NO
SUPPLEMENTAL_LOG_DATA_FK      : NO
SUPPLEMENTAL_LOG_DATA_ALL     : NO
SUPPLEMENTAL_LOG_DATA_PL      : NO

4.你也可以建立如下脚本:
$ cat prp.sql
spool /tmp/oop.pipe
@ prxx
spool off

--//session 1先执行:
select * from v$database;

--//session 2执行:
$ tail -f /tmp/oop.pipe | grep SUPP

--//session 1执行:
@ prp

--//由于缓存影响,最好执行2次.避免信息混乱,你可以在session 2上先会几个回车,再在session 1上执行.

$ tail -f /tmp/oop.pipe | egrep "_CHANGE|SUPP"
SUPPLEMENTAL_LOG_DATA_PL      : NO
MIN_REQUIRED_CAPTURE_CHANGE#  :


RESETLOGS_CHANGE#             : 925702
PRIOR_RESETLOGS_CHANGE#       : 1
CHECKPOINT_CHANGE#            : 45243913791
ARCHIVE_CHANGE#               : 45243779946
CONTROLFILE_CHANGE#           : 45243917934
ARCHIVELOG_CHANGE#            : 45243913791
SUPPLEMENTAL_LOG_DATA_MIN     : YES
SUPPLEMENTAL_LOG_DATA_PK      : NO
SUPPLEMENTAL_LOG_DATA_UI      : NO
SUPPLEMENTAL_LOG_DATA_FK      : NO
SUPPLEMENTAL_LOG_DATA_ALL     : NO
SUPPLEMENTAL_LOG_DATA_PL      : NO
MIN_REQUIRED_CAPTURE_CHANGE#  :

--//这样就不需要锻炼眼力了.

5.继续测试:
--//session 1:
SCOTT@book> set linesize 20000
SCOTT@book> set colsep |
SCOTT@book> spool /tmp/oop.pipe
SCOTT@book> @ desc v$database
SCOTT@book> spool off

--//session 2:
$ tail -f /tmp/oop.pipe | egrep "SUPP"
   30      SUPPLEMENTAL_LOG_DATA_MIN                VARCHAR2(8)
   31      SUPPLEMENTAL_LOG_DATA_PK                 VARCHAR2(3)
   32      SUPPLEMENTAL_LOG_DATA_UI                 VARCHAR2(3)
   40      SUPPLEMENTAL_LOG_DATA_FK                 VARCHAR2(3)
   41      SUPPLEMENTAL_LOG_DATA_ALL                VARCHAR2(3)
   51      SUPPLEMENTAL_LOG_DATA_PL                 VARCHAR2(3)
--//可以确定这些相关列在30,31,32,40,41,51.
--//sesson 2先执行:
$ tail -f /tmp/oop.pipe | cut -d"|" -f30,31,32,40,41,51

--//session 1:
SCOTT@book> spool /tmp/oop.pipe
SCOTT@book> select * from v$database;
SCOTT@book> spool off

--//sesson 2的输出:
SCOTT@book> select * from v$database ;
SUPPLEME|SUP|SUP|SUP|SUP|SUP
--------|---|---|---|---|---
YES     |NO |NO |NO |NO |NO

--//你也可以将prp.sql脚本修改如下,不过这样必须先在session 1执行命令,这里是select * from v$database;:
$ cat prp.sql
spool /tmp/oop.pipe
/
spool off

6.prxx脚本如下:
--//前面的点可不是多余的.如果windows下执行,必须修改_pr_tmpfile定义,以及host rm改为host del.

$ cat prxx.sql
.

set termout off
def _pr_tmpfile=/tmp/pr.out

store set &_pr_tmpfile.set replace
set termout on

set serverout on size 1000000 termout off echo off
save &_pr_tmpfile replace
set termout on

0 c clob := q'\
0 declare

999999      \';;
999999      l_theCursor     integer default dbms_sql.open_cursor;;
999999      l_columnValue   varchar2(4000);;
999999      l_status        integer;;
999999      l_descTbl       dbms_sql.desc_tab;;
999999      l_colCnt        number;;
999999  begin
999999      dbms_sql.parse(  l_theCursor, c, dbms_sql.native );;
999999      dbms_sql.describe_columns( l_theCursor, l_colCnt, l_descTbl );;
999999      for i in 1 .. l_colCnt loop
999999          dbms_sql.define_column( l_theCursor, i,
999999                                  l_columnValue, 4000 );;
999999      end loop;;
999999      l_status := dbms_sql.execute(l_theCursor);;
999999      while ( dbms_sql.fetch_rows(l_theCursor) > 0 ) loop
999999          dbms_output.put_line( '==============================' );;
999999          for i in 1 .. l_colCnt loop
999999                  dbms_sql.column_value( l_theCursor, i,
999999                                         l_columnValue );;
999999                  dbms_output.put_line
999999                      ( rpad( l_descTbl(i).col_name,
999999                        30 ) || ': ' || l_columnValue );;
999999          end loop;;
999999      end loop;;
999999  exception
999999      when others then
999999          dbms_output.put_line(dbms_utility.format_error_backtrace);;
999999          raise;;
999999 end;;
/

set termout off
@&_pr_tmpfile.set

get &_pr_tmpfile nolist
host rm  &_pr_tmpfile
set termout on

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/267265/viewspace-2662499/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
熟悉oracle相关技术,擅长sql优化,rman备份与恢复,熟悉linux shell编程。

注册时间:2008-01-03

  • 博文量
    4006
  • 访问量
    7969544