CREATE OR REPLACE PACKAGE BW_SIMPLE_GEN AS -------------------------------------------------------------- --Purpose: Module generates package body based on XML -- -- specification of mapping stored as comment -- -- in package specification. -- --Author: Bob Jankovsky, copyleft 2007 -- --Version: 1.0 /19-OCT-2007 -- --Exceptions: 20006 ... Unsuccessfully compiled module -- -------------------------------------------------------------- Procedure GenPackageBody( p_Module in VARCHAR2 -- package name ); END BW_SIMPLE_GEN; / CREATE OR REPLACE PACKAGE BODY BW_SIMPLE_GEN AS ------------------------------------------------------------- Procedure GenPackageBody( p_Module in VARCHAR2 -- package name )is TYPE TAE is table of Varchar2(1000) index by Varchar2(100); TYPE TAI is table of Varchar2(2000) index by binary_integer; va_expr TAE; c_StdSourcePrefix Varchar2(10):='SRC$$'; c_StdTargetPrefix Varchar2(10):='TRG$$'; v_xml XMLTYPE; v_Delim1 Varchar2(30); v_isDBLink Boolean:=false; va_expr_replace TAE; va_spec_functions TAI; va_spec_funcnames TAI; Cursor c_mod_attrs is SELECT * FROM XMLTABLE ( '/' PASSING v_xml COLUMNS ORD for ordinality ,Pattern Varchar2(100) PATH '@Pattern' ,TargetOwner Varchar2(100) PATH '@TargetOwner' ,TargetTable Varchar2(100) PATH '@TargetTable' ,TargetLink Varchar2(100) PATH '@TargetLink' ,TargetPartition Varchar2(100) PATH '@TargetPartition' ,TargetHint Varchar2(100) PATH '@TargetHint' ,SourceHint Varchar2(100) PATH '@SourceHint' ); Cursor c_expr is SELECT * FROM XMLTABLE ( '//EXPR' PASSING v_xml COLUMNS Name Varchar2(100) PATH '@Name' ,Expr Varchar2(1000)PATH 'text()' ); Cursor c_constant is SELECT * FROM XMLTABLE ( '//CONSTANT' PASSING v_xml COLUMNS Name Varchar2(100) PATH '@Name' ,Type Varchar2(100) PATH '@Type' ,Value Varchar2(100) PATH '@Value' ,Query Varchar2(2000)PATH 'text()' ); Cursor c_premappings is SELECT * FROM XMLTABLE ( '//PREMAPPING' PASSING v_xml COLUMNS Name Varchar2(500) PATH '@Comment' ,Code Varchar2(2000)PATH 'text()' ); Cursor c_postmappings is SELECT * FROM XMLTABLE ( '//POSTMAPPING' PASSING v_xml COLUMNS Name Varchar2(500) PATH '@Comment' ,Code Varchar2(2000)PATH 'text()' ); Cursor c_execConditions is SELECT * FROM XMLTABLE ( '//EXECCONDITION' PASSING v_xml COLUMNS Name Varchar2(500) PATH '@Comment' ,Code Varchar2(2000)PATH 'text()' ); Cursor c_loop is SELECT * FROM XMLTABLE ('//LOOP' PASSING v_xml); Cursor c_loopVar (p_xml XMLTYPE)is SELECT * FROM XMLTABLE ( '/*/VAR' PASSING p_xml COLUMNS Name Varchar2(500) PATH '@Name' ,Value Varchar2(2000)PATH 'text()' ); Cursor c_srctab is SELECT * FROM XMLTABLE('//SRCTAB' PASSING v_xml); Cursor c_tab_attrs (p_xml XMLTYPE)is SELECT * FROM XMLTABLE ( '/' PASSING p_xml COLUMNS ORD for ordinality ,Alias Varchar2(100) PATH '@Alias' ,Owner Varchar2(100) PATH '@Owner' ,Name Varchar2(100) PATH '@Name' ,Link Varchar2(100) PATH '@Link' ,Partition Varchar2(100) PATH '@Partition' ,JoinType Varchar2(100) PATH '@Type' ,EnclFlag Varchar2(100) PATH '@EncloseFlag' ,NoIndex Varchar2(100) PATH '@NoIndex' ); Cursor c_tab_attrs2 (p_xml XMLTYPE)is SELECT * FROM XMLTABLE ( '/' PASSING p_xml COLUMNS ORD for ordinality ,Alias Varchar2(100) PATH '@Alias' ,Owner Varchar2(100) PATH '@Owner' ,Name Varchar2(100) PATH '@Name' ,Link Varchar2(100) PATH '@Link' ,Partition Varchar2(100) PATH '@Partition' ,JoinType Varchar2(100) PATH '@Type' ,EnclFlag Varchar2(100) PATH '@EncloseFlag' ,NoIndex Varchar2(100) PATH '@NoIndex' ); Cursor c_tab_on (p_xml XMLTYPE)is SELECT * FROM XMLTABLE ( '/*/ON' PASSING p_xml COLUMNS ORD for ordinality ,COND Varchar2(2000) PATH 'text()' ); Cursor c_tab_where (p_xml XMLTYPE)is SELECT * FROM XMLTABLE ( '//WHERE' PASSING p_xml COLUMNS ORD for ordinality ,COND Varchar2(2000) PATH 'text()' ); Cursor c_tab_dedup_part (p_xml XMLTYPE)is SELECT * FROM XMLTABLE ( '//DEDUP_PARTITION' PASSING p_xml COLUMNS ORD for ordinality ,COND Varchar2(2000) PATH 'text()' ); Cursor c_tab_dedup_ord (p_xml XMLTYPE)is SELECT * FROM XMLTABLE ( '//DEDUP_ORDER' PASSING p_xml COLUMNS ORD for ordinality ,COND Varchar2(2000) PATH 'text()' ); Cursor c_tab_agg (p_xml XMLTYPE)is SELECT * FROM XMLTABLE ( '//AGG' PASSING p_xml COLUMNS COLUMN_NAME Varchar2(1000) PATH '@ColumnName' ,AGG_FUNCTION Varchar2(100) PATH '@AggFunction' ,DistinctFlag Varchar2(10) PATH '@DistinctFlag' ,Alias Varchar2(100) PATH '@Alias' ); Cursor c_tab_subjoin (p_xml XMLTYPE)is SELECT * FROM XMLTABLE ( '//SUBJOIN' PASSING p_xml); Cursor c_subjoin_col (p_xml XMLTYPE)is SELECT * FROM XMLTABLE ( '//COL' PASSING p_xml COLUMNS COLUMN_NAME Varchar2(100) PATH '@ColumnName' ,COLUMN_ALIAS Varchar2(100) PATH '@ColumnAlias' ); Cursor c_filter is SELECT * FROM XMLTABLE ( '//FILTER' PASSING v_xml COLUMNS Type Varchar2(100) PATH '@Type' ,Cond Varchar2(2000) PATH 'text()' ); Cursor c_colmap is SELECT * FROM XMLTABLE ( '//COLMAP' PASSING v_xml COLUMNS ORD for ordinality ,SourceAlias Varchar2(100) PATH '@SourceAlias' ,SourceColumn Varchar2(100) PATH '@SourceColumn' ,SourceExpression Varchar2(2000)PATH 'text()' ,TargetColumn Varchar2(100) PATH '@TargetColumn' ,MatchFlag Varchar2(10) PATH '@MatchFlag' ,UpdateFlag Varchar2(10) PATH '@UpdateFlag' ,DirectFlag Varchar2(10) PATH '@DirectFlag' ,DummyFlag Varchar2(10) PATH '@DummyFlag' ,PartFlag Varchar2(10) PATH '@PartFlag' ,ValidFromFlag Varchar2(10) PATH '@ValidFromFlag' ,ValidToFlag Varchar2(10) PATH '@ValidToFlag' ,NullableFlag Varchar2(10) PATH '@NullableFlag' ,Expr Varchar2(100) PATH '@Expr' ,UpdateExpr Varchar2(100) PATH '@UpdateExpr' ,InsertExpr Varchar2(100) PATH '@InsertExpr' ); ------------------------------------------------------------------------------------------------------- Procedure fillXML is v_is_metadata Boolean:=false; v_is_xml Boolean:=false; v_Str Varchar2(32767); Begin for r1 in ( Select TEXT from USER_SOURCE where NAME=p_Module and TYPE='PACKAGE' order by line )LOOP if v_is_xml then --witin XML code if r1.TEXT like '%*/%' then --resolve end v_is_xml:=false; r1.TEXT:=regexp_replace(r1.TEXT,'(^.*)([*][/])(.*$)','\1'); end if; if r1.TEXT not like '#%' then v_Str:=concat(v_str,r1.TEXT); end if; elsif upper(replace(r1.TEXT,' ')) like '/*METADATA%' then --find tag METADATA: v_is_metadata:=true; elsif v_is_metadata and upper(replace(r1.TEXT,' ')) like '%' then --resolve start of XML v_is_xml:=true; v_Str:=r1.TEXT; end if; End LOOP; v_xml:=XMLTYPE.CREATEXML(v_Str); for r1 in c_expr LOOP va_expr(r1.Name):=r1.Expr; end LOOP; End fillXML; ------------------------------------------------------------------------------------------------------- Function translateDBLink(p Varchar2) return Varchar2 is v_oldL Varchar2(100):=regexp_replace(regexp_substr(p,'@\w+(\W|$)'),'\W','',1,0); v_newL Varchar2(100); Begin if v_oldL is not null then v_isDBLink:=true; end if; v_newL:= v_oldL; --possible translation return regexp_replace(p,'(@'||v_oldL||')(\W|$)','@'||v_newL||'\2'); End; ------------------------------------------------------------------------------------------------------- Function getTableQual(p_name Varchar2,p_owner Varchar2:=null,p_link Varchar2:=null,p_partition Varchar2:=null) return Varchar2 is v_partition_suffix Varchar2(100):=case when p_partition is null then '' else ' PARTITION('||p_partition||')' end; Begin return translateDBLink(rtrim(ltrim(p_owner||'.'||p_name,'.')||'@'||p_link,'@')||v_partition_suffix); End getTableQual; ------------------------------------------------------------------------------------------------------- Function dedupList(p_list Varchar2) return Varchar2 is v_word Varchar2(30); i pls_integer:=1; v_res Varchar2(8000):=p_list; v_res_old Varchar2(8000); Begin LOOP v_word:=regexp_replace(regexp_substr(v_res,'(^|\W)\w+($|\W)',1,i),'\W'); exit when v_word is null; v_res_old:=v_res; v_res:=regexp_replace(v_res,'(^|\W+)('||v_word||')(\W+'||v_word||')($|\W)','\1\2\4'); v_res:=regexp_replace(v_res,'(^|[[:punct:]])(\W*)('||v_word||')($|\W)','\4',1,2); if v_res=v_res_old then i:=i+1; end if; end LOOP; return v_res; End dedupList; ------------------------------------------------------------------------------------------------------- Function getDedupAttrList(P_alias Varchar2, P_srctabXml XMLTYPE) return Varchar2 is v_res Varchar2(8000):=''; v_delim Varchar2(20):=''; Function getList (p Varchar2) return Varchar2 is v_str Varchar2(2000):=p; Begin for i in 1..2 LOOP v_str:=regexp_replace(v_str,'(\W|^)('||p_alias||'[.])(\w+)(\W|$)','\1~\3;\4',1,0,'i'); end LOOP; if v_str!=p then v_str:=regexp_replace(v_str,';[^~]*~',', ',1,0); v_str:=regexp_replace(v_str,'^[^~]*~','',1,0); v_str:=regexp_replace(v_str,';[^;]*$','',1,0); v_str:=concat(v_delim,v_str); v_delim:=', '; else v_str:=''; end if; return v_str; End getList; Begin for r1 in c_colmap LOOP if r1.SourceAlias=P_ALIAS and r1.SourceColumn is not null then v_res:=concat(v_res,v_delim||r1.SourceColumn); v_delim:=', '; elsif r1.SourceExpression is not null then v_res:=concat(v_res,getList(r1.SourceExpression)); end if; End LOOP; for r1 in (SELECT * FROM XMLTABLE ( '/*/*/ON' PASSING v_Xml COLUMNS Cond Varchar2(100) PATH 'text()'))LOOP v_res:=concat(v_res,getList(r1.cond)); end LOOP; for r1 in c_filter LOOP v_res:=concat(v_res,getList(r1.cond)); end LOOP; return deduplist(v_res); End getDedupAttrList; ------------------------------------------------------------------------------------------------------- Function getSourceExpression(r1 c_colmap%rowtype) return Varchar2 is v_express Varchar2(2000); Begin if r1.SourceAlias is not null and r1.SourceColumn is not null then v_express:=r1.SourceAlias||'.'||r1.SourceColumn; else v_express:=translateDBLink(r1.SourceExpression); end if; if r1.Expr is not null then v_express:=replace(va_expr(r1.Expr),':1',v_express); end if; return v_express; End getSourceExpression; ------------------------------------------------------------------------------------------------------- Function getGeneratedSourceHints return Varchar2 is v_express Varchar2(8000):=''; Begin for r1 in c_srctab LOOP for r2 in c_tab_attrs(r1.COLUMN_VALUE) LOOP if NVL(r2.NoIndex,'N')='Y' then v_express:=concat(v_express,'NO_INDEX('||r2.Alias||') '); end if; end LOOP;--r2 end LOOP;--r1 return v_express; End getGeneratedSourceHints; ------------------------------------------------------------------------------------------------------- Function isEnclosed(p_SRCTAB XMLTYPE, p_mask Varchar2:='%' ) return boolean is Begin for r2 in c_tab_attrs2(p_SRCTAB) LOOP if (nvl(r2.EnclFlag,'N')='Y') and ('ENCL' like p_mask) then return true; end if; for r3 in (SELECT * FROM XMLTABLE( '//AGG | //DEDUP_PARTITION | //DEDUP_ORDER | //SUBJOIN' PASSING p_SRCTAB)) LOOP if r3.COLUMN_VALUE.getRootElement() like p_mask then return true; end if; end LOOP;--r3 end LOOP;--r2 return false; End isEnclosed; ------------------------------------------------------------------------------------------------------- -- STATEMENT PARTS PART ------------------------------------------------------------------------------------------------------- Procedure addSelectPart (P_Source_hint Varchar2:=null)is v_delim Varchar2(30):=' '; v_Source_hint varchar2(8000):=P_Source_hint; Begin for r1 in c_srctab LOOP if isEnclosed(r1.COLUMN_VALUE) then for r2 in c_tab_attrs2(r1.COLUMN_VALUE) LOOP v_Source_hint:=regexp_replace(v_Source_hint,'(\W)('||r2.alias||')(\W)','\1@'||r2.alias||' '||r2.alias||'\3'); end LOOP; --r2 end if; end LOOP; --r1 BW_BUFFER.AddLN('SELECT'||replace(' /*+'||v_Source_hint||'*/',' /*+*/')); BW_BUFFER.IND(3); for r1 in c_COLMAP LOOP if NVL(r1.DirectFlag,'N')!='Y' then BW_BUFFER.AddLN(v_delim||getSourceExpression(r1)||' as '||r1.TargetColumn); v_delim:=','; end if; end LOOP; BW_BUFFER.IND(-3); End addSelectPart; ------------------------------------------------------------------------------------------------------- Procedure addFromPart is v_Delim1 Varchar2(30); v_AnyEncl boolean; v_Dedup boolean; v_Agg boolean; v_Encl boolean; v_Subjoin boolean; v_Dedup_part Varchar2(4000); v_Dedup_ord Varchar2(4000); v_AttrList Varchar2(8000); v_GrpList Varchar2(8000); v_Hint Varchar2(2000):=null; Procedure QualifyList (P_list IN OUT Varchar2,P_alias Varchar2) is Begin for i in 1..2 LOOP P_List:=regexp_replace(P_List,'(^|[,(]|distinct)(\s*)(\w+)(\s*)([,)]|\s+[Aa][Ss]|$)','\1\2'||P_ALIAS||'.\3\4\5'); end LOOP; End QualifyList; Begin for r1 in c_srctab LOOP v_AnyEncl :=isEnclosed(r1.COLUMN_VALUE); v_Dedup :=false; v_Agg :=isEnclosed(r1.COLUMN_VALUE,'AGG'); v_Encl :=isEnclosed(r1.COLUMN_VALUE,'ENCL'); v_Subjoin :=isEnclosed(r1.COLUMN_VALUE,'SUBJOIN'); v_Dedup_part:=''; v_Dedup_ord :=''; for r2 in c_tab_attrs(r1.COLUMN_VALUE) LOOP --BW_BUFFER.AddLN('--Source table : '||r2.Name); v_Encl:=isEnclosed(r1.COLUMN_VALUE,'ENCL'); for r3 in c_tab_dedup_part(r1.COLUMN_VALUE) LOOP v_dedup:=true; v_dedup_part:='partition by '||r3.cond; end LOOP;--r3 --dedup partition for r3 in c_tab_dedup_ord(r1.COLUMN_VALUE) LOOP v_dedup:=true; v_dedup_ord:='order by '||r3.cond; end LOOP;--r3 --dedup order BW_BUFFER.AddCH(r2.JoinType||' '); v_HINT:=null; if v_anyEncl then v_HINT:=regexp_replace(NVL(v_HINT,'/*+*/'),'[+]','+ QB_NAME('||r2.ALIAS||') '); if NVL(r2.NoIndex,'N')='Y' then v_HINT:=regexp_replace(NVL(v_HINT,'/*+*/'),'[+]','+ NO_INDEX('||r2.ALIAS||') '); end if; BW_BUFFER.AddLN('-- '||getTableQual(r2.Name,r2.Owner,r2.Link,r2.Partition)||' '||r2.Alias||' ... '||case when v_dedup then 'deduplication' when v_agg then 'aggregation' when v_subjoin then 'subjoin' else 'enclosed' end); BW_BUFFER.IND(2); v_AttrList:=getDedupAttrList(r2.Alias,r1.COLUMN_VALUE); ------------------------------------------------ --aggregations if v_agg then v_GrpList:=v_AttrList; for r3 in c_tab_agg(r1.COLUMN_VALUE) LOOP v_AttrList:=regexp_replace(v_AttrList,'(\W|^)('||COALESCE(r3.ALIAS,r3.COLUMN_NAME,'#')||')(\W|$)','\1'||r3.AGG_FUNCTION||'('||case when r3.DistinctFlag='Y' then 'distinct ' else '' end||r3.COLUMN_NAME||') as '||NVL(r3.ALIAS,r3.COLUMN_NAME)||'\3'); v_GrpList:=regexp_replace(v_GrpList,'(\W|^)('||COALESCE(r3.ALIAS,r3.COLUMN_NAME,'#')||')(\W|$)','\3'); end LOOP;--r3 --aggregation v_GrpList:=regexp_replace(v_GrpList,'(^)(\W*)(\w)','\1\3'); v_GrpList:=regexp_replace(v_GrpList,'(\w)(\W*)($)','\1\3'); end if; ------------------------------------------------ --subjoins if v_subjoin then for r3 in c_tab_subjoin(r1.COLUMN_VALUE) LOOP for r4 in c_tab_attrs2(r3.COLUMN_VALUE) LOOP for r5 in c_subjoin_col(r3.COLUMN_VALUE) LOOP v_AttrList:=regexp_replace(v_AttrList,'(\W|^)([aA][sS] )('||r5.COLUMN_ALIAS||')(\W|$)','\1\2\3xxxxxxxx\4'); v_AttrList:=regexp_replace(v_AttrList,'([^([:alnum:]]|^)('||r5.COLUMN_ALIAS||')(\W|$)','\1'||r4.ALIAS||'.'||r5.COLUMN_NAME||' as '||r5.COLUMN_ALIAS||'xxxxxxxx\3'); v_AttrList:=regexp_replace(v_AttrList,'([(])('||r5.COLUMN_ALIAS||')(\W|$)','\1'||r4.ALIAS||'.'||r5.COLUMN_NAME||'\3'); v_AttrList:=regexp_replace(v_AttrList,'(\W|^)([aA][sS] '||r5.COLUMN_ALIAS||')(xxxxxxxx)(\W|$)','\1\2\4'); v_GrpList:=regexp_replace(v_GrpList,'([^([:alnum:]]|^)('||r5.COLUMN_ALIAS||')(\W|$)','\1'||r4.ALIAS||'.'||r5.COLUMN_NAME||'\3'); end LOOP;--r5 if NVL(r4.NoIndex,'N')='Y' then v_HINT:=regexp_replace(NVL(v_HINT,'/*+*/'),'[+]','+ NO_INDEX('||r4.ALIAS||') '); end if; end LOOP;--r4 end LOOP;--r3 --subjoin process QualifyList(v_AttrList,r2.Alias); QualifyList(v_GrpList,r2.Alias); end if; ------------------------------------------------ BW_BUFFER.AddLN('(Select '||v_Hint||v_AttrList); BW_BUFFER.IND(2); if v_dedup then BW_BUFFER.AddLN(', row_number()over('||v_dedup_part||' '||v_dedup_ord||') as rn$'); end if; BW_BUFFER.AddLN('From '||getTableQual(r2.Name,r2.Owner,r2.Link,r2.Partition)||' '||r2.alias); ------------------------------------------------ --subjoins if v_subjoin then for r3 in c_tab_subjoin(r1.COLUMN_VALUE) LOOP for r4 in c_tab_attrs2(r3.COLUMN_VALUE) LOOP BW_BUFFER.AddLN(r4.JoinType||' '||getTableQual(r4.Name,r4.Owner,r4.Link,r4.Partition)||' '||r4.alias); BW_BUFFER.IND(2); v_Delim1:='ON '; for r5 in c_tab_on(r3.COLUMN_VALUE) LOOP BW_BUFFER.AddLN(v_Delim1||'('||r5.COND||')'); v_Delim1:='AND '; end LOOP;--r5 BW_BUFFER.IND(-2); end LOOP;--r4 end LOOP;--r3 --subjoin process end if; ------------------------------------------------ v_Delim1:='Where '; for r3 in c_tab_where(r1.COLUMN_VALUE) LOOP BW_BUFFER.AddLN(v_Delim1||'('||r3.COND||')'); v_Delim1:='and '; end LOOP;--r3 if v_agg then BW_BUFFER.AddLN('Group by '||v_GrpList); end if; BW_BUFFER.IND(-2); BW_BUFFER.AddLN(') '||r2.alias); BW_BUFFER.IND(-2); else BW_BUFFER.AddLN(getTableQual(r2.Name,r2.Owner,r2.Link,r2.Partition)||' '||r2.Alias); end if; BW_BUFFER.IND(2); v_Delim1:='ON '; for r3 in c_tab_on(r1.COLUMN_VALUE) LOOP BW_BUFFER.AddLN(v_Delim1||'('||r3.COND||')'); v_Delim1:='AND '; end LOOP;--r3 if upper(r2.JoinType) not in ('FROM') then if v_dedup then BW_BUFFER.AddLN(v_Delim1||'('||r2.Alias||'.rn$=1)'); v_Delim1:='AND '; end if; if (not v_anyEncl) then for r3 in c_tab_where(r1.COLUMN_VALUE) LOOP BW_BUFFER.AddLN(v_Delim1||'('||r3.COND||')'); v_Delim1:='AND '; end LOOP;--r3 end if; end if; BW_BUFFER.IND(-2); end LOOP;--r2 End LOOP;--r1 End addFromPart; ------------------------------------------------------------------------------------------------------- Procedure addFilterPart is v_delim Varchar2(30):='WHERE '; v_encl boolean:=false; Begin for r1 in c_filter LOOP if NVL(r1.type,'SOURCE')='SOURCE' then BW_BUFFER.AddLN(v_delim||r1.cond); v_delim:='AND '; end if; end LOOP; for r1 in c_srctab LOOP for r2 in c_tab_attrs(r1.COLUMN_VALUE) LOOP if upper(r2.JoinType) in('FROM') then if not isEnclosed(r1.COLUMN_VALUE) then for r3 in c_tab_where(r1.COLUMN_VALUE) LOOP BW_BUFFER.AddLN(v_delim||r3.cond); v_delim:='AND '; end LOOP;--r3 --dedup order elsif isEnclosed(r1.COLUMN_VALUE,'DEDUP%') then BW_BUFFER.AddLN(v_delim||r2.Alias||'.rn$=1'); v_delim:='AND '; end if; end if; end LOOP; end LOOP; End addFilterPart; ------------------------------------------------------------------------------------------------------- Procedure addColumnList(P_Prefix Varchar2,p_use_direct Boolean:=false,p_incl_direct Boolean:=true) is v_delim Varchar2(30):=' '; Begin for r1 in c_COLMAP LOOP if NVL(r1.DummyFlag,'N')!='Y' then if p_use_direct and r1.InsertExpr is not null then BW_BUFFER.AddLN(v_delim||replace(va_expr(r1.InsertExpr),':1',P_Prefix||'.'||r1.TargetColumn)); elsif p_use_direct and r1.DirectFlag='Y' then if va_expr_replace.exists(r1.TargetColumn) then BW_BUFFER.AddLN(v_delim||va_expr_replace(r1.TargetColumn)); else BW_BUFFER.AddLN(v_delim||getSourceExpression(r1)); end if; v_delim:=','; elsif p_incl_direct or NVL(r1.DirectFlag,'N')='N' then BW_BUFFER.AddLN(v_delim||P_Prefix||'.'||r1.TargetColumn); v_delim:=','; end if; end if; end LOOP; End addColumnList; ------------------------------------------------------------------------------------------------------- Procedure addSetList(P_AllDirect boolean:=false) is v_delim Varchar2(30):=' '; Begin for r1 in c_COLMAP LOOP if NVL(r1.UpdateFlag,'Y')!='N' and NVL(r1.MatchFlag,'N')!='Y' and NVL(r1.DummyFlag,'N')!='Y' and getSourceExpression(r1) is not null then BW_BUFFER.AddCH(v_delim||c_StdTargetPrefix||'.'||r1.TargetColumn||'='); if r1.UpdateExpr is not null then BW_BUFFER.AddLN(replace(va_expr(r1.UpdateExpr),':1',c_StdSourcePrefix||'.'||r1.TargetColumn)); elsif NVL(r1.DirectFlag,'N')='Y' or P_AllDirect then BW_BUFFER.AddLN(getSourceExpression(r1)); else BW_BUFFER.AddLN(c_StdSourcePrefix||'.'||r1.TargetColumn); end if; v_delim:=','; end if; end LOOP; End addSetList; ------------------------------------------------------------------------------------------------------- Procedure addOnList is v_delim Varchar2(30):=''; Begin for r1 in c_COLMAP LOOP if r1.MatchFlag='Y' then if NVL(r1.DirectFlag,'N')='N' then BW_BUFFER.AddLN(v_delim||c_StdTargetPrefix||'.'||r1.TargetColumn||'='||c_StdSourcePrefix||'.'||r1.TargetColumn); else BW_BUFFER.AddLN(v_delim||c_StdTargetPrefix||'.'||r1.TargetColumn||'='||r1.SourceExpression); end if; v_delim:='AND '; end if; end LOOP; for r1 in c_filter LOOP if NVL(r1.type,'SOURCE') in ('TARGET','SOURCE_OUTER','ON') then BW_BUFFER.AddLN(v_delim||r1.cond); v_delim:='AND '; end if; end LOOP; End addOnList; ------------------------------------------------------------------------------------------------------- Procedure addInsertWhere is v_delim Varchar2(30):='WHERE '; Begin for r1 in c_filter LOOP if NVL(r1.type,'SOURCE') in ('INSERT','SOURCE_OUTER') then BW_BUFFER.AddLN(v_delim||r1.cond); v_delim:='AND '; end if; end LOOP; End addInsertWhere; ------------------------------------------------------------------------------------------------------- Procedure addUpdateWhere (p_diff boolean:=false,p_AllDirect boolean:=false) is v_delim Varchar2(30):='WHERE '; Begin if p_diff then v_delim:=v_delim||'('; for r1 in c_COLMAP LOOP if nvl(r1.updateFlag,'Y')!='N' and nvl(r1.dummyFlag,'N')!='Y' and NVL(r1.MatchFlag,'N')!='Y' and NVL(r1.DirectFlag,'N')!='Y' then if not p_AllDirect then BW_BUFFER.AddLN(v_delim||c_StdTargetPrefix||'.'||r1.TargetColumn||'!='||c_StdSourcePrefix||'.'||r1.TargetColumn); else BW_BUFFER.AddLN(v_delim||c_StdTargetPrefix||'.'||r1.TargetColumn||'!='||getSourceExpression(r1)); end if; v_delim:='OR '; end if; end LOOP; Case when v_delim='OR ' then BW_BUFFER.AddLN(')--/differential part'); v_delim:='AND '; when v_delim like '%(' then v_delim:=rtrim(v_delim,'('); else null; end Case; end if; for r1 in c_filter LOOP if NVL(r1.type,'SOURCE') in ('UPDATE') then BW_BUFFER.AddLN(v_delim||r1.cond); v_delim:='AND '; end if; end LOOP; End addUpdateWhere; ------------------------------------------------------------------------------------------------------- Procedure addLinkDummyMergeInsert(r1 c_mod_attrs%rowtype ) is v_delim Varchar2(2):=' '; Begin if v_isDBLink then BW_BUFFER.AddLN('WHEN NOT MATCHED THEN INSERT'); BW_BUFFER.IND(2); BW_BUFFER.AddLN('('); BW_BUFFER.IND(2); for r2 in c_COLMAP LOOP if NVL(r2.MatchFlag,'N')='Y' then BW_BUFFER.AddLN(v_delim||c_StdTargetPrefix||'.'||r2.TargetColumn); v_delim:=','; end if; end LOOP; BW_BUFFER.IND(-1); BW_BUFFER.AddLN(')VALUES('); BW_BUFFER.IND(1); v_delim:=' '; for r2 in c_COLMAP LOOP if NVL(r2.MatchFlag,'N')='Y' then BW_BUFFER.AddLN(v_delim||c_StdSourcePrefix||'.'||r2.TargetColumn); v_delim:=','; end if; end LOOP; BW_BUFFER.IND(-2); BW_BUFFER.AddLN(')'); BW_BUFFER.AddLN('WHERE 1=0'); BW_BUFFER.IND(-2); end if; End addLinkDummyMergeInsert; ------------------------------------------------------------------------------------------------------- -- Patterns Part ------------------------------------------------------------------------------------------------------- Procedure addMergePattern( r1 c_mod_attrs%rowtype ) is Begin BW_BUFFER.AddLN('MERGE'||replace(' /*+'||r1.TargetHint||'*/',' /*+*/')||' INTO ' ||getTableQual(r1.TargetTable,r1.TargetOwner,r1.TargetLink,r1.TargetPartition)||' '||c_StdTargetPrefix); BW_BUFFER.AddLN('USING('); BW_BUFFER.IND(2); AddSelectPart(getGeneratedSourceHints||r1.SourceHint); AddFromPart; AddFilterPart; BW_BUFFER.IND(-2); BW_BUFFER.AddLN(') '||c_StdSourcePrefix); BW_BUFFER.AddLN('ON('); BW_BUFFER.IND(2); AddOnList; BW_BUFFER.IND(-2); BW_BUFFER.AddLN(')'); if r1.pattern in ('MERGE','DIFF_MERGE','UPDATE','DIFF_UPDATE') then BW_BUFFER.AddLN('WHEN MATCHED THEN UPDATE SET'); BW_BUFFER.IND(2); AddSetList; addUpdateWhere(r1.pattern in ('DIFF_MERGE','DIFF_UPDATE')); BW_BUFFER.IND(-2); end if; if r1.pattern in ('MERGE','DIFF_MERGE','DIFF_INSERT') then BW_BUFFER.AddLN('WHEN NOT MATCHED THEN INSERT'); BW_BUFFER.IND(2); BW_BUFFER.AddLN('('); BW_BUFFER.IND(2); AddColumnList(c_StdTargetPrefix,false); BW_BUFFER.IND(-1); BW_BUFFER.AddLN(')VALUES('); BW_BUFFER.IND(1); AddColumnList(c_StdSourcePrefix,true); BW_BUFFER.IND(-2); BW_BUFFER.AddLN(')'); addInsertWhere; BW_BUFFER.IND(-2); end if; If r1.pattern in ('UPDATE','DIFF_UPDATE') then addLinkDummyMergeInsert(r1); end if; BW_BUFFER.AddLN(';'); BW_BUFFER.AddLN('v_processed_rows:=v_processed_rows+SQL%ROWCOUNT;'); End addMergePattern; ------------------------------------------------------------------------------------------------------- Procedure addInsertPattern(r1 c_mod_attrs%rowtype) is v_delim Varchar2(30):='WHERE '; Begin BW_BUFFER.AddLN('INSERT'||replace(' /*+'||r1.TargetHint||'*/',' /*+*/')||' INTO ' ||getTableQual(r1.TargetTable,r1.TargetOwner,r1.TargetLink,r1.TargetPartition)||' '||c_StdTargetPrefix); BW_BUFFER.IND(2); BW_BUFFER.AddLN('('); BW_BUFFER.IND(2); AddColumnList(c_StdTargetPrefix,false); BW_BUFFER.IND(-1); BW_BUFFER.AddLN(')'); BW_BUFFER.AddLN('Select'); BW_BUFFER.IND(1); AddColumnList(c_StdSourcePrefix,true); BW_BUFFER.IND(-1); BW_BUFFER.AddLN('from('); BW_BUFFER.IND(2); AddSelectPart(getGeneratedSourceHints||r1.SourceHint); AddFromPart; AddFilterPart; if r1.pattern in ('DIFF_INSERT(MINUS)') then BW_BUFFER.AddLN('MINUS'); BW_BUFFER.IND(2); BW_BUFFER.AddLN('SELECT'); AddColumnList(c_StdTargetPrefix,false,false); BW_BUFFER.AddLN('FROM ' ||getTableQual(r1.TargetTable,r1.TargetOwner,r1.TargetLink,r1.TargetPartition)||' '||c_StdTargetPrefix); for r1 in c_filter LOOP if NVL(r1.type,'SOURCE')='TARGET' then BW_BUFFER.AddLN(v_delim||r1.cond); v_delim:='AND '; end if; end LOOP; BW_BUFFER.IND(-2); end if; BW_BUFFER.IND(-2); BW_BUFFER.AddLN(') '||c_StdSourcePrefix); addInsertWhere; BW_BUFFER.IND(-3); BW_BUFFER.AddLN(';'); BW_BUFFER.AddLN('v_processed_rows:=v_processed_rows+SQL%ROWCOUNT;'); End addInsertPattern; ------------------------------------------------------------------------------------------------------- Procedure addSelfUpdatePattern( r1 c_mod_attrs%rowtype ) is Begin BW_BUFFER.AddLN('UPDATE'||replace(' /*+'||r1.TargetHint||'*/',' /*+*/')||' ' ||getTableQual(r1.TargetTable,r1.TargetOwner,r1.TargetLink,r1.TargetPartition)||' '||c_StdTargetPrefix); BW_BUFFER.AddLN('SET'); BW_BUFFER.IND(2); AddSetList(true); addUpdateWhere(true,true); BW_BUFFER.IND(-2); BW_BUFFER.AddLN(';'); BW_BUFFER.AddLN('v_processed_rows:=v_processed_rows+SQL%ROWCOUNT;'); End addSelfUpdatePattern; ------------------------------------------------------------------------------------------------------- Procedure addFRDeletePattern( r1 c_mod_attrs%rowtype ) is v_delim Varchar2(30):=' '; Begin BW_BUFFER.AddLN('MERGE'||replace(' /*+'||r1.TargetHint||'*/',' /*+*/')||' INTO ' ||getTableQual(r1.TargetTable,r1.TargetOwner,r1.TargetLink,r1.TargetPartition)||' '||c_StdTargetPrefix); BW_BUFFER.AddLN('USING('); BW_BUFFER.IND(2); BW_BUFFER.AddLN('SELECT'); BW_BUFFER.IND(3); for r1 in c_COLMAP LOOP if NVL(r1.DirectFlag,'N')!='Y' then BW_BUFFER.AddLN(v_delim||r1.TargetColumn); v_delim:=','; end if; end LOOP; BW_BUFFER.IND(-3); BW_BUFFER.AddLN('FROM '||getTableQual(r1.TargetTable,r1.TargetOwner,r1.TargetLink,r1.TargetPartition)); BW_BUFFER.IND(-1); BW_BUFFER.AddLN('MINUS'); BW_BUFFER.IND(1); AddSelectPart(getGeneratedSourceHints||r1.SourceHint); AddFromPart; AddFilterPart; BW_BUFFER.IND(-2); BW_BUFFER.AddLN(') '||c_StdSourcePrefix); BW_BUFFER.AddLN('ON('); BW_BUFFER.IND(2); AddOnList; BW_BUFFER.IND(-2); BW_BUFFER.AddLN(')'); BW_BUFFER.AddLN('WHEN MATCHED THEN UPDATE SET'); BW_BUFFER.IND(2); AddSetList; addUpdateWhere(r1.pattern in ('DIFF_MERGE','DIFF_UPDATE')); BW_BUFFER.IND(-2); addLinkDummyMergeInsert(r1); BW_BUFFER.AddLN(';'); BW_BUFFER.AddLN('v_processed_rows:=v_processed_rows+SQL%ROWCOUNT;'); End addFRDeletePattern; ------------------------------------------------------------------------------------------------------- Procedure addCreepingDeathPattern(r1 c_mod_attrs%rowtype) is Procedure addSelectPartCreepingDeath (P_Source_hint Varchar2:=null)is v_delim Varchar2(30):=' '; v_partitionBy Varchar2(8000):=''; v_validFrom Varchar2(8000):=''; v_partitionDelim Varchar2(30):=' '; Begin BW_BUFFER.AddLN('SELECT'||replace(' /*+'||P_Source_hint||'*/',' /*+*/')); BW_BUFFER.IND(3); for r1 in c_COLMAP LOOP if NVL(r1.MatchFlag,'N')='Y' or NVL(r1.ValidToFlag,'N')='Y' then BW_BUFFER.AddLN(v_delim||r1.TargetColumn); v_delim:=','; end if; if NVL(r1.PartFlag,'N')='Y' then v_partitionBy:=concat(v_partitionBy,v_partitionDelim||r1.TargetColumn); v_partitionDelim:=','; end if; if NVL(r1.ValidFromFlag,'N')='Y' then v_validFrom:=r1.TargetColumn; end if; end LOOP; BW_BUFFER.AddLN(v_delim||'Lead('||v_validFrom||')over(partition by '||v_partitionBy||' order by '||v_validFrom||') as NEXT$FROM'); BW_BUFFER.IND(-3); End addSelectPartCreepingDeath ; Begin BW_BUFFER.AddLN('MERGE'||replace(' /*+'||r1.TargetHint||'*/',' /*+*/')||' INTO ' ||getTableQual(r1.TargetTable,r1.TargetOwner,r1.TargetLink,r1.TargetPartition)||' '||c_StdTargetPrefix); BW_BUFFER.AddLN('USING('); BW_BUFFER.IND(2); AddSelectPartCreepingDeath(getGeneratedSourceHints||r1.SourceHint); BW_BUFFER.AddLN('From '||getTableQual(r1.TargetTable,r1.TargetOwner,r1.TargetLink,r1.TargetPartition)); AddFilterPart; BW_BUFFER.IND(-2); BW_BUFFER.AddLN(') '||c_StdSourcePrefix); BW_BUFFER.AddLN('ON('); BW_BUFFER.IND(2); AddOnList; BW_BUFFER.AddLN('AND '||c_StdSourcePrefix||'.NEXT$FROM is not null'); BW_BUFFER.IND(-2); BW_BUFFER.AddLN(')'); addLinkDummyMergeInsert(r1); BW_BUFFER.AddLN('WHEN MATCHED THEN UPDATE SET'); BW_BUFFER.IND(2); AddSetList(true); for r1 in c_COLMAP LOOP if r1.ValidToFlag='Y' then BW_BUFFER.AddLN(','||c_StdTargetPrefix||'.'||r1.TargetColumn||'='||c_StdSourcePrefix||'.NEXT$FROM-1'); end if; end LOOP; BW_BUFFER.AddLN(''); addUpdateWhere(false); BW_BUFFER.IND(-2); BW_BUFFER.AddLN(';'); BW_BUFFER.AddLN('v_processed_rows:=v_processed_rows+SQL%ROWCOUNT;'); End addCreepingDeathPattern; ------------------------------------------------------------------------------------------------------- -- Package Part ------------------------------------------------------------------------------------------------------- Procedure addLogProcedure is Begin BW_BUFFER.AddLN('--Log info -- some logging procedure should be added here'); End addLogProcedure; ------------------------------------------------------------------------------------------------------- Procedure addSeqWasteIssueFunctions is v_seqNm Varchar2(100); v_delim Varchar2(30):=''; v_cond Varchar2(9000):=''; Begin for r1 in c_filter LOOP if NVL(r1.type,'SOURCE') in ('INSERT','SOURCE_OUTER') then v_cond:=concat(v_cond,v_delim||r1.cond); v_delim:=chr(10)||'and '; end if; end LOOP; if v_cond is not null then for r2 in c_colmap LOOP if upper(r2.SourceExpression) like '%.NEXTVAL%' then v_seqNM:=regexp_replace(regexp_substr(upper(r2.SourceExpression),'(^|\W)\w+([.]NEXTVAL)'),'\W|NEXTVAL'); BW_BUFFER.AddLN('--sequence '||v_seqNM); BW_BUFFER.AddLN('Function get_'||v_seqNM||'(isit Integer) return Integer is'); BW_BUFFER.AddLN(' i integer:=0;'); BW_BUFFER.AddLN('Begin'); BW_BUFFER.IND(2); BW_BUFFER.AddLN(' if isit=1 then'); BW_BUFFER.AddLN(' select '||r2.SourceExpression||' into i from dual;'); BW_BUFFER.AddLN(' end if;'); BW_BUFFER.AddLN(' return i;'); BW_BUFFER.IND(-2); BW_BUFFER.AddLN('End get_'||v_seqNM||';'); va_expr_replace(r2.targetColumn):=p_module||'.get_'||v_seqNM||'(case when '||v_cond||' then 1 else 0 end)'; va_spec_functions(nvl(va_spec_functions.last,0)+1):='Function get_'||v_seqNM||'(isit Integer) return Integer;'; va_spec_funcnames(nvl(va_spec_funcnames.last,0)+1):='get_'||v_seqNM; end if; end LOOP; --r2 end if; End addSeqWasteIssueFunctions ; ------------------------------------------------------------------------------------------------------- Procedure addMainProcHead is v_is_head Boolean:=false; v_tbdConst Boolean:=true; Begin for r1 in ( Select TEXT from USER_SOURCE where NAME=p_Module and TYPE='PACKAGE' order by line )LOOP if not v_is_head and upper(replace(r1.TEXT,' ')) like 'PROCEDUREMAIN%' then v_is_head:=true; end if; if v_is_head then --witin header code if r1.TEXT like '%;%' then --resolve end v_is_head:=false; r1.TEXT:=rtrim(regexp_replace(r1.TEXT,'(^.*)(;)(.*$)','\1'),chr(10)||chr(13))||' is'; BW_BUFFER.AddLN(r1.TEXT); else BW_BUFFER.AddCH(r1.TEXT); end if; end if; End LOOP; BW_BUFFER.IND(2); BW_BUFFER.AddLN('--Audit variables'); BW_BUFFER.AddLN('v_processed_rows Integer:=0;'); BW_BUFFER.AddLN('v_Module_name Varchar2(100):='''||p_Module||''';'); for r1 in c_constant LOOP BW_BUFFER.AddCH(r1.Name||' '||r1.Type); if r1.Value is not null then BW_BUFFER.AddCH(' := '||r1.Value); end if; BW_BUFFER.AddLN(';'); end LOOP; BW_BUFFER.IND(-2); BW_BUFFER.AddLN('Begin'); BW_BUFFER.IND(2); addLogProcedure; for r1 in c_constant LOOP if r1.query is not null then if v_tbdConst then BW_BUFFER.AddLN('--Constant queries'); v_tbdConst:=false; end if; BW_BUFFER.AddLN('Begin'); BW_BUFFER.AddLN(' '||translateDBLink(regexp_replace(r1.query,'(\W)(FROM)(\W)','\1INTO '||r1.Name||' \2\3',1,1,'i'))||';'); BW_BUFFER.AddLN(' Exception when others then '||r1.name||':='||NVL(r1.value,'null')||';'); BW_BUFFER.AddLN('End;'); end if; end LOOP; BW_BUFFER.AddLN('--Mapping statement'); End addMainProcHead; ------------------------------------------------------------------------------------------------------- Procedure addMainProcTail is Begin addLogProcedure; BW_BUFFER.IND(-2); BW_BUFFER.AddLN('End Main;'); End addMainProcTail; ------------------------------------------------------------------------------------------------------- Procedure addPremappings is Begin for r1 in c_premappings LOOP BW_BUFFER.AddLN('-- Premapping: '||r1.name); BW_BUFFER.AddLN(translateDBLink(r1.code)); end LOOP; End addPremappings; ------------------------------------------------------------------------------------------------------- Procedure addPostmappings is Begin for r1 in c_postmappings LOOP BW_BUFFER.AddLN('-- Postmapping: '||r1.name); BW_BUFFER.AddLN(translateDBLink(r1.code)); end LOOP; End addPostmappings; ------------------------------------------------------------------------------------------------------- Procedure addExecConditionHead is Begin for r1 in c_execConditions LOOP BW_BUFFER.AddLN('if '||r1.code||' then -- Execute condition '||r1.name); BW_BUFFER.IND(2); end LOOP; End addExecConditionHead; ------------------------------------------------------------------------------------------------------- Procedure addExecConditionTail is Begin for r1 in c_execConditions LOOP BW_BUFFER.IND(-2); BW_BUFFER.AddLN('end if;'); end LOOP; End addExecConditionTail; ------------------------------------------------------------------------------------------------------- Procedure addLoopHead is i integer:=0; v_case TAE; v_cs Varchar2(2000); Begin for r1 in c_loop LOOP i:=i+1; for r2 in c_loopVar(r1.COLUMN_VALUE) LOOP v_cs:=chr(10)||' when '||to_char(i)||' then '||r2.value; if v_case.exists(r2.name) then v_case(r2.name):=concat(v_case(r2.name),v_cs); else v_case(r2.name):=r2.name||':=case i '||v_cs; end if; end LOOP; end LOOP; if i>0 then BW_BUFFER.AddLN('for i in 1..'||to_char(i)||' LOOP'); BW_BUFFER.IND(2); v_cs:=v_case.first; while v_cs is not null LOOP BW_BUFFER.AddLN(concat(v_case(v_cs),chr(10)||'end;')); v_cs:=v_case.next(v_cs); end LOOP; end if; End addLoopHead; ------------------------------------------------------------------------------------------------------- Procedure addLoopTail is Begin for r1 in c_loop LOOP BW_BUFFER.IND(-2); BW_BUFFER.AddLN('end LOOP;'); exit; end LOOP; End addLoopTail; ------------------------------------------------------------------------------------------------------- Procedure addPackageBodyHead is Begin BW_BUFFER.AddLN('Create or replace package body '||p_Module||' as'); BW_BUFFER.IND(2); addSeqWasteIssueFunctions; BW_BUFFER.AddLN('--Procedure MAIN'); addMainProcHead; addLoopHead; addExecConditionHead; addPremappings; End addPackageBodyHead; ------------------------------------------------------------------------------------------------------- Procedure addPackageBodyTail is Begin addPostmappings; addExecConditionTail; addLoopTail; addMainProcTail; BW_BUFFER.IND(-2); BW_BUFFER.AddLN('End '||p_Module||';'); End addPackageBodyTail; ------------------------------------------------------------------------------------------------------- procedure checkStatus is v_status Varchar2(30); Begin Select status into v_status from user_objects where object_type='PACKAGE BODY' and object_name=p_Module; if v_status='INVALID' then raise_application_error(-20006,'Module '||p_Module||' compiled unsuccessfully'); end if; End checkStatus; ------------------------------------------------------------------------------------------------------- Procedure rewriteSpec is v_yetgen boolean:=false; v_ptg boolean:=false; v_pt1 boolean:=false; v_pt2 boolean:=false; v_done boolean:=false; v_skip boolean:=false; Begin for r1 in ( Select TEXT from USER_SOURCE where NAME=p_Module and TYPE='PACKAGE' order by line )LOOP if upper(replace(r1.TEXT,' ')) like '/*GENERATEDPART%' then v_yetgen:=true; exit; end if; End LOOP; BW_BUFFER.Init; BW_BUFFER.AddCh(' CREATE OR REPLACE '); for r1 in ( Select TEXT from USER_SOURCE where NAME=p_Module and TYPE='PACKAGE' order by line )LOOP if not v_pt1 and upper(replace(r1.TEXT,' ')) like 'PROCEDUREMAIN%' then v_pt1:=true; end if; if v_pt1 and r1.TEXT like '%;%' then v_pt2:=true; end if; if not v_ptg and upper(replace(r1.TEXT,' ')) like '/*GENERATEDPART%' then v_ptg:=true; end if; if v_skip and upper(replace(r1.TEXT,' ')) like '/*!GENERATEDPART%' then v_skip:=false; end if; if not v_skip then BW_BUFFER.AddLN(rtrim(r1.TEXT,chr(10))); end if; if not v_done and ((v_pt2 and not v_yetgen) or v_ptg) then if va_spec_functions.count>0 then if v_yetgen then v_skip:=true; else BW_BUFFER.AddLN('/* GENERATED PART */'); end if; for i in 1..va_spec_functions.count LOOP BW_BUFFER.AddLN(' '||va_spec_functions(i)); BW_BUFFER.AddLN(' PRAGMA RESTRICT_REFERENCES ('||va_spec_funcnames(i)||', WNPS, WNDS, RNPS);'); end LOOP; if not v_yetgen then BW_BUFFER.AddLN('/* !GENERATED PART */'); end if; elsif v_yetgen then v_skip:=true; end if; v_done:=true; end if; End LOOP; BW_BUFFER.BuffExec; BW_BUFFER.Init; BW_BUFFER.AddLN('ALTER PACKAGE '||p_Module||' COMPILE BODY'); BW_BUFFER.BuffExec; End rewriteSpec; ------------------------------------------------------------------------------------------------------- Begin DBMS_OUTPUT.ENABLE(1000000); BW_Buffer.Init; fillXML; addPackageBodyHead; for r1 in c_mod_attrs LOOP if r1.pattern in ('MERGE','DIFF_MERGE','UPDATE','DIFF_UPDATE','DIFF_INSERT') then addMergePattern(r1); elsif r1.pattern in ('INSERT','DIFF_INSERT(MINUS)') then addInsertPattern(r1); elsif r1.pattern in ('SELF_UPDATE') then addSelfUpdatePattern(r1); elsif r1.pattern in ('FR_DELETE') then addFRDeletePattern(r1); elsif r1.pattern in ('CREEPING_DEATH') then addCreepingDeathPattern(r1); elsif r1.pattern in ('NONE') then null; end if; end LOOP; addPackageBodyTail; BW_Buffer.BuffExec; rewritespec; checkStatus; End GenPackageBody; END BW_SIMPLE_GEN; /