Xml ORA-31181:PL/SQL DOM句柄访问不再可用的节点
我试图从oraclesql表中提取数据,当我将write-to文件放在循环之外时,该表工作到一定程度,如下面的示例所示。但在下面的代码中,当我将写文件放入循环中时,它出现了ORA-31181错误 我试图在更大范围内做的是通过写入clob将XML加载到文件中,每次循环时将其输出到平面文件中Xml ORA-31181:PL/SQL DOM句柄访问不再可用的节点,xml,oracle,plsql,oracle11g,Xml,Oracle,Plsql,Oracle11g,我试图从oraclesql表中提取数据,当我将write-to文件放在循环之外时,该表工作到一定程度,如下面的示例所示。但在下面的代码中,当我将写文件放入循环中时,它出现了ORA-31181错误 我试图在更大范围内做的是通过写入clob将XML加载到文件中,每次循环时将其输出到平面文件中 DECLARE -- this version of code works as the write to is outside loop l_file UTL_FILE.FILE_TYPE; l_
DECLARE -- this version of code works as the write to is outside loop
l_file UTL_FILE.FILE_TYPE;
l_clob CLOB;
l_buffer VARCHAR2(32767);
l_amount BINARY_INTEGER := 32767;
l_pos INTEGER := 1;
l_extract_dir CONSTANT dba_directories.directory_name%TYPE:= 'REPORTS_OUT_DIR'; -- \\data2\data\download\d7prdv1\prsrepreports
l_xmltype XMLTYPE;
l_domdoc dbms_xmldom.DOMDocument;
l_root_node dbms_xmldom.DOMNode;
l_message_node dbms_xmldom.DOMNode;
l_production_element dbms_xmldom.DOMElement;
l_production_node dbms_xmldom.DOMNode;
-- production XML elements, node, text
l_prod_element dbms_xmldom.DOMElement;
l_prod_node dbms_xmldom.DOMNode;
l_prod_t_node dbms_xmldom.DOMNode;
l_prod_text dbms_xmldom.DOMText;
-- production XML elements, node, text, node
CURSOR c_production
IS SELECT prod.cre_surr_id as cre_surr_id
, prod.production_type as prodCategoryType
from productions prod
where prod.cre_surr_id in (1753959927,1753959929);
BEGIN
UTL_FILE.FCLOSE_ALL;
l_file := UTL_FILE.fopen(l_extract_dir , 'Sample2.dat', 'w', 32767);
-- Create an empty XML document
l_domdoc := dbms_xmldom.newDomDocument;
-- Create a root node
l_root_node := dbms_xmldom.makeNode(l_domdoc);
-- Create a message root node
l_message_node := dbms_xmldom.appendChild( l_root_node
, dbms_xmldom.makeNode(dbms_xmldom.createElement(l_domdoc, 'message' ))
);
FOR production_rec in c_production LOOP
l_production_element := dbms_xmldom.createElement(l_domdoc, 'production' );
l_production_node := dbms_xmldom.appendChild(l_message_node,dbms_xmldom.makeNode(l_production_element));
-- prodCategoryType
l_prod_element := dbms_xmldom.createElement(l_domdoc, 'prodCategoryType' );
l_prod_node := dbms_xmldom.appendChild(l_production_node,dbms_xmldom.makeNode(l_prod_element));
l_prod_text := dbms_xmldom.createTextNode(l_domdoc, production_rec.prodCategoryType );
l_prod_t_node := dbms_xmldom.appendChild(l_prod_node,dbms_xmldom.makeNode(l_prod_text));
END LOOP;
l_xmltype := dbms_xmldom.getXmlType(l_domdoc);
dbms_xmldom.freeDocument(l_domdoc);
l_clob := l_xmltype.getClobVal;
DBMS_LOB.read (l_clob, l_amount, l_pos, l_buffer);
UTL_FILE.put(l_file, l_buffer);
l_pos := l_pos + l_amount;
UTL_FILE.fclose(l_file);
END;
下面的代码在我将write to文件放入循环时创建了一条错误消息
DECLARE -- this version of code works as the write to is outside loop
l_file UTL_FILE.FILE_TYPE;
l_clob CLOB;
l_buffer VARCHAR2(32767);
l_amount BINARY_INTEGER := 32767;
l_pos INTEGER := 1;
l_extract_dir CONSTANT dba_directories.directory_name%TYPE:= 'REPORTS_OUT_DIR'; -- \\data2\data\download\d7prdv1\prsrepreports
l_xmltype XMLTYPE;
l_domdoc dbms_xmldom.DOMDocument;
l_root_node dbms_xmldom.DOMNode;
l_message_node dbms_xmldom.DOMNode;
l_production_element dbms_xmldom.DOMElement;
l_production_node dbms_xmldom.DOMNode;
-- production XML elements, node, text
l_prod_element dbms_xmldom.DOMElement;
l_prod_node dbms_xmldom.DOMNode;
l_prod_t_node dbms_xmldom.DOMNode;
l_prod_text dbms_xmldom.DOMText;
-- production XML elements, node, text, node
CURSOR c_production
IS SELECT prod.cre_surr_id as cre_surr_id
, prod.production_type as prodCategoryType
from productions prod
where prod.cre_surr_id in (1753959927,1753959929);
BEGIN
UTL_FILE.FCLOSE_ALL;
l_file := UTL_FILE.fopen(l_extract_dir , 'Sample2.dat', 'w', 32767);
-- Create an empty XML document
l_domdoc := dbms_xmldom.newDomDocument;
-- Create a root node
l_root_node := dbms_xmldom.makeNode(l_domdoc);
-- Create a message root node
l_message_node := dbms_xmldom.appendChild( l_root_node
, dbms_xmldom.makeNode(dbms_xmldom.createElement(l_domdoc, 'message' ))
);
FOR production_rec in c_production LOOP
l_production_element := dbms_xmldom.createElement(l_domdoc, 'production' );
l_production_node := dbms_xmldom.appendChild(l_message_node,dbms_xmldom.makeNode(l_production_element));
-- prodCategoryType
l_prod_element := dbms_xmldom.createElement(l_domdoc, 'prodCategoryType' );
l_prod_node := dbms_xmldom.appendChild(l_production_node,dbms_xmldom.makeNode(l_prod_element));
l_prod_text := dbms_xmldom.createTextNode(l_domdoc, production_rec.prodCategoryType );
l_prod_t_node := dbms_xmldom.appendChild(l_prod_node,dbms_xmldom.makeNode(l_prod_text));
END LOOP;
l_xmltype := dbms_xmldom.getXmlType(l_domdoc);
dbms_xmldom.freeDocument(l_domdoc);
l_clob := l_xmltype.getClobVal;
DBMS_LOB.read (l_clob, l_amount, l_pos, l_buffer);
UTL_FILE.put(l_file, l_buffer);
l_pos := l_pos + l_amount;
UTL_FILE.fclose(l_file);
END;
下面是错误消息
第1行出错
ORA-31181:PL/SQL DOM句柄访问不再可用的节点
ORA-06512:“XDB.DBMS_XMLDOM”,第4735行
ORA-06512:“XDB.DBMS_XMLDOM”,第4762行
ORA-06512:在第52行
DECLARE -- this version of code DOES not work and creates the ORA-31181 error
l_file UTL_FILE.FILE_TYPE;
l_clob CLOB;
l_buffer VARCHAR2(32767);
l_amount BINARY_INTEGER := 32767;
l_pos INTEGER := 1;
l_extract_dir CONSTANT dba_directories.directory_name%TYPE:= 'REPORTS_OUT_DIR'; -- \\data2\data\download\d7prdv1\prsrepreports
l_xmltype XMLTYPE;
l_domdoc dbms_xmldom.DOMDocument;
l_root_node dbms_xmldom.DOMNode;
l_message_node dbms_xmldom.DOMNode;
l_production_element dbms_xmldom.DOMElement;
l_production_node dbms_xmldom.DOMNode;
-- production XML elements, node, text
l_prod_element dbms_xmldom.DOMElement;
l_prod_node dbms_xmldom.DOMNode;
l_prod_t_node dbms_xmldom.DOMNode;
l_prod_text dbms_xmldom.DOMText;
-- production XML elements, node, text, node
CURSOR c_production
IS SELECT prod.cre_surr_id as cre_surr_id
, prod.production_type as prodCategoryType
from productions prod
where prod.cre_surr_id in (1753959927,1753959929);
BEGIN
UTL_FILE.FCLOSE_ALL;
l_file := UTL_FILE.fopen(l_extract_dir , 'Sample2.dat', 'w', 32767);
-- Create an empty XML document
l_domdoc := dbms_xmldom.newDomDocument;
-- Create a root node
l_root_node := dbms_xmldom.makeNode(l_domdoc);
-- Create a message root node
l_message_node := dbms_xmldom.appendChild( l_root_node
, dbms_xmldom.makeNode(dbms_xmldom.createElement(l_domdoc, 'message' ))
);
FOR production_rec in c_production LOOP
l_production_element := dbms_xmldom.createElement(l_domdoc, 'production' );
l_production_node := dbms_xmldom.appendChild(l_message_node,dbms_xmldom.makeNode(l_production_element));
-- prodCategoryType
l_prod_element := dbms_xmldom.createElement(l_domdoc, 'prodCategoryType' );
l_prod_node := dbms_xmldom.appendChild(l_production_node,dbms_xmldom.makeNode(l_prod_element));
l_prod_text := dbms_xmldom.createTextNode(l_domdoc, production_rec.prodCategoryType );
l_prod_t_node := dbms_xmldom.appendChild(l_prod_node,dbms_xmldom.makeNode(l_prod_text));
l_xmltype := dbms_xmldom.getXmlType(l_domdoc);
dbms_xmldom.freeDocument(l_domdoc);
l_clob := l_xmltype.getClobVal;
DBMS_LOB.read (l_clob, l_amount, l_pos, l_buffer);
UTL_FILE.put(l_file, l_buffer);
l_pos := l_pos + l_amount;
END LOOP;
UTL_FILE.fclose(l_file);
END;
最简单的方法
begin
for rec in ( SELECT xmlserialize(content xmlelement("production",
xmlelement("prodCategoryType",prod.production_type)) as varchar2(4000)) val from productions prod ) loop
dbms_output.put_line(rec.val) ;
end loop;
end;
或者在代码中添加v_temp DBMS_XMLDOM.DOMNODE声明中的代码>并替换dbms_xmldom.freeDocument(l_domdoc)带有temp:=DBMS_XMLDOM.REMOVECHILD(l_消息节点、l_生产节点)的code>编码>最简单的方法
begin
for rec in ( SELECT xmlserialize(content xmlelement("production",
xmlelement("prodCategoryType",prod.production_type)) as varchar2(4000)) val from productions prod ) loop
dbms_output.put_line(rec.val) ;
end loop;
end;
或者在代码中添加v_temp DBMS_XMLDOM.DOMNODE声明中的代码>并替换dbms_xmldom.freeDocument(l_domdoc)带有temp:=DBMS_XMLDOM.REMOVECHILD(l_消息节点、l_生产节点)的code>代码>因为这一行<代码>dbms_xmldom.freeDocument(l_domdoc)那么dbms_xmldom.freeDocument(l_domdoc)实际上摆脱了什么呢?它是XML文档结构还是删除了该结构中的数据?释放/销毁整个XML结构。为什么要在循环内写入文件?因为我将获得大约100万条记录,这将大于clob最大大小,所以我需要将clob写入文件,然后释放clob以获取更多XML数据。如果有更简单的方法,我会做的。因为这条线<代码>dbms_xmldom.freeDocument(l_domdoc)那么dbms_xmldom.freeDocument(l_domdoc)实际上摆脱了什么呢?它是XML文档结构还是删除了该结构中的数据?释放/销毁整个XML结构。为什么要在循环内写入文件?因为我将获得大约100万条记录,这将大于clob最大大小,所以我需要将clob写入文件,然后释放clob以获取更多XML数据。如果有更简单的方法,我会做的。