[20251010]建立完善tpt的prr.sql腳本.txt
[20251010]建立完善tpt的prr.sql腳本.txt
--//昨天在測試時不小心輸入pr命令時多輸入一個r,沒想到居然執行了,說明在本目錄或者SQLPATH環境目錄下存在prr.sql腳本。
--//當時忙著處理其他事情,先把這件事情放一放,今天上班優先做一個探究。
1.環境:
SCOTT@book01p> @ ver2
==============================
PORT_STRING : x86_64/Linux 2.4.xx
VERSION : 21.0.0.0.0
BANNER : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
BANNER_FULL : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0
BANNER_LEGACY : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
CON_ID : 0
PL/SQL procedure successfully completed.
$ echo $SQLPATH
/home/oracle/sqllaji:/home/oracle/sqllaji/tpt
$ locate prr.sql
/home/oracle/sqllaji/tpt-oracle-master/prr.sql
/home/oracle/sqllaji/tpt-oracle-master.20250702/prr.sql
--//很明顯確實存在1個prr.sql腳本。仔細查看prr.sql腳本發現存在如下內容:
regexp_like(lower(l_descTbl(i).col_name), lower('&1'))
--//也就是可以根據參數1,輸入正則表達式顯示僅僅顯示需要的字段。不過我估計作者也很少使用,存在一些小問題,根據pr.sql腳本
--//做一些改動.
2.改動后腳本如下:
$ cat -v tpt/prr.sql
.
-- Notes: This script is based on Tom Kyte's original printtbl code ( http://asktom.oracle.com )
-- For coding simplicity I'm using custom quotation marks ( q'\ ) so this script works
-- from Oracle 10gR2 onwards
def _pr_tmpfile=&_tpt_tempdir/pr_&_tpt_tempfile..tmp
def _set_tmpfile=&_tpt_tempdir/set_&_tpt_tempfile..sql
@@saveset
set serverout on size 1000000 termout off
save &_pr_tmpfile replace
set termout on
0 c clob := q'^F
0 declare
999999 ^F';;
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 if regexp_like(lower(l_descTbl(i).col_name), lower('&1')) then
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 if;;
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 serverout off term on
@@loadset
get &_pr_tmpfile nolist
host &_delete &_pr_tmpfile &_set_tmpfile
--//注:里面的^F在linux下的插入模式按ctrl+v,ctrl+f輸入,這樣SQL語句里基本不存在^F字符,不會遇到沖突的可能。
--//另外注意腳本開始的. 不是多余的字符。
3.測試:
SCOTT@book01p> select * from emp where sal>3400;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- ------------------- ---------- ---------- ----------
7839 KING PRESIDENT 1981-11-17 00:00:00 5000 10
--//@ prr * 相當于執行@ pr ,結果我不貼出了。
SCOTT@book01p> @ prr e
==============================
EMPNO : 7839
ENAME : KING
HIREDATE : 1981-11-17 00:00:00
DEPTNO : 10
PL/SQL procedure successfully completed.
--//輸入E表示輸出僅僅含有e字符的字段。
SCOTT@book01p> @ prr ^e
==============================
EMPNO : 7839
ENAME : KING
PL/SQL procedure successfully completed.
--//輸入E開頭的字段。
SCOTT@book01p> @ prr deptno|ename|empno
==============================
EMPNO : 7839
ENAME : KING
DEPTNO : 10
PL/SQL procedure successfully completed.
--//輸入deptno|ename|empno,表示輸出deptno,ename,empno三個字段。
SCOTT@book01p> @ prr [^HIREdate|mgr]
==============================
EMPNO : 7839
ENAME : KING
JOB : PRESIDENT
SAL : 5000
COMM :
DEPTNO : 10
PL/SQL procedure successfully completed.
--//表示輸出除HIREdate,mgr外其他字段。
SCOTT@book01p> @ prr e$
==============================
ENAME : KING
HIREDATE : 1981-11-17 00:00:00
PL/SQL procedure successfully completed.
--//表示輸出e結尾的字段。
--//還可以像pr.sql那樣調用prr.sql,例子如下:
SCOTT@book01p> select * from emp where sal>3400
2 @ prr deptno|ename|empno
==============================
EMPNO : 7839
ENAME : KING
DEPTNO : 10
PL/SQL procedure successfully completed.
SCOTT@book01p> select * from v$database
2 @ prr supp|^dbid
==============================
DBID : 1617337831
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
SUPPLEMENTAL_LOG_DATA_SR : NO
PL/SQL procedure successfully completed.
--//注:該腳本還調用saveset.sql,loadset.sql腳本,如果你不想安裝tpt的整個腳本集合??梢宰约鹤鲆稽c點改動就可以實現相似的
--//功能。
--//注解saveset,loadset,自己定義_pr_tmpfile,_set_tmpfile,_delete滿足需求就可以了。
--//昨天在測試時不小心輸入pr命令時多輸入一個r,沒想到居然執行了,說明在本目錄或者SQLPATH環境目錄下存在prr.sql腳本。
--//當時忙著處理其他事情,先把這件事情放一放,今天上班優先做一個探究。
1.環境:
SCOTT@book01p> @ ver2
==============================
PORT_STRING : x86_64/Linux 2.4.xx
VERSION : 21.0.0.0.0
BANNER : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
BANNER_FULL : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0
BANNER_LEGACY : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
CON_ID : 0
PL/SQL procedure successfully completed.
$ echo $SQLPATH
/home/oracle/sqllaji:/home/oracle/sqllaji/tpt
$ locate prr.sql
/home/oracle/sqllaji/tpt-oracle-master/prr.sql
/home/oracle/sqllaji/tpt-oracle-master.20250702/prr.sql
--//很明顯確實存在1個prr.sql腳本。仔細查看prr.sql腳本發現存在如下內容:
regexp_like(lower(l_descTbl(i).col_name), lower('&1'))
--//也就是可以根據參數1,輸入正則表達式顯示僅僅顯示需要的字段。不過我估計作者也很少使用,存在一些小問題,根據pr.sql腳本
--//做一些改動.
2.改動后腳本如下:
$ cat -v tpt/prr.sql
.
-- Notes: This script is based on Tom Kyte's original printtbl code ( http://asktom.oracle.com )
-- For coding simplicity I'm using custom quotation marks ( q'\ ) so this script works
-- from Oracle 10gR2 onwards
def _pr_tmpfile=&_tpt_tempdir/pr_&_tpt_tempfile..tmp
def _set_tmpfile=&_tpt_tempdir/set_&_tpt_tempfile..sql
@@saveset
set serverout on size 1000000 termout off
save &_pr_tmpfile replace
set termout on
0 c clob := q'^F
0 declare
999999 ^F';;
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 if regexp_like(lower(l_descTbl(i).col_name), lower('&1')) then
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 if;;
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 serverout off term on
@@loadset
get &_pr_tmpfile nolist
host &_delete &_pr_tmpfile &_set_tmpfile
--//注:里面的^F在linux下的插入模式按ctrl+v,ctrl+f輸入,這樣SQL語句里基本不存在^F字符,不會遇到沖突的可能。
--//另外注意腳本開始的. 不是多余的字符。
3.測試:
SCOTT@book01p> select * from emp where sal>3400;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- ------------------- ---------- ---------- ----------
7839 KING PRESIDENT 1981-11-17 00:00:00 5000 10
--//@ prr * 相當于執行@ pr ,結果我不貼出了。
SCOTT@book01p> @ prr e
==============================
EMPNO : 7839
ENAME : KING
HIREDATE : 1981-11-17 00:00:00
DEPTNO : 10
PL/SQL procedure successfully completed.
--//輸入E表示輸出僅僅含有e字符的字段。
SCOTT@book01p> @ prr ^e
==============================
EMPNO : 7839
ENAME : KING
PL/SQL procedure successfully completed.
--//輸入E開頭的字段。
SCOTT@book01p> @ prr deptno|ename|empno
==============================
EMPNO : 7839
ENAME : KING
DEPTNO : 10
PL/SQL procedure successfully completed.
--//輸入deptno|ename|empno,表示輸出deptno,ename,empno三個字段。
SCOTT@book01p> @ prr [^HIREdate|mgr]
==============================
EMPNO : 7839
ENAME : KING
JOB : PRESIDENT
SAL : 5000
COMM :
DEPTNO : 10
PL/SQL procedure successfully completed.
--//表示輸出除HIREdate,mgr外其他字段。
SCOTT@book01p> @ prr e$
==============================
ENAME : KING
HIREDATE : 1981-11-17 00:00:00
PL/SQL procedure successfully completed.
--//表示輸出e結尾的字段。
--//還可以像pr.sql那樣調用prr.sql,例子如下:
SCOTT@book01p> select * from emp where sal>3400
2 @ prr deptno|ename|empno
==============================
EMPNO : 7839
ENAME : KING
DEPTNO : 10
PL/SQL procedure successfully completed.
SCOTT@book01p> select * from v$database
2 @ prr supp|^dbid
==============================
DBID : 1617337831
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
SUPPLEMENTAL_LOG_DATA_SR : NO
PL/SQL procedure successfully completed.
--//注:該腳本還調用saveset.sql,loadset.sql腳本,如果你不想安裝tpt的整個腳本集合??梢宰约鹤鲆稽c點改動就可以實現相似的
--//功能。
--//注解saveset,loadset,自己定義_pr_tmpfile,_set_tmpfile,_delete滿足需求就可以了。
浙公網安備 33010602011771號