我做了一些搜索,并且找不到与我想做的事情类似的情况。
我有以下代码,首先构建一个填充的游标 1)xml 2)id。
这可以正常工作,直到命中错误的xml行(在第二个select语句中)然后它会中断该过程并且不会继续。我需要找到一种方法来跳过第二个select语句中的错误xml并继续构建游标。
以下是代码:
DECLARE
COUNTER NUMBER;
CURSOR CXD_ID_UPDATE IS
WITH
XMLDATA
AS
(
SELECT XMLTYPE(X.XMLDOC) XMLD, X.CXD_ID
FROM
C_XML_DOC X RIGHT OUTER JOIN CPS_POT P ON X.CXD_ID = P.CXD_ID
WHERE P.CXD_ID IS NOT NULL
)
SELECT XT.SCAN_DOC_ID AS SCAN_DOC_ID
,X.CXD_ID AS CXD_ID
FROM XMLDATA X, CPS_DOCUMENT DOC,
XMLTABLE('/HXML/BATCH/FOLDER/DOCUMENTS/DOCUMENT'
PASSING X.XMLD
COLUMNS SCAN_DOC_ID VARCHAR2(50) PATH '@ScanDocID') XT
WHERE REGEXP_LIKE(XT.SCAN_DOC_ID,'^\d+(\.\d+)?$', '')
AND XT.SCAN_DOC_ID = DOC.DOC_ID;
BEGIN
COUNTER := 0;
FOR REC IN CXD_ID_UPDATE
LOOP
BEGIN
UPDATE DOCUMENT SET CXD_ID = REC.CXD_ID WHERE DOC_ID = REC.SCAN_DOC_ID ;
COUNTER := COUNTER + 1;
EXCEPTION WHEN OTHERS THEN
CONTINUE;
END;
END LOOP;
DBMS_OUTPUT.PUT_LINE('UPDATED: ' || COUNTER || ' DOCUMENTS' );
END;
答案 0 :(得分:0)
对于那些想要在这里得到答案的人来说。
我首先创建了一个新函数:
create or replace function isWellFormedXML(P_XML_CONTENT CLOB,
P_ERROR_MESSAGE OUT VARCHAR2)
return number
as
PARSING_ERROR exception;
PRAGMA EXCEPTION_INIT( PARSING_ERROR , -31011 );
V_VALID_XML XMLTYPE;
begin
V_VALID_XML := XMLTYPE(P_XML_CONTENT);
V_VALID_XML := NULL;
return 1;
exception
when PARSING_ERROR then
P_ERROR_MESSAGE := DBMS_UTILITY.FORMAT_ERROR_STACK() || DBMS_UTILITY.FORMAT_ERROR_BACKTRACE();
return 0;
when others then
RAISE;
end;
这是实用程序的主要功能。
DECLARE
V_ERROR_MSG VARCHAR2(4000);
COUNTER NUMBER(10);
BEGIN
COUNTER := 0;
FOR R IN (
SELECT X.CXD_ID CXD,
X.XMLDOC XML FROM XML_DOC X, POT P WHERE P.CXD_ID = X.CXD_ID
) LOOP
BEGIN
IF(isWellFormedXML(R.XML,V_ERROR_MSG)) = 1 THEN
FOR L IN (
SELECT D.SCAN_DOC_ID DOCID
FROM DOCUMENT DOC, xmltable
('/HXML/BATCH/FOLDER/DOCUMENTS/DOCUMENT'
PASSING XMLTYPE.CREATEXML(R.XML)
COLUMNS SCAN_DOC_ID VARCHAR2(50) PATH '@ScanDocID'
) D
WHERE REGEXP_LIKE(D.SCAN_DOC_ID,'^\d+(\.\d+)?$', '')
AND D.SCAN_DOC_ID = DOC.DOC_ID
) LOOP
BEGIN
COUNTER := COUNTER + 1;
--DBMS_OUTPUT.put_line('CXD '|| R.CXD || ' DOCID ' || L.DOCID);
END;
END LOOP;
END IF;
EXCEPTION
WHEN no_data_found THEN
NULL;
END;
END LOOP;
DBMS_OUTPUT.put_line('TOTAL NUMBER OF DOCUMENTS : ' || COUNTER);
END;