通過pl/sql來格式化sql

jeanron100發表於2015-03-03
在之前的一篇博文中分享了通過java來格式化sql,http://blog.itpub.net/23718752/viewspace-1444910/
今天突然想試試通過sql來格式化一把pl/sql試試,想起來容易,做起來難,自己搗鼓了半天,總算是弄出點雛形了。簡單分享一下。
我們還是格式化同一段sql語句。
select /*+ leading(s) index(s TABLE_BPM_STEP_INST_5IX) use_nl(s p
p step) */ s.ALLOW_CREATE, s.ASSIGNEE, s.ASYNC_RETURNED_PARAMS, s
.ATTACHER2STEP_INST, s.COMMITTER, s.CONTROL_COUNT, s.CURR_FAULT2F
AULT_INFO, s.DO_AVAIL_ON_RESUM, s.DO_FIN_ON_RESUM, s.HAS_DEPENDEN
TS, s.HAS_MARCH_REND, s.HAS_REND, s.INFLOW_BITS, s.ITER_COUNT, s.
NUM_OR_PREREQS, s.NUM_PENDING, s.NUM_PENDING_PREREQS, s.OBJID, s.
OUTFLOW_BITS, s.PARAMS, s.PARENT2PROC_INST, s.ROOT2PROC_INST, s.S
TART_TIME, s.STATUS, s.STATUS_CHANGE_TIME, s.STEP2STEP, s.TARGETE
D_BY_ALARMS, s.TRIGGERS_ALARMS, s.WAIT_TIME, s.WORKER FROM TABLE_
BPM_PROC_INST p, TABLE_BPM_STEP_INST s, TABLE_BPM_STEP step WHERE
 s.root2proc_inst = p.objid AND s.step2step = step.objid AND ( NO
T (step.step_type = 4)) AND p.root_status in (0, 14) AND s.commit
ter = :1 AND s.assignee in ('BpmInServer', 'BpmInServerSmThr', 'B
pmJms') AND s.status in (50, 55) AND s.curr_fault2fault_info is n
ull and ( p.EXEC_DOMAIN like :2 ) 

自己嘗試通過建立一個臨時用的表,然後通過pl/sql來簡單分析,從這個過程來看,pl/sql處理的思路和java還是差別很大。
create table tmp_format_sql(text varchar2(200));
首先得到一個sql檔案,內容如上,我們假設為test.sql
格式化成為insert 語句。
[ora11g@rac1 ~]$  awk '{print "insert into tmp_format_sql values(" "'\''"$0"'\''" " );"}' test.sh
insert into tmp_format_sql values('select /*+ leading(s) index(s TABLE_BPM_STEP_INST_5IX) use_nl(s p' );
insert into tmp_format_sql values('p step) */ s.ALLOW_CREATE, s.ASSIGNEE, s.ASYNC_RETURNED_PARAMS, s' );
insert into tmp_format_sql values('.ATTACHER2STEP_INST, s.COMMITTER, s.CONTROL_COUNT, s.CURR_FAULT2F' );
insert into tmp_format_sql values('AULT_INFO, s.DO_AVAIL_ON_RESUM, s.DO_FIN_ON_RESUM, s.HAS_DEPENDEN' );
insert into tmp_format_sql values('TS, s.HAS_MARCH_REND, s.HAS_REND, s.INFLOW_BITS, s.ITER_COUNT, s.' );
insert into tmp_format_sql values('NUM_OR_PREREQS, s.NUM_PENDING, s.NUM_PENDING_PREREQS, s.OBJID, s.' );
insert into tmp_format_sql values('OUTFLOW_BITS, s.PARAMS, s.PARENT2PROC_INST, s.ROOT2PROC_INST, s.S' );
insert into tmp_format_sql values('TART_TIME, s.STATUS, s.STATUS_CHANGE_TIME, s.STEP2STEP, s.TARGETE' );
insert into tmp_format_sql values('D_BY_ALARMS, s.TRIGGERS_ALARMS, s.WAIT_TIME, s.WORKER FROM TABLE_' );
insert into tmp_format_sql values('BPM_PROC_INST p, TABLE_BPM_STEP_INST s, TABLE_BPM_STEP step WHERE' );
insert into tmp_format_sql values(' s.root2proc_inst = p.objid AND s.step2step = step.objid AND ( NO' );
insert into tmp_format_sql values('T (step.step_type = 4)) AND p.root_status in (0, 14) AND s.commit' );
insert into tmp_format_sql values('ter = :1 AND s.assignee in ('BpmInServer', 'BpmInServerSmThr', 'B' );
insert into tmp_format_sql values('pmJms') AND s.status in (50, 55) AND s.curr_fault2fault_info is n' );
insert into tmp_format_sql values('ull and ( p.EXEC_DOMAIN like :2 )' );
直接執行生成的Insert語句即可,使用sed先來把單引號‘替換成為'' 然後通過awk來拼接成需要的sql語句。
然後使用pl/sql來直接解析tmp_format_sql中的資料即可,pl/sql的內容很簡單,相比java的處理來說要簡化很多。
set feedback off
set serveroutput on
declare
a varchar2(200);
b varchar2(200);
cursor tmp_sql is select substr(text,1,instr(text,' ',-1,1))left_part,substr(text,instr(text,' ',-1,1)) right_part from tmp_format_sql;  --這是最重要的語句,以每行最後的一個空格為界,把每一行分成兩部分,在迴圈中拼接。
begin
for i in tmp_sql loop
i.left_part:=a||i.left_part;
a:=i.right_part;
dbms_output.put_line(i.left_part);
end loop;
end;
/

得到的結果如下:
select /*+ leading(s) index(s TABLE_BPM_STEP_INST_5IX) use_nl(s
pp step) */ s.ALLOW_CREATE, s.ASSIGNEE, s.ASYNC_RETURNED_PARAMS,
s.ATTACHER2STEP_INST, s.COMMITTER, s.CONTROL_COUNT,
s.CURR_FAULT2FAULT_INFO, s.DO_AVAIL_ON_RESUM, s.DO_FIN_ON_RESUM,
s.HAS_DEPENDENTS, s.HAS_MARCH_REND, s.HAS_REND, s.INFLOW_BITS, s.ITER_COUNT,
s.NUM_OR_PREREQS, s.NUM_PENDING, s.NUM_PENDING_PREREQS, s.OBJID,
s.OUTFLOW_BITS, s.PARAMS, s.PARENT2PROC_INST, s.ROOT2PROC_INST,
s.START_TIME, s.STATUS, s.STATUS_CHANGE_TIME, s.STEP2STEP,
s.TARGETED_BY_ALARMS, s.TRIGGERS_ALARMS, s.WAIT_TIME, s.WORKER FROM
TABLE_BPM_PROC_INST p, TABLE_BPM_STEP_INST s, TABLE_BPM_STEP step
WHERE s.root2proc_inst = p.objid AND s.step2step = step.objid AND (
NOT (step.step_type = 4)) AND p.root_status in (0, 14) AND
s.committer = :1 AND s.assignee in ('BpmInServer', 'BpmInServerSmThr',
'BpmJms') AND s.status in (50, 55) AND s.curr_fault2fault_info is
null and ( p.EXEC_DOMAIN like :2

預期結果和java格式化的一致,可以從這個過程中看出來,同一個功能有多種實現方式,oracle中對於字元處理的功能還是很強大的,可以根據自己的需要來靈活使用。



來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/23718752/viewspace-1447260/,如需轉載,請註明出處,否則將追究法律責任。

相關文章