通过XML的方式来Update/Insert/Delete表是一种很奇妙的功能,Oracle为此给PL/SQL提供了两个包:DBMS_XMLSave和DBMS_XMLStore。从某些方面看,使用XML方式来提交数据比拼装SQL更有优势,特别是大批量的数据更新时。
DBMS_XMLSave和DBMS_XMLStore提供了相似的功能,不过前者调用的是Java接口,后者调用的是C。江湖传言DBMS_XMLStore比DBMS_XMLSave更高效,不过也有例外,我们看下面的代码:
CREATE TABLE T(X INT);
DECLARE
xml_data XMLTYPE := XMLTYPE('
1
2
3
4
5
6
7
8
');
c PLS_INTEGER;
BEGIN
c := dbms_xmlstore.newContext('T');
c := dbms_xmlstore.insertXML(c, xml_data);
c := dbms_xmlsave.newContext('T');
dbms_xmlsave.setBatchSize(c, 1000);
c := dbms_xmlsave.insertXML(c, xml_data.getstringval);
END;
/
通过分析其Trace日志,会发现dbms_xmlstore使用非绑定变量的方式来循环插入数据,例如:
SQL ID: 1ppj91r1bg67x Plan Hash: 0
INSERT INTO T ("X")
VALUES
('1')
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.04 0 0 0 0
Execute 1 0.00 0.00 1 1 4 1
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 0.00 0.04 1 1 4 1
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 101 (recursive depth: 1)
Number of plan statistics captured: 1
Rows (1st) Rows (avg) Rows (max) Row Source Operation
---------- ---------- ---------- ---------------------------------------------------
0 0 0 LOAD TABLE CONVENTIONAL (cr=1 pr=1 pw=0 time=244 us)
********************************************************************************
SQL ID: 1t35m8v9kmxn1 Plan Hash: 0
INSERT INTO T ("X")
VALUES
('2')
.......
而Dbms_XMLSave却使用的是通过绑定变量作Bulk Insert,如下:
SQL ID: fmxba6axp3x8u Plan Hash: 0
insert into T ("X")
values
(:1)
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 1 4 8
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 0.00 0.00 0 1 4 8
所以,在排除Java在第一次使用所需要的预编译时间之外,这种大批量的操作,DBMS_XMLSave显得更高效。这种情况对Update同样有效。
为了解决DBMS_XMLStore在更新时不绑定变量的情况出现,Oracle为这个包提供了setUpdateColumn方法。只要通过该方法指明所有需要Update/Insert的列的列名,DBMS_XMLStore就支持绑定变量操作了。例如:
DECLARE
xml_data XMLTYPE := XMLTYPE('
1
2
3
4
5
6
7
8
');
c PLS_INTEGER;
BEGIN
c := dbms_xmlstore.newContext('T');
dbms_xmlstore.setUpdateColumn(c,'X');
c := dbms_xmlstore.insertXML(c, xml_data);
END;
/
-------------------------------------------------------------------------------
SQL ID: 1pz57j7y6yngc Plan Hash: 0
INSERT INTO T ("X")
VALUES
(:1)
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 8 0.00 0.00 0 1 10 8
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 9 0.00 0.00 0 1 10 8
令人遗憾的是,通过上面的报告(execute count = 8),我们看到它只是绑定了变量,却不支持Bulk Insert。
另外,DBMS_XMLSave支持XSLT2.0转换功能,通过dbms_xmlsave.setXSLT,可以在insert/delete/updateXML之前先对输入的XML文本进行转换,再执行DML。同样支持XSLT 2.0的还有DBMS_XMLQuery.这是Oracle 10g/11g提供给PL/SQL的为数极少的支持XSLT 2.0特性的功能包之一。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/7836777/viewspace-722851/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/7836777/viewspace-722851/