[英]Parsing only valid xml in Oracle Stored Procedure
我做了一些搜索,但找不到與我嘗試做的相似的情況。
我有以下代碼,該代碼首先構建一個游標,該游標填充有1)xml 2)id。
直到在第二個select語句中擊中了錯誤的xml行之后,此方法才能正常工作,然后它中斷了該過程且不再繼續。 我需要找到一種方法來跳過第二個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;
對於那些想要解決這個問題的人。
我首先創建了一個新函數:
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;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.