之後直接調用過程相比花費很多時間我有一個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驗證約束。我已經使用禁用觸發器進行了測試,插入速度非常快。 –