この項の例では、表外のXMLデータを含む表に対してXML REDOをマイニングおよび作成するのに使用可能なプロシージャについて説明します。この例では、一時LOBを使用してXMLデータを作成する方法を示します。XML文書を一度作成すると、その文書を有効に使用できます。この例では、EmployeeName要素に対して作成された文書を問い合せて、EMPLOYEE_XML_DOCS表の元のDMLに対して返された名前、XML文書およびSQL_REDOを格納します。
注意:
このプロシージャでは、簡単な例のみを示します。この例は、LogMinerを使用して、XMLTypeデータを含む表に対するDMLのマイニングおよび作成が可能であることの説明のみを目的としています。
このプロシージャをコールする前に、関連するすべてのログをLogMinerセッションに追加し、COMMITTED_DATA_ONLYオプションを使用して、DBMS_LOGMNR.START_LOGMNR()をコールする必要があります。その後、マイニング対象のXMLデータを含む表のスキーマ名と表名を使用して、MINE_AND_ASSEMBLE()プロシージャをコールすることができます。
-- table to store assembled XML documents
create table employee_xml_docs (
employee_name varchar2(100),
sql_stmt varchar2(4000),
xml_doc SYS.XMLType);
-- procedure to assemble the XML documents
create or replace procedure mine_and_assemble(
schemaname in varchar2,
tablename in varchar2)
AS
loc_c CLOB;
row_op VARCHAR2(100);
row_status NUMBER;
stmt VARCHAR2(4000);
row_redo VARCHAR2(4000);
xml_data VARCHAR2(32767 CHAR);
data_len NUMBER;
xml_lob clob;
xml_doc XMLType;
BEGIN
-- Look for the rows in V$LOGMNR_CONTENTS that are for the appropriate schema
-- and table name but limit it to those that are valid sql or that need assembly
-- because they are XML documents.
For item in ( SELECT operation, status, sql_redo FROM v$logmnr_contents
where seg_owner = schemaname and table_name = tablename
and status IN (DBMS_LOGMNR.VALID_SQL, DBMS_LOGMNR.ASSEMBLY_REQUIRED_SQL))
LOOP
row_op := item.operation;
row_status := item.status;
row_redo := item.sql_redo;
CASE row_op
WHEN 'XML DOC BEGIN' THEN
BEGIN
-- save statement and begin assembling XML data
stmt := row_redo;
xml_data := '';
data_len := 0;
DBMS_LOB.CreateTemporary(xml_lob, TRUE);
END;
WHEN 'XML DOC WRITE' THEN
BEGIN
-- Continue to assemble XML data
xml_data := xml_data || row_redo;
data_len := data_len + length(row_redo);
DBMS_LOB.WriteAppend(xml_lob, length(row_redo), row_redo);
END;
WHEN 'XML DOC END' THEN
BEGIN
-- Now that assembly is complete, we can use the XML document
xml_doc := XMLType.createXML(xml_lob);
insert into employee_xml_docs values
(extractvalue(xml_doc, '/EMPLOYEE/NAME'), stmt, xml_doc);
commit;
-- reset
xml_data := '';
data_len := 0;
xml_lob := NULL;
END;
WHEN 'INSERT' THEN
BEGIN
stmt := row_redo;
END;
WHEN 'UPDATE' THEN
BEGIN
stmt := row_redo;
END;
WHEN 'INTERNAL' THEN
DBMS_OUTPUT.PUT_LINE('Skip rows marked INTERNAL');
ELSE
BEGIN
stmt := row_redo;
DBMS_OUTPUT.PUT_LINE('Other - ' || stmt);
IF row_status != DBMS_LOGMNR.VALID_SQL then
DBMS_OUTPUT.PUT_LINE('Skip rows marked non-executable');
ELSE
dbms_output.put_line('Status : ' || row_status);
END IF;
END;
END CASE;
End LOOP;
End;
/
show errors;
次に、このプロシージャをコールして、SCOTT.XML_DATA_TABへの変更をマイニングし、DMLを適用できます。
EXECUTE MINE_AND_ASSEMBLE ('SCOTT', 'XML_DATA_TAB');
このプロシージャの結果、EMPLOYEE_XML_DOCS表には、変更されたXMLの表外の列それぞれに対する行が含まれます。EMPLOYEE_NAME列には、XML文書から抽出された値が含まれ、SQL_STMT列とXML_DOC列には、元の行の変更が反映されます。
次に、従業員名とSQL文のみが表示される結果表への問合せの例を示します。
SELECT EMPLOYEE_NAME, SQL_STMT FROM EMPLOYEE_XML_DOCS;
EMPLOYEE_NAME SQL_STMT
Scott Davis update "SCOTT"."XML_DATA_TAB" a set a."F3" = XMLType(:1)
where a."F1" = '5000' and a."F2" = 'Chen' and a."F5" = 'JJJ'
Richard Harry update "SCOTT"."XML_DATA_TAB" a set a."F4" = XMLType(:1)
where a."F1" = '5000' and a."F2" = 'Chen' and a."F5" = 'JJJ'
Margaret Sally update "SCOTT"."XML_DATA_TAB" a set a."F4" = XMLType(:1)
where a."F1" = '5006' and a."F2" = 'Janosik' and a."F5" = 'MMM'