我继承了一个在后端使用 Oracle 数据库的应用程序。该数据库最初使用的是完整版的 Oracle,但我们已将其移至 Oracle XE。Oracle XE 似乎不支持 Oracle XML SQL 实用程序(包括 DBMS_XMLSave),或者至少我无法弄清楚如何安装它。
根据此链接(http://ellebaek.wordpress.com/2011/01/27/converting-between-oracle-data-and-xml/):
与 DBMS_XMLQUERY 一样,DBMS_XMLSAVE 是用 Java 实现的,因此 Oracle Database Express Edition 不支持它。
数据库中的存储过程使用 DBMS_XMLSave,但从这个链接 ( https://forums.oracle.com/forums/thread.jspa?threadID=530048 ) 看来 DBMS_XMLSave 已被 DBMS_XMLStore 取代:
DBMS_XMLSTORE PL/SQL 包是在 Oracle 数据库 10g 第 1 版中引入的。该包根据 XML 文档的内容对数据库内的关系表或对象表执行 DML 操作。
请注意,在 Oracle 数据库 10g 之前,此功能存在于另一个 PL/SQL 包中,称为 DBMS_XMLSAVE。
我尝试了链接中的解决方案:
CREATE OR REPLACE PUBLIC SYNONYM DBMS_XMLSAVE FOR DBMS_XMLSTORE;
GRANT EXECUTE ON DBMS_XMLSAVE TO PUBLIC;
这确实修复了大部分错误,但是我留下了一些问题行:
DBMS_XMLSave.setDateFormat(v_insCtx, 'MM/dd/yyyy');
DBMS_XMLSave.setBatchSize(v_updCtx, -1);
DBMS_XMLSave.setDateFormat(v_updCtx, 'MM/dd/yyyy');
DBMS_XMLStore 似乎不支持这些方法。挖掘我想我找到了解决setDateFormat的方法。根据此链接 ( http://ellebaek.wordpress.com/2011/01/27/converting-between-oracle-data-and-xml/ ) DBMS_XMLStore 使用 NLS 设置日期/时间值。此链接(http://www.tiplib.com/231/nls-parameter-session-logon-trigger)指出可以在这样的存储过程中更改 NLS 设置:
BEGIN
DBMS_SESSION.SET_NLS('NLS_DATE_FORMAT','YYYYMMDD');
COMMIT;
END;
所以我希望我可以像这样替换 setDateFormat 行:
-DBMS_XMLSave.setDateFormat(v_insCtx, 'MM/dd/yyyy'); -- remove
+DBMS_SESSION.SET_NLS('NLS_DATE_FORMAT','MM/dd/yyyy'); -- insert
我找不到 setBatchSize 的替代品。
所以我的问题是:
我是以正确的方式处理这个问题,还是有更好的方法?
DBMS_XMLSave.setDateFormat(v_insCtx, 'MM/dd/yyyy') -> DBMS_SESSION.SET_NLS('NLS_DATE_FORMAT','MM/dd/yyyy') 会改变工作吗?
是否有 setBatchSize 的替代品?是否需要更换 setBatchSize?
一般来说,如果有人问类似上述问题 2 的问题,我会告诉他们尝试并告诉我,但我目前无法编译代码,而且我没有已知的工作基线。我可以删除问题行,它可能会产生一些结果,但我不清楚结果是否正确。删除问题线并尝试检查结果将是我从这里开始的方法。
原代码如下:
procedure insert_xml(p_xmlDoc in clob, p_tableName in varchar2) is
v_insCtx DBMS_XMLSave.ctxType;
v_rows number;
begin
v_insCtx := DBMS_XMLSave.newContext(p_tableName); -- get the context handle
DBMS_XMLSave.setDateFormat(v_insCtx, 'MM/dd/yyyy'); -- set date format
v_rows := DBMS_XMLSave.insertXML(v_insCtx, p_xmlDoc); -- this inserts the document
DBMS_XMLSave.closeContext(v_insCtx); -- this closes the handle
exception
when OTHERS then
raise_application_error(-20001,'An error was encountered. - '||SQLCODE||' -ERROR- '||SQLERRM);
end insert_xml;
procedure update_xml(p_xmlDoc in clob, p_tableName in varchar2, p_key in varchar2) is
v_updCtx DBMS_XMLSave.ctxType;
v_rows number;
begin
v_updCtx := DBMS_XMLSave.newContext(p_tableName); -- get the context
DBMS_XMLSave.setBatchSize(v_updCtx, -1);
DBMS_XMLSave.setDateFormat(v_updCtx, 'MM/dd/yyyy'); -- set date format
DBMS_XMLSave.clearUpdateColumnList(v_updCtx); -- clear the update settings..
DBMS_XMLSave.setKeyColumn(v_updCtx, p_key); -- set EMPNO as key column
v_rows := DBMS_XMLSave.updateXML(v_updCtx, p_xmlDoc); -- update the table.
DBMS_XMLSave.closeContext(v_updCtx); -- close the context..!
exception
when OTHERS then
raise_application_error(-20001,'An error was encountered. - '||SQLCODE||' -ERROR- '||SQLERRM);
end update_xml;
感谢你的协助。