[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/ ,如需转载,请注明出处,否则将追究法律责任。