Rem Rem Rem bug_9488925.sql Rem Rem Rem NAME Rem bug_9488925.sql - Report on or fix issues found in bug 9488925 Rem Rem DESCRIPTION Rem See description block for each issue below Rem Rem Rem Rem Rem MODIFIED (MM/DD/YY) Rem bjeffrie 10/03/08 - Created for 10.2.0.5, original script is bug7435518.sql Rem swzhou 09/01/09 - Modified: update condition to check duplicated LocationUsages. Rem yuanzha 03/18/01 - Modified: update for 11.2.0.2 Rem Rem How to apply the script: Rem 1) If there are any OWB products running, exit from all of them. Rem 2) Make a backup of the repository Rem 3) Log in to sqlplus as the repository owner(OWBSYS) and execute bug_9488925.sql script Rem The script will prompt for execution options (see below) Rem SQL> @bug_9488925 Rem Report Only? (Y/N=Report+Fix):[N] Rem Test Mode? (Y=rollback/N=commit):[Y] N Rem Warning: Turning show key info on could result in extremely large output volume Rem (Tip: Running in report only mode with row info set to FALSE will allow you to determine row counts first.) Rem Show detail info for found rows? (Y=show/N=hide):[N] Rem Review above entries and press Rem to continue or Ctrl-C to cancel Rem Start bug_9488925 Customer Critical Issues Repository Cleaning ... Rem Note: Script execution could take several hours. Rem 4) Examine bug_9488925_LOG.TXT generated and save to another copy in case you need to re-run the patch script Rem 5) [Optional] You can re-run the script selecting report-only mode to verify all found issues were resolved. set serveroutput on size 999999 set line 300 ACCEPT V_REPORTONLY DEFAULT 'N' PROMPT 'Report Only? (Y/N=Report+Fix):[N] ' ACCEPT V_TESTING DEFAULT 'Y' PROMPT 'Test Mode? (Y=rollback/N=commit):[Y] ' PROMPT Warning: Turning show key info on could result in extremely large output volume PROMPT . (Tip: Running in report only mode with row info set to FALSE will allow you to determine row counts first.) ACCEPT V_SHOWROWS DEFAULT 'N' PROMPT 'Show detail info for found rows? (Y=show/N=hide):[N] ' PROMPT PROMPT Review above entries and press ACCEPT V_DUMMY PROMPT ' to continue or Ctrl-C to cancel' PROMPT Start bug_9488925 Customer Critical Issues Repository Cleaning ... SPOOL bug_9488925_LOG.TXT set role OWB_USER; CREATE OR REPLACE TYPE tmp_IdSet IS TABLE OF NUMBER(9,0); -- type for element id sets / DECLARE -- NOTE: PL/SQL error message line numbers are offset from here SCRIPTID CONSTANT VARCHAR2(30) := 'bug_9488925'; -- For output logging EOL CONSTANT VARCHAR2(01) := CHR(10); -- new line OUTINITED BOOLEAN := FALSE; -- Flag indicating output has been enabled REPORTONLY BOOLEAN := FALSE; -- Report Only? (TRUE/FALSE=Report+Fix) TESTING BOOLEAN := TRUE; -- Test Mode? (TRUE=rollback/FALSE=commit) SHOWROWS BOOLEAN := FALSE; -- Show detail info for found rows? (TRUE=show/FALSE=hide) -- ************************************************************************** -- ************************************************************************** -- Useful functions/procedures -- ************************************************************************** -- ************************************************************************** -- ========================================================================== -- put message to output (uses DBMS_OUTPUT) PROCEDURE putMsg(msg VARCHAR2) IS -- ========================================================================== BEGIN IF NOT OUTINITED THEN OUTINITED := TRUE; DBMS_OUTPUT.ENABLE(200000); putMsg('DBMS_OUTPUT Enabled.' || EOL); END IF; DBMS_OUTPUT.put_line(SYSTIMESTAMP || ' ' || SCRIPTID || ': ' || msg); -- adds eol + moves to output -- use .put(x); and .new_line; to control seperately END putMsg; -- ========================================================================== -- put nicely formatted count info indented to level 2 to output (uses putMsg) PROCEDURE putCount(aCount NUMBER, aDesc VARCHAR2) IS -- ========================================================================== BEGIN putMsg(' ' || LPAD(aCount,7,' ' ) || ' ' || aDesc); END putCount; -- ========================================================================== -- put detail message indented under putCount to output (uses putMsg) PROCEDURE putDetail(msg VARCHAR2) IS -- ========================================================================== BEGIN -- putCount uses 4+7+1 and we want one more level so +2 = 14 putMsg(' ' || msg); END putDetail; -- ========================================================================== -- return id of object's parent FUNCTION parentIdOf(cId IN NUMBER) -- ========================================================================== RETURN NUMBER IS pId NUMBER(9) := 0; BEGIN BEGIN -- Exception block SELECT ATTRIBUTEGROUPOWNER INTO pId FROM CMPMapAttributeGroup_v WHERE ELEMENTID=cId; RETURN pId; EXCEPTION WHEN OTHERS THEN BEGIN -- Exception block SELECT ATTRIBUTEGROUP INTO pId FROM CMPMapAttribute_v WHERE ELEMENTID=cId; RETURN pId; EXCEPTION WHEN OTHERS THEN BEGIN SELECT PROPERTYOWNER INTO pId FROM CMPPropertyValue_v WHERE ELEMENTID=cId; RETURN pId; EXCEPTION WHEN OTHERS THEN BEGIN SELECT OWNINGFOLDER INTO pId FROM FirstClassObject_v WHERE ELEMENTID=cId; RETURN pId; EXCEPTION WHEN OTHERS THEN BEGIN SELECT FIRSTCLASSOBJECT INTO pId FROM SecondClassObject_v WHERE ELEMENTID=cId; RETURN pId; EXCEPTION WHEN OTHERS THEN RETURN -1; -- Exception END; END; END; END; END; END parentIdOf; -- ========================================================================== -- return fully qualified context string describing the object FUNCTION fqContext(cId IN NUMBER) -- ========================================================================== RETURN VARCHAR2 IS cClass VARCHAR2(100) := ''; cLName VARCHAR2(100) := ''; cName VARCHAR2(30) := ''; cCtx VARCHAR2(1000) := ''; pId NUMBER(9) := -1; pCtx VARCHAR2(4000) := ''; BEGIN BEGIN SELECT CLASSNAME, NAME, LOGICALNAME INTO cClass, cName, cLName FROM CMPElement_v WHERE ELEMENTID=cId; IF cClass = '' OR cClass IS NULL THEN RETURN ''; END IF; cCtx := '(' || cClass || '#' || cId || ')' || NVL(cLName,'null'); IF NOT NVL(cLName,'null') = NVL(cName,'null') THEN cCtx := cCtx || '[' || NVL(cName,'null') || ']'; END IF; pId := parentIdOf(cId); IF( pId > 0 ) THEN pCtx := fqContext(pId); END IF; IF( pCtx = '' OR pCtx IS NULL) THEN RETURN cCtx; ELSE RETURN pCtx || '.' || cCtx; END IF; EXCEPTION WHEN OTHERS THEN RETURN ''; END; END fqContext; -- ************************************************************************** -- ************************************************************************** -- Start of 'real' processing -- ************************************************************************** -- ************************************************************************** BEGIN IF '&V_REPORTONLY' = 'N' THEN -- DEFAULT 'N' PROMPT 'Report Only? (Y/N=Report+Fix):[N] ' REPORTONLY := FALSE; ELSE REPORTONLY := TRUE; END IF; IF '&V_TESTING' = 'N' THEN -- DEFAULT 'Y' PROMPT 'Test Mode? (Y=rollback/N=commit):[Y] ' TESTING := FALSE; ELSE TESTING := TRUE; END IF; IF '&V_SHOWROWS' = 'Y' THEN -- DEFAULT 'N' PROMPT 'Show detail info for found rows? (Y=show/N=hide):[N] ' SHOWROWS := TRUE; ELSE SHOWROWS := FALSE; END IF; putMsg('Starting (Report Only = ' || '&V_REPORTONLY' || ', Testing = ' || '&V_TESTING' || ', Show Row Detail = ' || '&V_SHOWROWS' || ') ...' || EOL); -- add blank line after IF SHOWROWS THEN putMsg('Note: Object info in the details sections includes only the primary (at issue) rows.'); putMsg(' The associated children (if any) do not have detail information produced. The'); putMsg(' row information is generally of the form:'); putMsg(' (#)[] (physicalName only shown if different)'); putMsg(' for each object. Where used, addditional attributes will be labelled. E.g., '); putMsg(' (#)/position=' || EOL); END IF; FOR x in (select workspaceid,name from CMPWorkspace_v where workspaceid != 1) LOOP -- Added by YUANZHA owb_workspace_manager.set_workspace(x.workspaceid); -- set current workspace putMsg('Begin processing workspace ' || x.name || ' ...'); -- *************************************************************************** -- Issue: Orphaned PhysicalObjects -- Delete PhysicalObjects referencing NamedConfigurations that do not exist -- as well as their 'children', 'grand-children', etc. -- -- Test Scenario: --UNKNOWN -- *************************************************************************** DECLARE aCount NUMBER; pDesc VARCHAR2(100) := 'Orphaned PhysicalObjects'; -- parent pIds tmp_IdSet; -- selected set of parent elementIds c1Desc VARCHAR2(100) := 'Owned SecondClassOjbects'; -- child c1Ids tmp_IdSet; -- all owned sco elementIds l_str VARCHAR2(4000); BEGIN putMsg(' Issue: Orphaned PhysicalObjects...'); putMsg(' FOUND:'); aCount := 0; SELECT ELEMENTID BULK COLLECT INTO pIds FROM CMPPhysicalObject_v WHERE NAMEDCONFIGURATION NOT IN ( SELECT ELEMENTID FROM CMPNamedConfiguration_v ) OR NAMEDCONFIGURATION IS NULL OR PLATFORMCONFIGURATION NOT IN ( SELECT ELEMENTID FROM CMPPLATFORMCONFIGURATION_V ) OR PLATFORMCONFIGURATION IS NULL; putCount(pIds.COUNT, pDesc); IF pIds.COUNT > 0 AND SHOWROWS THEN putDetail('Details (Named Configuration does not exist)'); putDetail('--------------------------------------------'); FOR i IN pIds.FIRST .. pIds.LAST LOOP DECLARE details VARCHAR2(100) := ''; BEGIN SELECT '/namedConfiguration=' || NVL2(NAMEDCONFIGURATION,TRIM(TO_CHAR(NAMEDCONFIGURATION)),'null') INTO details FROM CMPPhysicalObject_V WHERE ELEMENTID=pIds(i); putDetail(fqContext(pIds(i)) || details); END; END LOOP; END IF; SELECT ELEMENTID BULK COLLECT INTO c1Ids FROM SecondClassObject_v where FIRSTCLASSOBJECT MEMBER OF pIds ; putCount(c1Ids.COUNT, c1Desc); IF pIds.COUNT > 0 AND NOT REPORTONLY THEN BEGIN putMsg(' DELETED:'); FOR c in (select distinct CLASSNAME from SecondClassObject_v where FIRSTCLASSOBJECT MEMBER OF pIds and CLASSNAME is not null) LOOP l_str := 'DELETE FROM ' || c.CLASSNAME || '_v WHERE ELEMENTID MEMBER OF :1 RETURNING COUNT(ELEMENTID) INTO :2'; --putMsg(' l_str:' || l_str); EXECUTE IMMEDIATE l_str using c1Ids returning into aCount ; putCount(aCount, c.CLASSNAME); END LOOP; DELETE FROM CMPPhysicalObject_v WHERE ELEMENTID MEMBER OF pIds RETURNING COUNT(ELEMENTID) INTO aCount ; putCount(aCount, pDesc); IF TESTING THEN BEGIN ROLLBACK; putMsg(' *ROLLBACK*'); END; ELSE -- I.E., NOT TESTING BEGIN COMMIT; putMsg(' **COMMIT**'); END; END IF; -- TESTING END; END IF; -- NOT REPORTONLY putMsg(' Issue processing completed.' || EOL); -- blank line after END; -- Issue: Orphaned PhysicalObjects -- *************************************************************************** -- Issue: Duplicate PhysicalObjects -- Delete all but most recent duplicate PhysicalObjects -- as well as their 'children', 'grand-children', etc. -- -- PhysicalObject as FirstClassObject may have children -- -- Test Scenario: -- UNKNOWN -- *************************************************************************** DECLARE aCount NUMBER; pDesc VARCHAR2(100) := 'Duplicate PhysicalObjects'; -- parent pIds tmp_IdSet; -- selected set of parent elementIds c1Desc VARCHAR2(100) := 'Owned SecondClassOjbects'; -- sco children c1Ids tmp_IdSet; l_str VARCHAR2(4000); BEGIN putMsg(' Issue: Duplicate PhysicalObjects...'); putMsg(' FOUND:'); aCount := 0; -- Note that AGGREGATESIGNATURE for all of the duplicates is the same (?) -- so use element id to determine 'most recent' SELECT ELEMENTID BULK COLLECT INTO pIds FROM CMPPhysicalObject_v po WHERE po.ELEMENTID < ( SELECT max(ELEMENTID) FROM CMPPhysicalObject_v poKeep WHERE po.LOGICALOBJECT=poKeep.LOGICALOBJECT AND NVL(po.namedconfiguration,0)=NVL(poKeep.namedconfiguration,0) And NVL(po.platformconfiguration,0)=NVL(poKeep.platformconfiguration,0) ); putCount(pIds.COUNT, pDesc); IF pIds.COUNT > 0 AND SHOWROWS THEN putDetail('Details (Match on LogicalObject + NamedConfiguration + PlatformConfiguration)'); putDetail('-----------------------------------------------------'); FOR i IN pIds.FIRST .. pIds.LAST LOOP DECLARE details VARCHAR2(100) := ''; BEGIN SELECT '/namedConfiguration=' || NVL2(NAMEDCONFIGURATION,TRIM(TO_CHAR(NAMEDCONFIGURATION)),'null') INTO details FROM CMPPhysicalObject_V WHERE ELEMENTID=pIds(i); putDetail(fqContext(pIds(i)) || details); END; END LOOP; END IF; SELECT ELEMENTID BULK COLLECT INTO c1Ids FROM SecondClassObject_v where FIRSTCLASSOBJECT MEMBER OF pIds ; putCount(c1Ids.COUNT, c1Desc); IF pIds.COUNT > 0 AND NOT REPORTONLY THEN BEGIN putMsg(' DELETED:'); FOR c in (select distinct CLASSNAME from SecondClassObject_v where FIRSTCLASSOBJECT MEMBER OF pIds and CLASSNAME is not null) LOOP l_str := 'DELETE FROM ' || c.CLASSNAME || '_v WHERE ELEMENTID MEMBER OF :1 RETURNING COUNT(ELEMENTID) INTO :2'; --putMsg(' l_str:' || l_str); EXECUTE IMMEDIATE l_str using c1Ids returning into aCount ; putCount(aCount, c.CLASSNAME); END LOOP; DELETE FROM CMPPhysicalObject_v WHERE ELEMENTID MEMBER OF pIds RETURNING COUNT(ELEMENTID) INTO aCount; putCount(aCount, pDesc); IF TESTING THEN BEGIN ROLLBACK; putMsg(' *ROLLBACK*'); END; ELSE -- I.E., NOT TESTING BEGIN COMMIT; putMsg(' **COMMIT**'); END; END IF; -- TESTING END; END IF; -- NOT REPORTONLY putMsg( ' Issue processing completed.' || EOL); -- blank line after END; -- Issue: Duplicate PhysicalObjects -- *************************************************************************** -- Issue: Orphaned LocationUsages -- Delete LocationUsages referencing Locations that do not exist -- as well as their 'children', 'grand-children', etc. -- -- No children. -- -- Test Scenario: -- UNKNOWN -- *************************************************************************** DECLARE aCount NUMBER; pDesc VARCHAR2(100) := 'Orphaned LocationUsages'; -- parent pIds tmp_IdSet; -- selected set of parent elementIds BEGIN putMsg(' Issue: Orphaned LocationUsages...'); putMsg(' FOUND:'); aCount := 0; SELECT ELEMENTID BULK COLLECT INTO pIds FROM CMPLocationUsage_v WHERE LOCATION NOT IN ( SELECT ELEMENTID FROM CMPLocation_v ) OR LOCATION IS NULL ; putCount(pIds.COUNT, pDesc); IF pIds.COUNT > 0 AND SHOWROWS THEN putDetail('Details (Location does not exist)'); putDetail('---------------------------------'); FOR i IN pIds.FIRST .. pIds.LAST LOOP DECLARE details VARCHAR2(100) := ''; BEGIN SELECT '/location=' || NVL2(LOCATION,TRIM(TO_CHAR(LOCATION)),'null') INTO details FROM CMPLocationUsage_V WHERE ELEMENTID=pIds(i); putDetail(fqContext(pIds(i)) || details); END; END LOOP; END IF; IF pIds.COUNT > 0 AND NOT REPORTONLY THEN BEGIN putMsg(' DELETED:'); DELETE FROM CMPLocationUsage_v WHERE ELEMENTID MEMBER OF pIds RETURNING COUNT(ELEMENTID) INTO aCount ; putCount(aCount, pDesc); IF TESTING THEN BEGIN ROLLBACK; putMsg(' *ROLLBACK*'); END; ELSE -- I.E., NOT TESTING BEGIN COMMIT; putMsg(' **COMMIT**'); END; END IF; -- TESTING END; END IF; -- NOT REPORTONLY putMsg(' Issue processing completed.' || EOL); -- blank line after END; -- Issue: Orphaned LocationUsages -- *************************************************************************** -- Issue: Duplicate LocationUsages -- Delete all but latest duplicate LocationUsages -- as well as their 'children', 'grand-children', etc. -- -- No children. -- -- Test Scenario: -- UNKNOWN -- *************************************************************************** DECLARE aCount NUMBER; pDesc VARCHAR2(100) := 'Duplicate LocationUsages'; -- parent pIds tmp_IdSet; -- selected set of parent elementIds BEGIN putMsg(' Issue: Duplicate LocationUsages...'); putMsg(' FOUND:'); aCount := 0; SELECT ELEMENTID BULK COLLECT INTO pIds FROM CMPLocationUsage_v lu WHERE lu.AGGREGATEDSIGNATURE < ( SELECT MAX(AGGREGATEDSIGNATURE) FROM CMPLocationUsage_v luKeep WHERE NVL(lu.NAME,'null')=NVL(luKeep.NAME,'null') AND lu.DEPLOYMENTDEFAULT=luKeep.DEPLOYMENTDEFAULT AND lu.METADATASOURCEFLAG=luKeep.METADATASOURCEFLAG AND lu.LOCATION=luKeep.LOCATION -- make sure LocationUsage refer to same location (swzhou @ 090901 for bug 8478615) AND lu.INSTALLEDMODULE=luKeep.INSTALLEDMODULE -- make sure LocationUsage refer to same InstalledModule (swzhou @ 090901 for bug 8478615) ) ; putCount(pIds.COUNT, pDesc); IF pIds.COUNT > 0 AND SHOWROWS THEN putDetail('Details (Match on name, deploymentDefault, metaDataSourceFlag,location, installedmodule - only "extra" rows shown)'); putDetail('----------------------------------------------------------------------------------------'); FOR i IN pIds.FIRST .. pIds.LAST LOOP DECLARE details VARCHAR2(100) := ''; BEGIN SELECT '/deploymentDefault=' || TRIM(TO_CHAR(DEPLOYMENTDEFAULT)) || '/metaDataSourceFlag=' || TRIM(TO_CHAR(METADATASOURCEFLAG)) INTO details FROM CMPLocationUsage_V WHERE ELEMENTID=pIds(i); putDetail(fqContext(pIds(i)) || details); END; END LOOP; END IF; IF pIds.COUNT > 0 AND NOT REPORTONLY THEN BEGIN putMsg(' DELETED:'); DELETE FROM CMPLocationUsage_v WHERE ELEMENTID MEMBER OF pIds RETURNING COUNT(ELEMENTID) INTO aCount ; putCount(aCount, pDesc); IF TESTING THEN BEGIN ROLLBACK; putMsg('*ROLLBACK*'); END; ELSE -- I.E., NOT TESTING BEGIN COMMIT; putMsg('**COMMIT**'); END; END IF; -- TESTING END; END IF; -- NOT REPORTONLY putMsg(' Issue processing completed.' || EOL); -- blank line after END; -- Issue: Duplicate LocationUsages -- *************************************************************************** -- Issue: Deployment and Metadata location usages have same name -- Append '_METADATA' to location usage's name where the -- souceMetaDataLocation flag is true. -- -- No childern. -- -- Test Scenario: -- UNKNOWN -- *************************************************************************** DECLARE aCount NUMBER; pDesc VARCHAR2(100) := 'Metadata LocationUsages without "_METADATA" name suffix'; -- parent pIds tmp_IdSet; -- selected set of parent elementIds BEGIN putMsg(' Issue: Deployment and Metadata location usages have same name...'); putMsg(' FOUND:'); aCount := 0; SELECT ELEMENTID BULK COLLECT INTO pIds FROM CMPLocationUsage_v lu WHERE METADATASOURCEFLAG='1' AND NOT NAME LIKE '%_METADATA' ; putCount(pIds.COUNT, pDesc); IF pIds.COUNT > 0 AND SHOWROWS THEN putDetail('Details (NOT NAME LIKE "%_METADATA")'); putDetail('------------------------------------'); FOR i IN pIds.FIRST .. pIds.LAST LOOP DECLARE details VARCHAR2(100) := ''; BEGIN SELECT '/deploymentDefault=' || TRIM(TO_CHAR(DEPLOYMENTDEFAULT)) || '/metaDataSourceFlag=' || TRIM(TO_CHAR(METADATASOURCEFLAG)) INTO details FROM CMPLocationUsage_V WHERE ELEMENTID=pIds(i); putDetail(fqContext(pIds(i)) || details); END; END LOOP; END IF; IF pIds.COUNT > 0 AND NOT REPORTONLY THEN BEGIN DECLARE -- See oracle.wh.repos.sdk.WBRestrictedNameValidator() total max = 30 suffix VARCHAR2(9) := '_METADATA'; maxLen NUMBER := 21; -- (30 - 9) newName VARCHAR2(30); BEGIN putMsg(' UPDATED:'); aCount := 0; FOR i IN pIds.FIRST .. pIds.LAST LOOP BEGIN SELECT NAME INTO newName FROM CMPLocationUsage_v WHERE ELEMENTID=pIds(i); IF LENGTH(newName) > maxLen THEN newName := SUBSTR(newName, 1, maxLen); END IF; newName := newName || suffix; UPDATE CMPLocationUsage_v SET name=newName, logicalName=newName WHERE ELEMENTID=pIds(i); aCount := aCount + 1; END; END LOOP; putCount(aCount, pDesc); IF TESTING THEN BEGIN ROLLBACK; putMsg(' *ROLLBACK*'); END; ELSE -- I.E., NOT TESTING BEGIN COMMIT; putMsg(' **COMMIT**'); END; END IF; -- TESTING END; END; END IF; -- NOT REPORTONLY putMsg(' Issue processing completed.' || EOL); -- blank line after END; -- Issue Deployment and Metadata location usages have same name -- *************************************************************************** -- Issue: Orphaned ReferencePropertyValues -- Delete Orphaned ReferencePropertyValues referencing ReferencedElements that do not exist -- as well as their 'children', 'grand-children', etc. -- -- ReferencePropertyValues as PROPERTYOWNER may have child PropertyValue -- PropertyValue as PROPERTYOWNER may have child PropertyValue -- -- Test Scenario: -- UNKNOWN -- *************************************************************************** DECLARE aCount NUMBER; pDesc VARCHAR2(100) := 'Orphaned ReferencePropertyValues'; -- parent pIds tmp_IdSet; -- selected set of parent elementIds c1Desc VARCHAR2(100) := 'Owned PropertyValues'; -- 1st child c1Ids tmp_IdSet; BEGIN putMsg(' Issue: Orphaned ReferencePropertyValues...'); putMsg(' FOUND:'); aCount := 0; SELECT ELEMENTID BULK COLLECT INTO pIds FROM CMPReferencePropertyValue_v WHERE REFERENCEDELEMENT NOT IN ( SELECT ELEMENTID FROM CMPElement_v ) OR REFERENCEDELEMENT IS NULL ; putCount(pIds.COUNT, pDesc); IF pIds.COUNT > 0 AND SHOWROWS THEN putDetail('Details (referencedElement does not exist)'); putDetail('------------------------------------------'); FOR i IN pIds.FIRST .. pIds.LAST LOOP DECLARE details VARCHAR2(100) := ''; details2 VARCHAR2(100) := ''; BEGIN SELECT '/position=' || TRIM(TO_CHAR(POSITION)) ,' /description=' || TRIM(NVL(DESCRIPTION,'null')) || '/referencedElement=' || NVL2(REFERENCEDELEMENT,TRIM(TO_CHAR(REFERENCEDELEMENT)),'null') INTO details, details2 FROM CMPReferencePropertyValue_V WHERE ELEMENTID=pIds(i); putDetail(fqContext(pIds(i)) || details); putDetail(details2); END; END LOOP; END IF; SELECT ELEMENTID BULK COLLECT INTO c1Ids FROM CMPPropertyValue_v START WITH PROPERTYOWNER MEMBER OF pIds CONNECT BY PRIOR ELEMENTID = PROPERTYOWNER ; putCount(c1Ids.COUNT, c1Desc); IF pIds.COUNT > 0 AND NOT REPORTONLY THEN BEGIN putMsg(' DELETED:'); DELETE FROM CMPPropertyValue_v WHERE ELEMENTID MEMBER OF c1Ids RETURNING COUNT(ELEMENTID) INTO aCount ; putCount(aCount, c1Desc); DELETE FROM CMPReferencePropertyValue_v WHERE ELEMENTID MEMBER OF pIds RETURNING COUNT(ELEMENTID) INTO aCount ; putCount(aCount, pDesc); IF TESTING THEN BEGIN ROLLBACK; putMsg(' *ROLLBACK*'); END; ELSE -- I.E., NOT TESTING BEGIN COMMIT; putMsg(' **COMMIT**'); END; END IF; -- TESTING END; END IF; -- NOT REPORTONLY putMsg(' Issue processing completed.' || EOL); -- blank line after END; -- Issue: Orphaned ReferencePropertyValues -- *************************************************************************** -- Issue: Duplicate PropertyValues -- Delete all but most recent duplicate PropertyValues -- as well as their 'children', 'grand-children', etc. -- -- PropertyValue as PROPERTYOWNER may have child PropertyValue -- -- Test Scenario: -- UNKNOWN -- *************************************************************************** DECLARE aCount NUMBER; pDesc VARCHAR2(100) := 'Duplicate PropertyValues'; -- parent pIds tmp_IdSet; -- selected set of parent elementIds c1Desc VARCHAR2(100) := 'Owned PropertyValues'; -- 1st child c1Ids tmp_IdSet; BEGIN putMsg(' Issue: Duplicate PropertyValues...'); putMsg(' FOUND:'); aCount := 0; SELECT ELEMENTID BULK COLLECT INTO pIds FROM CMPPropertyValue_v pv WHERE pv.AGGREGATEDSIGNATURE < ( SELECT max(AGGREGATEDSIGNATURE) FROM CMPPropertyValue_v pvKeep WHERE pv.PROPERTYOWNER=pvKeep.PROPERTYOWNER AND pv.LOGICALNAME=pvKeep.LOGICALNAME AND pv.POSITION=pvKeep.POSITION AND NVL(pv.NAME,'null')=NVL(pvKeep.NAME,'null') AND NVL(pv.CLASSNAME,'null')=NVL(pvKeep.CLASSNAME,'null') ) ; putCount(pIds.COUNT, pDesc); IF pIds.COUNT > 0 AND SHOWROWS THEN putDetail('Details (Match on owner, logical name, name, position,className)'); putDetail('------------------------------------------------------'); FOR i IN pIds.FIRST .. pIds.LAST LOOP DECLARE details VARCHAR2(100) := ''; BEGIN SELECT '/position=' || TRIM(TO_CHAR(POSITION)) INTO details FROM CMPPropertyValue_V WHERE ELEMENTID=pIds(i); putDetail(fqContext(pIds(i)) || details); END; END LOOP; END IF; SELECT ELEMENTID BULK COLLECT INTO c1Ids FROM CMPPropertyValue_v START WITH PROPERTYOWNER MEMBER OF pIds CONNECT BY PRIOR ELEMENTID = PROPERTYOWNER ; putCount(c1Ids.COUNT, c1Desc); IF pIds.COUNT > 0 AND NOT REPORTONLY THEN BEGIN putMsg(' DELETED:'); DELETE FROM CMPPropertyValue_v WHERE ELEMENTID MEMBER OF c1Ids RETURNING COUNT(ELEMENTID) INTO aCount ; putCount(aCount, c1Desc); DELETE FROM CMPPropertyValue_v WHERE ELEMENTID MEMBER OF pIds RETURNING COUNT(ELEMENTID) INTO aCount ; putCount(aCount, pDesc); IF TESTING THEN BEGIN ROLLBACK; putMsg(' *ROLLBACK*'); END; ELSE -- I.E., NOT TESTING BEGIN COMMIT; putMsg(' **COMMIT**'); END; END IF; -- TESTING END; END IF; -- NOT REPORTONLY putMsg(' Issue processing completed.' || EOL); -- blank line after END; -- Issue: Duplicate PropertyValues putMsg('Workspace ' || x.name || ' processing completed.' || EOL); END LOOP; -- ........................................................................... putMsg('Processing completed.'); END; / --DROP TYPE tmp_IdSet; --/ PROMPT End of the cleaning. SPOOL OFF --exit -- commented out as most typical case will be to run at least twice -- ########################################################################### -- bug_9488925 cleanup -- ###########################################################################