之后直接调用过程相比花费很多时间我有一个INSERT触发器调用我的过程来处理STAGE_TBL的XMLTYPE字段中的XML并将数据插入到PROCESSED_DATA_TBL中 为了根据处理XML的结果更新STAGE_TBL行上的状态,我必须使用INSERT触发器之前(我也可以使用Compound Trigger,但我没有尝试过)。INSERT触发器之前的性能问题,与插入
我遇到的问题是我的XML是巨大的它可以有大约100 - 2000 rp_sendRow块,如果是巨大的,则触发正在采取这么多的时间。我尝试了100 rp_sendRow,大约需要4分钟才能触发。 但是,如果我禁用触发器并插入STAGE_TBL,然后使用该ID为新插入的记录调用XML_PROCESS,那么它将在不到一秒的时间内从SQL Developer完成(处理XML并插入PROCESSED_DATA_TBL)。
我无法使用常规SQL从SQL Developer中插入巨大的XML,因为有4000个字符限制,因为数据库不在我的本地,我甚至不能使用XMLType(bfilename('XMLDIR','MY.xml' )选项,这样我使用JDBC代码中插入大量XML。
我呼吁直接从JDBC的XML_PROCESS为相同的XML,它比第二耗时还不到处理和插入PROCESSED_DATA_TBL
请让我知道为什么触发需要时间?
我使用的是Oracle 11g,SQL开发4.1.0.19
--Trigger Code
create or replace TRIGGER STAGE_TRIGGER
BEFORE INSERT ON STAGE_TBL
FOR EACH ROW
DECLARE
ROW_COUNT NUMBER;
PROCESS_STATUS VARCHAR2(1);
STATUS_DESCRIPTION VARCHAR2(300);
BEGIN
XML_PROCESS(:NEW.ID, :NEW.XML_DOCUMENT, PROCESS_STATUS, STATUS_DESCRIPTION, ROW_COUNT);
IF(ROW_COUNT > 0) THEN
:NEW.STATUS := PROCESS_STATUS;
:NEW.STATUS_DATE := SYSDATE;
:NEW.STATUS_DESCRIPTION := STATUS_DESCRIPTION;
:NEW.SHRED_TS := SYSTIMESTAMP;
ELSE--This is to handle 0 records inserted scenario & exception scenarios
:NEW.STATUS := STATUS.ERROR;
:NEW.STATUS_DATE := SYSDATE;
:NEW.STATUS_DESCRIPTION := STATUS_DESCRIPTION;
END IF;
EXCEPTION
WHEN OTHERS THEN
:NEW.STATUS := PROCESS_STATUS;
:NEW.STATUS_DESCRIPTION := STATUS_DESCRIPTION;
NULL;
END STAGE_TRIGGER;
--Stored Procedure
create or replace PROCEDURE XML_PROCESS (ID IN RAW, xData IN XMLTYPE, PROCESS_STATUS OUT VARCHAR2, STATUS_DESCRIPTION OUT VARCHAR2, ROW_COUNT OUT NUMBER) AS
BEGIN
INSERT ALL INTO PROCESSED_DATA_TBL
(ID,
STORE,
SALES_NBR,
UNIT_COST,
ST_FLAG,
ST_DATE,
ST,
START_QTY,
START_VALUE,
START_ON_ORDER,
HAND,
ORDER,
COMMITED,
SALES,
RECEIVE,
VALUE,
COST,
ID_1,
ID_2,
ID_3,
UNIT_PRICE,
EFFECTIVE_DATE,
STATUS,
STATUS_DATE,
STATUS_REASON)
VALUES (ID
,storenbr
,SalesNo
,UnitCost
,StWac
,StDt
,St
,StartQty
,StartValue
,StartOnOrder
,Hand
,Order
,Commit
,Sales
,Rec
,Value
,Id1
,Id2
,Id3
,UnitPrice
,to_Date(EffectiveDate||' '||EffectiveTime, 'YYYY-MM-DD HH24:MI:SS')
,'N'
,SYSDATE
,'XML PROCESS INSERT')
SELECT E.* FROM XMLTABLE('rp_send/rp_sendRow' PASSING xData COLUMNS
store VARCHAR(20) PATH 'store'
,SalesNo VARCHAR(20) PATH 'sales'
,UnitCost NUMBER PATH 'cost'
,StWac VARCHAR(20) PATH 'flag'
,StDt DATE PATH 'st-dt'
,St NUMBER PATH 'st'
,StartQty NUMBER PATH 'qty'
,StartValue NUMBER PATH 'value'
,StartOnOrder NUMBER PATH 'order'
,Hand NUMBER PATH 'hand'
,Order NUMBER PATH 'order'
,Commit NUMBER PATH 'commit'
,Sales NUMBER PATH 'sales'
,Rec NUMBER PATH 'rec'
,Value NUMBER PATH 'val'
,Id1 VARCHAR(30) PATH 'id-1'
,Id2 VARCHAR(30) PATH 'id-2'
,Id3 VARCHAR(30) PATH 'id-3'
,UnitPrice NUMBER PATH 'unit-pr'
,EffectiveDate VARCHAR(30) PATH 'eff-dt'
,EffectiveTime VARCHAR(30) PATH 'eff-tm'
) E;
ROW_COUNT := SQL%ROWCOUNT;
PROCESS_STATUS := STATUS.PROCESSED;
STATUS_DESCRIPTION := ROW_COUNT || ' Rows Successfully Inserted ';
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
BEGIN
ROW_COUNT := 0;
PROCESS_STATUS := STATUS.ERROR;
STATUS_DESCRIPTION := SUBSTR(SQLERRM, 1, 250);
END;
WHEN OTHERS THEN
BEGIN
ROW_COUNT := 0;
PROCESS_STATUS := STATUS.ERROR;
STATUS_DESCRIPTION := SUBSTR(SQLERRM, 1, 250);
END;
END XML_PROCESS;
--Standalone Procedure calling XML_PROCESS
SET DEFINE OFF
DECLARE
ROW_COUNT NUMBER;
PROCESS_STATUS VARCHAR2(1);
STATUS_DESCRIPTION VARCHAR2(300);
V_ID NUMBER;
V_XML XMLTYPE;
BEGIN
SELECT ID, XML_DOCUMENT INTO V_ID, V_XML FROM STAGE_TBL WHERE ID = '7954';
XML_PROCESS(ID, V_XML, PROCESS_STATUS, STATUS_DESCRIPTION, ROW_COUNT);
update STAGE_TBL SET STATUS = PROCESS_STATUS,
STATUS_DATE = SYSDATE,
STATUS_DESCRIPTION = STATUS_DESCRIPTION
WHERE ID = V_ID;
END;
XML
<?xml version = \"1.0\" encoding = \"UTF-8\"?>
<rp_send xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">
<rp_sendRow>
<store>0123</store>
<sales>022399190</sales>
<cost>0.01</cost>
<flag>true</flag>
<st-dt>2013-04-19</st-dt>
<st>146.51</st>
<qty>13.0</qty>
<value>0.0</value>
<order>0.0</order>
<hand>0.0</hand>
<order>0.0</order>
<commit>0.0</commit>
<sales>0.0</sales>
<rec>0.0</rec>
<val>0.0</val>
<id-1/>
<id-2/>
<id-3/>
<unit-pr>13.0</unit-pr>
<eff-dt>2015-06-16</eff-dt>
<eff-tm>09:12:21</eff-tm>
</rp_sendRow>
</rp_send>
我已经测试了独立的程序来处理XML文件,它不是来自任何表和被处决非常类似于从STAGE_TBL中获取的那个。我已经使用JDBC直接调用存储过程,以便将大量的XML作为输入发送到过程。 –
@ java-ocean我已经包含了第三个可能的答案。请测试它。 – acesargl
感谢您的回复,我的STAGE_TBL没有XML验证约束。我已经使用禁用触发器进行了测试,插入速度非常快。 –