在PL/SQL中解析大型XML(>4k)
我得到一个长度约为30k的xml。我必须从这个xml中提取键和值对,并插入到表中。还必须避免表中的重复行。以下是我提出的问题:在PL/SQL中解析大型XML(>4k),xml,oracle,xmltype,Xml,Oracle,Xmltype,我得到一个长度约为30k的xml。我必须从这个xml中提取键和值对,并插入到表中。还必须避免表中的重复行。以下是我提出的问题: DECLARE PARSER XMLPARSER.PARSER; XMLDOC XMLDOM.DOMDOCUMENT; NODELIST XMLDOM.DOMNODELIST; REFDATA VARCHAR2(32767); REFDATAPART VARCHAR2(32767); NODELENGTH NUMBER; 开始 结束 此查询工作
DECLARE
PARSER XMLPARSER.PARSER;
XMLDOC XMLDOM.DOMDOCUMENT;
NODELIST XMLDOM.DOMNODELIST;
REFDATA VARCHAR2(32767);
REFDATAPART VARCHAR2(32767);
NODELENGTH NUMBER;
开始
结束
此查询工作正常,最终将成为存储过程的一部分
我有两个问题:
1-这是处理最大大小为32k的大型xml的正确方法吗
2-这是否足以在一秒钟内处理700个电话 谢谢,
阿提克我想你至少肯定想收集插页。我不知道NODELENGTH有多大,但您可以使用类似于: 在你的声明中:
TYPE T_STRING IS TABLE OF VARCHAR2(1024); -- adjust size
arr T_STRING := T_STRING();
在pl正文中:
REFDATA := '<ReferenceFields><ReferenceField><FieldKey>Name1</FieldKey> <FieldValue>ABCD</FieldValue></ReferenceField><ReferenceField><FieldKey>Name1</FieldKey><FieldValue>ABCD</FieldValue></ReferenceField></ReferenceFields>';
PARSER := XMLPARSER.NEWPARSER;
XMLPARSER.PARSEBUFFER(PARSER,REFDATA);
XMLDOC := XMLPARSER.GETDOCUMENT(PARSER);
NODELIST := XMLDOM.GETELEMENTSBYTAGNAME(XMLDOC, 'ReferenceField');
NODELENGTH := XMLDOM.GETLENGTH(NODELIST);
FOR i IN 0..NODELENGTH-1 LOOP
XMLDOM.WRITETOBUFFER(XMLDOM.ITEM(NODELIST, i), REFDATAPART);
arr.EXTEND();
arr(arr.COUNT) := XMLSequence(XMLTYPE(REFDATAPART));
END LOOP;
FORALL i IN arr.FIRST..arr.LAST
INSERT INTO HTS_TRANSACTION_XREF(TRANS_ID,XREF_FIELD, XREF_VALUE)
SELECT
'1',
EXTRACTVALUE(arr(i), '/ReferenceField/FieldKey') "FIELDKEY",
EXTRACTVALUE(arr(i), '/ReferenceField/FieldValue') "FIELDVALUE"
FROM
dual
WHERE
NOT EXISTS (
SELECT 1 FROM TRANSACTION_CROSSREFERENCE
WHERE
TRANS_ID = '1'
AND XREF_FIELD = EXTRACTVALUE(arr(i), '/ReferenceField/FieldKey')
AND XREF_VALUE = EXTRACTVALUE(arr(i), '/ReferenceField/FieldValue')
);
XMLPARSER.FREEPARSER(PARSER);
我也不知道“不存在”部分的目的是什么,您确定这是必要的吗?2-这是否足够高效,可以在一秒钟内处理700个呼叫这是在什么硬件上运行的,还有其他任何东西在这上面运行,等等。这是一个只有你才能回答的问题。就个人而言,我不会在数据库中进行这种处理,而是在应用服务器中进行处理,这样可以更好、更便宜地扩展以满足您的需求。您还可以看看XMLTYPE,我认为它比XMLPARSER更容易使用。不知道它是否会表现得更好。32K应该不会造成问题,但我已经看到使用MBs大小的XML的XMLTYPE存在性能问题。对于700 tps,我将考虑使用中端应用服务器来执行繁重的XML提升,并比较两种方法的性能。
REFDATA := '<ReferenceFields><ReferenceField><FieldKey>Name1</FieldKey> <FieldValue>ABCD</FieldValue></ReferenceField><ReferenceField><FieldKey>Name1</FieldKey><FieldValue>ABCD</FieldValue></ReferenceField></ReferenceFields>';
PARSER := XMLPARSER.NEWPARSER;
XMLPARSER.PARSEBUFFER(PARSER,REFDATA);
XMLDOC := XMLPARSER.GETDOCUMENT(PARSER);
NODELIST := XMLDOM.GETELEMENTSBYTAGNAME(XMLDOC, 'ReferenceField');
NODELENGTH := XMLDOM.GETLENGTH(NODELIST);
FOR i IN 0..NODELENGTH-1 LOOP
XMLDOM.WRITETOBUFFER(XMLDOM.ITEM(NODELIST, i), REFDATAPART);
arr.EXTEND();
arr(arr.COUNT) := XMLSequence(XMLTYPE(REFDATAPART));
END LOOP;
FORALL i IN arr.FIRST..arr.LAST
INSERT INTO HTS_TRANSACTION_XREF(TRANS_ID,XREF_FIELD, XREF_VALUE)
SELECT
'1',
EXTRACTVALUE(arr(i), '/ReferenceField/FieldKey') "FIELDKEY",
EXTRACTVALUE(arr(i), '/ReferenceField/FieldValue') "FIELDVALUE"
FROM
dual
WHERE
NOT EXISTS (
SELECT 1 FROM TRANSACTION_CROSSREFERENCE
WHERE
TRANS_ID = '1'
AND XREF_FIELD = EXTRACTVALUE(arr(i), '/ReferenceField/FieldKey')
AND XREF_VALUE = EXTRACTVALUE(arr(i), '/ReferenceField/FieldValue')
);
XMLPARSER.FREEPARSER(PARSER);