Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在PL/SQL中解析大型XML(>4k)_Xml_Oracle_Xmltype - Fatal编程技术网

在PL/SQL中解析大型XML(>4k)

在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; 开始 结束 此查询工作

我得到一个长度约为30k的xml。我必须从这个xml中提取键和值对,并插入到表中。还必须避免表中的重复行。以下是我提出的问题:

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);