【发布时间】:2011-11-08 19:22:50
【问题描述】:
我得到一个长度约为 30k 的 xml。我必须从这个 xml 中提取键和值对并插入到表中。还必须避免表中的重复行。这是我想出的查询:
DECLARE
PARSER XMLPARSER.PARSER;
XMLDOC XMLDOM.DOMDOCUMENT;
NODELIST XMLDOM.DOMNODELIST;
REFDATA VARCHAR2(32767);
REFDATAPART VARCHAR2(32767);
NODELENGTH NUMBER;
开始
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);
INSERT INTO
HTS_TRANSACTION_XREF(TRANS_ID,XREF_FIELD, XREF_VALUE)
SELECT
'1',
EXTRACTVALUE(COLUMN_VALUE, '/ReferenceField/FieldKey') "FIELDKEY",
EXTRACTVALUE(COLUMN_VALUE, '/ReferenceField/FieldValue') "FIELDVALUE"
FROM
TABLE(XMLSequence(XMLTYPE(REFDATAPART))) REFDATA
WHERE
NOT EXISTS (SELECT 1 from TRANSACTION_CROSSREFERENCE WHERE TRANS_ID='1' AND XREF_FIELD=EXTRACTVALUE(column_value, '/ReferenceField/FieldKey') AND XREF_VALUE=EXTRACTVALUE(column_value, '/ReferenceField/FieldValue'));
END LOOP;
XMLPARSER.FREEPARSER(PARSER);
结束;
此查询运行良好,最终将成为 sproc 的一部分。
这里我有两个问题:
1- 这是处理最大大小为 32k 的大型 xml 的正确方法吗?
2- 这是否足以在一秒钟内处理 700 个呼叫?
谢谢, 态度
【问题讨论】:
-
"2- 这是否足够高效以在一秒钟内处理 700 个呼叫?" - 这是在什么硬件上运行,还有什么其他的东西在上面运行,等等。这是一个只有你能回答的问题。就个人而言,我不会在数据库中进行这种处理,而是在应用程序服务器中进行,您可以更好(并且更便宜)扩展以满足您的要求。
-
您还可以查看 XMLTYPE,在我看来,它比 XMLPARSER 更易于使用。不知道它是否会表现得更好。 32K 应该不会造成问题,但是我在 XMLTYPE 中看到了使用大小为 MB 的 XML 的性能问题。对于 700 tps,我会考虑使用中间层应用服务器来完成繁重的 XML 提升并比较两种方法的性能。