XML as CLOB parameter to procedure
I'm trying to insert data from an XML file into tables/columns via a stored procedure. The procedure is part is as follows:
create or replace procedure ParseSomeXMLTest
xmlDoc in CLOB, someID out int
as
doc xmldom.DOMDocument;
parser xmlparser.Parser;
begin
parser := xmlparser.newParser;
xmlparser.parseClob(parser, xmlDoc);
doc := xmlparser.getDocument(parser);
xmlparser.freeParser(parser);
When I call parseClob I get an ORA-20100 error complaining about the syntax of the XML file. If I cut my XML down to < 32K it works just fine.
If I write the CLOB to disk, read it out again and process it, it also works, as follows:
create or replace procedure ParseSomeXMLTest
xmlDoc in CLOB, someID out int
as
doc xmldom.DOMDocument;
parser xmlparser.Parser;
test CLOB;
begin
insert into junk values(xmlDoc);
commit;
select xmldata into test from junk;
delete from junk;
commit;
parser := xmlparser.newParser;
xmlparser.parseClob(parser, test);
doc := xmlparser.getDocument(parser);
xmlparser.freeParser(parser);
The problem is that it's entirely too slow to insert the CLOB, select it back out again and delete it. It takes around 4 seconds to do that. It takes me less than 1 second to actually process the XML once it's parsed. Increasing my process by 4x isn't an option.
Since the parseClob works on a "CLOB" I can only assume that I'm not truly passing in a CLOB from my C++/C# applications. I've used both the ODP.NET and the Microsoft's Oracle .NET provider in C# and the Oracle OLEDB provider in C++.
Here's a sample of my C# code:
OracleConnection connect = new OracleConnection("Data Source=ds;user id=UID;password=PWD;");
connect.Open();
OracleCommand insCmd = new OracleCommand("ParseSomeXMLTest", connect);
insCmd.CommandType = CommandType.StoredProcedure;
OracleParameter param = insCmd.Parameters.Add("xmlDoc", OracleDbType.Clob);
param.Direction = ParameterDirection.Input;
StreamReader reader = File.OpenText("c:\\oracletest.xml");
param.Value = reader.ReadToEnd();
OracleParameter param2 = insCmd.Parameters.Add("someID", OracleDbType.Int32);
param2.Direction = ParameterDirection.Output;
insCmd.ExecuteNonQuery();
long id = Convert.ToInt32(param2.Value);
Anyone have any ideas?
Hey!
I'm using the samme stuff ... while calling from .NET (c#) , it give me the error.
"Wrong number of arguments"...
oraconn.Open();
// Create a oracle Command
OracleCommand oCmd = new OracleCommand();
oCmd.CommandType = CommandType.StoredProcedure;
oCmd.CommandText ="sp_CV_InsertXmldetails";
oCmd.Connection = oraconn;
OracleParameter inputParam;
inputParam =oCmd.Parameters.Add("param_xml",System.Data.OracleClient.OracleType.Clob);
inputParam.Direction = ParameterDirection.Input;
StreamReader rd1 = File.OpenText("c:\\clob.xml");
inputParam.Value = rd1.ReadToEnd();
oCmd.ExecuteNonQuery();
In the Sp
create or replace sp_CV_InsertXmldetails(param_xml in clob)
AS
BEGIN
// xml parsing stuf
END
Similar Messages
-
Passing the xml data as parameter to procedure
i have table like this
CREATE TABLE employeeDetails
EmpName VARCHAR2(50),
EmpSal INTEGER,
DeptNo INTEGER,
JoinDate DATE
i am getting the i/p data in xml format to extract data i saw the code in net.http://riteshk.blogspot.com/2008/09/sending-xml-string-as-input-parameter.html
CREATE OR REPLACE PROCEDURE Insert_Employee_Data (ip_emp_details IN XMLTYPE)
IS
BEGIN
FOR i IN
(SELECT XMLTYPE.EXTRACT (VALUE (a),
'/Root/EmpName/text()').getstringval
() AS ipempname,
XMLTYPE.EXTRACT (VALUE (a), '/Root/EmpSal/text()').getstringval
() AS ipempsal,
XMLTYPE.EXTRACT (VALUE (a), '/Root/DeptNo/text()').getstringval
() AS ipdeptno,
XMLTYPE.EXTRACT (VALUE (a),
'/Root/JoinDate/text()'
).getstringval () AS ipjoindate
FROM TABLE (XMLSEQUENCE (ip_emp_details.EXTRACT ('/EmployeeData/Root')
) a)
LOOP
INSERT INTO EMPLOYEEDETAILS
(empname, empsal, deptno, joindate
VALUES (i.ipempname, i.ipempsal, i.ipdeptno, i.ipjoindate
END LOOP;
END Insert_Employee_Data;
i want to test the procedure in database itself.
how to call the procedure in database to test that procedure by passing sample data.how to pass paratmeters while cakking that procedure in database itself to test that the procedure is working or not
/Thats the way you would test it:
SQL> create table employeedetails
empname varchar2 (50),
empsal integer,
deptno integer,
joindate date
Table created.
SQL> create or replace procedure insert_employee_data (ip_emp_details in xmltype)
is
begin
for i
in (select xmltype.extract (value (a),
'Root/EmpName/text()').getstringval ()
as ipempname,
xmltype.extract (value (a),
'Root/EmpSal/text()').getnumberval ()
as ipempsal,
xmltype.extract (value (a),
'Root/DeptNo/text()').getnumberval ()
as ipdeptno,
xmltype.extract (value (a),
'Root/JoinDate/text()').getstringval ()
as ipjoindate
from table(xmlsequence (
ip_emp_details.extract ('/EmployeeData/Root')
)) a)
loop
insert into employeedetails (empname,
empsal,
deptno,
joindate)
values (i.ipempname,
i.ipempsal,
i.ipdeptno,
to_date (i.ipjoindate, 'dd-mon-rrrr', 'nls_date_language=english'));
end loop;
end insert_employee_data;
Procedure created.
SQL> begin
insert_employee_data(xmltype('<?xml version=''1.0'' encoding=''utf-8'' ?>
<EmployeeData>
<Root>
<EmpName>Ritesh</EmpName>
<EmpSal>10000</EmpSal>
<DeptNo>1010</DeptNo>
<JoinDate>03-Apr-2006</JoinDate>
</Root>
<Root>
<EmpName>Rajiv</EmpName>
<EmpSal>20000</EmpSal>
<DeptNo>2020</DeptNo>
<JoinDate>05-May-2007</JoinDate>
</Root>
</EmployeeData>'));
end;
PL/SQL procedure successfully completed.
SQL> select * from employeedetails
EMPNAME EMPSAL DEPTNO JOINDATE
Ritesh 10000 1010 03.04.06
Rajiv 20000 2020 05.05.07
2 rows selected.Much better and more efficient is of course to completly avoid the loop and just use:
insert into employeedetails
select xmltype.extract (value (a),
'Root/EmpName/text()').getstringval ()
as ipempname,
xmltype.extract (value (a), 'Root/EmpSal/text()').getnumberval ()
as ipempsal,
xmltype.extract (value (a), 'Root/DeptNo/text()').getnumberval ()
as ipdeptno,
to_date (
xmltype.extract (value (a),
'Root/JoinDate/text()').getstringval (),
'dd-mon-rrrr',
'nls_date_language=english'
as ipjoindate
from table (
xmlsequence (ip_emp_details.extract ('/EmployeeData/Root'))
) a;
.... -
Date insertion from large XML document (clob) into relation table very slow
Hi Everybody!
I'm working with Oracle 9.2.0.5 on Microsoft Windows Server 2003 Enterprise Edition.
The server (a test server) is a Pentium 4 2.8 GHz, 1GB of RAM.
I use a procedure called PARITOP_TRAITERXMLRESULTMASSE to insert the data contained in the pXMLDOC clob parameter in the table pTABLENAME. (You can see the format of the XML document below). The first step on this procedure is to verify that the XML document is not empty. If not, the procedure needs to add a node in the document, in every <ROW> tag. This added node is named âRST_IDâ. Itâs the foreign key of each record. I can retrieve the value of each <RST_ID> node in an other table in which the data has been previously added (by the calling procedure). When each of the <ROW> elements has been treated, the PARITOP_INSERTXML procedure is called. This procedure uses DBMS_XMLSAVE.INSERTXML to insert the data contained in the XML document in the specified table.
(Below, you can see the code of my procedures.)
With this information, can you tell me why this treatment is very very very slow with a large XML document and how I can improve it?
Thank you for your help!
Anne-Marie
CREATE OR REPLACE PROCEDURE "PARITOP_TRAITERXMLRESULTMASSE" (
pPRC_ID IN PARITOP_PARC.PRC_ID%TYPE,
pRST_MONDE IN PARITOP_RESULTAT.RST_MONDE%TYPE,
pXMLDOC IN CLOB,
pTABLENAME IN VARCHAR2)
AS
Objectif :Insérer le contenu du XML passé en paramètre (pXMLDOC) à la table passée en paramètre (pTABLENAME)
La table passée en paramètre doit être une table ayant comme clé étrangère le champs "RST_ID" .
(Le noeud RST_ID est donc ajouté à tous les document XML. Ce rst_id est
déterminé à partir de la table PARITOP_RESULTAT grâce à pPRC_ID et
pRstMonde fournis en paramètre)
result_doc CLOB;
XMLDOMDOC XDB.DBMS_XMLDOM.DOMDOCUMENT;
NODE_ROWSET DBMS_XMLDOM.DOMNODE;
NODE_ROW DBMS_XMLDOM.DOMNODE;
vUE_ID PARITOP_RESULTAT.UE_ID%TYPE;
vRST_ID PARITOP_RESULTAT.RST_ID%TYPE;
nodeList DBMS_XMLDOM.DOMNODELIST;
BEGIN
BEGIN
vUE_ID := 0;
vRST_ID := 0;
XMLDOMDOC := DBMS_XMLDOM.NEWDOMDOCUMENT(pXMLDOC);
IF NOT GESTXML_PKG.FN_PARITOP_DOCUMENT_IS_NULL(XMLDOMDOC) THEN
NODE_ROWSET := DBMS_XMLDOM.item(DBMS_XMLDOM.GETCHILDNODES (DBMS_XMLDOM.MAKENODE(XMLDOMDOC)),0);
for i in 0..dbms_xmldom.getLength(DBMS_XMLDOM.getchildnodes(NODE_ROWSET))-1 loop
NODE_ROW := DBMS_XMLDOM.ITEM(DBMS_XMLDOM.GETCHILDNODES(NODE_ROWSET), i) ;
nodeList := DBMS_XMLDOM.GETELEMENTSBYTAGNAME(DBMS_XMLDOM.makeelement(NODE_ROW) , 'UE_ID');
IF vUE_ID <> DBMS_XMLDOM.GETNODEVALUE(DBMS_XMLDOM.GETFIRSTCHILD(DBMS_XMLDOM.ITEM(nodeList, 0))) THEN
vUE_ID := DBMS_XMLDOM.GETNODEVALUE(DBMS_XMLDOM.GETFIRSTCHILD(DBMS_XMLDOM.ITEM(nodeList, 0)));
--on ramasse le rst_id
SELECT RST_ID INTO vRST_ID
FROM PARITOP_RESULTAT RST
WHERE RST.PRC_ID = pPRC_ID
AND RST.UE_ID = vUE_ID
AND RST.RST_MONDE = pRST_MONDE
AND RST_A_SUPPRIMER = 0;
END IF;
GESTXML_PKG.PARITOP_ADDNODETOROW(XMLDOMDOC, NODE_ROW, 'RST_ID', vRST_ID);
end loop;
RESULT_DOC := ' '; --Ã garder, pour ne pas que ca fasse d'erreur lors du WriteToClob.
dbms_xmldom.writeToClob(DBMS_XMLDOM.MAKENODE(XMLDOMDOC), RESULT_DOC);
--Insertion du document XML dans la table "tableName"
GESTXML_PKG.PARITOP_INSERTXML(RESULT_DOC, pTABLENAME);
DBMS_XMLDOM.FREEDOCUMENT( XMLDOMDOC);
end if;
EXCEPTION
[â¦exception treatementâ¦]
END;
END;
The format of a XML clob is :
<ROWSET>
<ROW>
<PRC_ID>193</PRC_ID>
<UE_ID>8781</UE_ID>
<VEN_ID>6223</VEN_ID>
<RST_MONDE>0</RST_MONDE>
<CMP_SELMAN>0</CMP_SELMAN>
<CMP_INDICESELECTION>92.307692307692307</CMP_INDICESELECTION>
<CMP_PVRES>94900</CMP_PVRES>
<CMP_PVAJUSTE>72678.017699115066</CMP_PVAJUSTE>
<CMP_PVAJUSTEMIN>72678.017699115095</CMP_PVAJUSTEMIN>
<CMP_PVAJUSTEMAX>72678.017699115037</CMP_PVAJUSTEMAX>
<CMP_PV>148000</CMP_PV>
<CMP_VALROLE>129400</CMP_VALROLE>
<CMP_PVRESECART>4790</CMP_PVRESECART>
<CMP_PVRHAB>101778.01769911509</CMP_PVRHAB>
<CMP_UTILISE>1</CMP_UTILISE>
<CMP_TVM>1</CMP_TVM>
<CMP_PVA>148000</CMP_PVA>
</ROW>
<ROW>
<PRC_ID>193</PRC_ID>
<UE_ID>8781</UE_ID>
<VEN_ID>6235</VEN_ID>
<RST_MONDE>0</RST_MONDE>
<CMP_SELMAN>0</CMP_SELMAN>
<CMP_INDICESELECTION>76.92307692307692</CMP_INDICESELECTION>
<CMP_PVRES>117800</CMP_PVRES>
<CMP_PVAJUSTE>118080</CMP_PVAJUSTE>
<CMP_PVAJUSTEMIN>118080</CMP_PVAJUSTEMIN>
<CMP_PVAJUSTEMAX>118080</CMP_PVAJUSTEMAX>
<CMP_PV>172000</CMP_PV>
<CMP_VALROLE>134800</CMP_VALROLE>
<CMP_PVRESECART>0</CMP_PVRESECART>
<CMP_PVRHAB>147180</CMP_PVRHAB>
<CMP_UTILISE>1</CMP_UTILISE>
<CMP_TVM>1</CMP_TVM>
<CMP_PVA>172000</CMP_PVA>
</ROW>
</ROWSET>
PARITOP_COMPARABLE TABLE :
RST_ID NUMBER(10) NOT NULL,
VEN_ID NUMBER(10) NOT NULL,
CMP_SELMAN NUMBER(1) NOT NULL,
CMP_UTILISE NUMBER(1) NOT NULL,
CMP_INDICESELECTION FLOAT(53) NOT NULL,
CMP_PVRES FLOAT(53) NULL,
CMP_PVAJUSTE FLOAT(53) NULL,
CMP_PVRHAB FLOAT(53) NULL,
CMP_TVM FLOAT(53) NULL
ROCEDURE PARITOP_INSERTXML (xmlDoc IN clob, tableName IN VARCHAR2)
AS
insCtx DBMS_XMLSave.ctxType;
rowss number;
BEGIN
--permet d'insérer les champs du XML dans la table passée en paramètre.
--il suffit que les champs XML aient le même nom que les champs de la table
BEGIN
insCtx := DBMS_XMLSave.newContext(tableName); -- get context handle
DBMS_XMLSAVE.SETDATEFORMAT( insCtx, 'yyyy-MM-dd HH:mm:ss');--attention, case sensitive
DBMS_XMLSAVE.setIgnoreCase(insCtx, 1);
rowss := DBMS_XMLSAVE.INSERTXML(insCtx , xmlDoc);
DBMS_XMLSave.closeContext(insCtx);
EXCEPTION
[â¦]
END;
END;
PROCEDURE PARITOP_ADDNODETOROW (
XMLDOMDOC DBMS_XMLDOM.DOMDOCUMENT,
NODE_ROW dbms_xmldom.DOMNode,
NOM_NOEUD VARCHAR2,
VALEUR_NOEUD VARCHAR2)
AS
--PERMET D'AJOUTER UN NOEUD AVEC 1 SEULE VALEUR DANS une ROW D'UN XML.
--UTILE SURTOUT POUR LES CLÃS ÃTRANGÃRES
domElemAInserer DBMS_XMLDOM.DOMELEMENT;
NODE dbms_xmldom.DOMNode;
NODE_TMP dbms_xmldom.DOMNode;
BEGIN
domElemAInserer := DBMS_XMLDOM.createElement(XMLDOMDOC, NOM_NOEUD) ;
NODE := DBMS_XMLDOM.MAKENODE(domElemAInserer); --cast
NODE := DBMS_XMLDOM.APPENDCHILD(NODE_ROW,NODE);
NODE_TMP := DBMS_XMLDOM.MAKENODE(DBMS_XMLDOM.CREATETEXTNODE(XMLDOMDOC, VALEUR_NOEUD ) );
NODE := DBMS_XMLDOM.APPENDCHILD(NODE,NODE_TMP );
END;Hi Everybody!
I'm working with Oracle 9.2.0.5 on Microsoft Windows Server 2003 Enterprise Edition.
The server (a test server) is a Pentium 4 2.8 GHz, 1GB of RAM.
I use a procedure called PARITOP_TRAITERXMLRESULTMASSE to insert the data contained in the pXMLDOC clob parameter in the table pTABLENAME. (You can see the format of the XML document below). The first step on this procedure is to verify that the XML document is not empty. If not, the procedure needs to add a node in the document, in every <ROW> tag. This added node is named âRST_IDâ. Itâs the foreign key of each record. I can retrieve the value of each <RST_ID> node in an other table in which the data has been previously added (by the calling procedure). When each of the <ROW> elements has been treated, the PARITOP_INSERTXML procedure is called. This procedure uses DBMS_XMLSAVE.INSERTXML to insert the data contained in the XML document in the specified table.
(Below, you can see the code of my procedures.)
With this information, can you tell me why this treatment is very very very slow with a large XML document and how I can improve it?
Thank you for your help!
Anne-Marie
CREATE OR REPLACE PROCEDURE "PARITOP_TRAITERXMLRESULTMASSE" (
pPRC_ID IN PARITOP_PARC.PRC_ID%TYPE,
pRST_MONDE IN PARITOP_RESULTAT.RST_MONDE%TYPE,
pXMLDOC IN CLOB,
pTABLENAME IN VARCHAR2)
AS
Objectif :Insérer le contenu du XML passé en paramètre (pXMLDOC) à la table passée en paramètre (pTABLENAME)
La table passée en paramètre doit être une table ayant comme clé étrangère le champs "RST_ID" .
(Le noeud RST_ID est donc ajouté à tous les document XML. Ce rst_id est
déterminé à partir de la table PARITOP_RESULTAT grâce à pPRC_ID et
pRstMonde fournis en paramètre)
result_doc CLOB;
XMLDOMDOC XDB.DBMS_XMLDOM.DOMDOCUMENT;
NODE_ROWSET DBMS_XMLDOM.DOMNODE;
NODE_ROW DBMS_XMLDOM.DOMNODE;
vUE_ID PARITOP_RESULTAT.UE_ID%TYPE;
vRST_ID PARITOP_RESULTAT.RST_ID%TYPE;
nodeList DBMS_XMLDOM.DOMNODELIST;
BEGIN
BEGIN
vUE_ID := 0;
vRST_ID := 0;
XMLDOMDOC := DBMS_XMLDOM.NEWDOMDOCUMENT(pXMLDOC);
IF NOT GESTXML_PKG.FN_PARITOP_DOCUMENT_IS_NULL(XMLDOMDOC) THEN
NODE_ROWSET := DBMS_XMLDOM.item(DBMS_XMLDOM.GETCHILDNODES (DBMS_XMLDOM.MAKENODE(XMLDOMDOC)),0);
for i in 0..dbms_xmldom.getLength(DBMS_XMLDOM.getchildnodes(NODE_ROWSET))-1 loop
NODE_ROW := DBMS_XMLDOM.ITEM(DBMS_XMLDOM.GETCHILDNODES(NODE_ROWSET), i) ;
nodeList := DBMS_XMLDOM.GETELEMENTSBYTAGNAME(DBMS_XMLDOM.makeelement(NODE_ROW) , 'UE_ID');
IF vUE_ID <> DBMS_XMLDOM.GETNODEVALUE(DBMS_XMLDOM.GETFIRSTCHILD(DBMS_XMLDOM.ITEM(nodeList, 0))) THEN
vUE_ID := DBMS_XMLDOM.GETNODEVALUE(DBMS_XMLDOM.GETFIRSTCHILD(DBMS_XMLDOM.ITEM(nodeList, 0)));
--on ramasse le rst_id
SELECT RST_ID INTO vRST_ID
FROM PARITOP_RESULTAT RST
WHERE RST.PRC_ID = pPRC_ID
AND RST.UE_ID = vUE_ID
AND RST.RST_MONDE = pRST_MONDE
AND RST_A_SUPPRIMER = 0;
END IF;
GESTXML_PKG.PARITOP_ADDNODETOROW(XMLDOMDOC, NODE_ROW, 'RST_ID', vRST_ID);
end loop;
RESULT_DOC := ' '; --Ã garder, pour ne pas que ca fasse d'erreur lors du WriteToClob.
dbms_xmldom.writeToClob(DBMS_XMLDOM.MAKENODE(XMLDOMDOC), RESULT_DOC);
--Insertion du document XML dans la table "tableName"
GESTXML_PKG.PARITOP_INSERTXML(RESULT_DOC, pTABLENAME);
DBMS_XMLDOM.FREEDOCUMENT( XMLDOMDOC);
end if;
EXCEPTION
[â¦exception treatementâ¦]
END;
END;
The format of a XML clob is :
<ROWSET>
<ROW>
<PRC_ID>193</PRC_ID>
<UE_ID>8781</UE_ID>
<VEN_ID>6223</VEN_ID>
<RST_MONDE>0</RST_MONDE>
<CMP_SELMAN>0</CMP_SELMAN>
<CMP_INDICESELECTION>92.307692307692307</CMP_INDICESELECTION>
<CMP_PVRES>94900</CMP_PVRES>
<CMP_PVAJUSTE>72678.017699115066</CMP_PVAJUSTE>
<CMP_PVAJUSTEMIN>72678.017699115095</CMP_PVAJUSTEMIN>
<CMP_PVAJUSTEMAX>72678.017699115037</CMP_PVAJUSTEMAX>
<CMP_PV>148000</CMP_PV>
<CMP_VALROLE>129400</CMP_VALROLE>
<CMP_PVRESECART>4790</CMP_PVRESECART>
<CMP_PVRHAB>101778.01769911509</CMP_PVRHAB>
<CMP_UTILISE>1</CMP_UTILISE>
<CMP_TVM>1</CMP_TVM>
<CMP_PVA>148000</CMP_PVA>
</ROW>
<ROW>
<PRC_ID>193</PRC_ID>
<UE_ID>8781</UE_ID>
<VEN_ID>6235</VEN_ID>
<RST_MONDE>0</RST_MONDE>
<CMP_SELMAN>0</CMP_SELMAN>
<CMP_INDICESELECTION>76.92307692307692</CMP_INDICESELECTION>
<CMP_PVRES>117800</CMP_PVRES>
<CMP_PVAJUSTE>118080</CMP_PVAJUSTE>
<CMP_PVAJUSTEMIN>118080</CMP_PVAJUSTEMIN>
<CMP_PVAJUSTEMAX>118080</CMP_PVAJUSTEMAX>
<CMP_PV>172000</CMP_PV>
<CMP_VALROLE>134800</CMP_VALROLE>
<CMP_PVRESECART>0</CMP_PVRESECART>
<CMP_PVRHAB>147180</CMP_PVRHAB>
<CMP_UTILISE>1</CMP_UTILISE>
<CMP_TVM>1</CMP_TVM>
<CMP_PVA>172000</CMP_PVA>
</ROW>
</ROWSET>
PARITOP_COMPARABLE TABLE :
RST_ID NUMBER(10) NOT NULL,
VEN_ID NUMBER(10) NOT NULL,
CMP_SELMAN NUMBER(1) NOT NULL,
CMP_UTILISE NUMBER(1) NOT NULL,
CMP_INDICESELECTION FLOAT(53) NOT NULL,
CMP_PVRES FLOAT(53) NULL,
CMP_PVAJUSTE FLOAT(53) NULL,
CMP_PVRHAB FLOAT(53) NULL,
CMP_TVM FLOAT(53) NULL
ROCEDURE PARITOP_INSERTXML (xmlDoc IN clob, tableName IN VARCHAR2)
AS
insCtx DBMS_XMLSave.ctxType;
rowss number;
BEGIN
--permet d'insérer les champs du XML dans la table passée en paramètre.
--il suffit que les champs XML aient le même nom que les champs de la table
BEGIN
insCtx := DBMS_XMLSave.newContext(tableName); -- get context handle
DBMS_XMLSAVE.SETDATEFORMAT( insCtx, 'yyyy-MM-dd HH:mm:ss');--attention, case sensitive
DBMS_XMLSAVE.setIgnoreCase(insCtx, 1);
rowss := DBMS_XMLSAVE.INSERTXML(insCtx , xmlDoc);
DBMS_XMLSave.closeContext(insCtx);
EXCEPTION
[â¦]
END;
END;
PROCEDURE PARITOP_ADDNODETOROW (
XMLDOMDOC DBMS_XMLDOM.DOMDOCUMENT,
NODE_ROW dbms_xmldom.DOMNode,
NOM_NOEUD VARCHAR2,
VALEUR_NOEUD VARCHAR2)
AS
--PERMET D'AJOUTER UN NOEUD AVEC 1 SEULE VALEUR DANS une ROW D'UN XML.
--UTILE SURTOUT POUR LES CLÃS ÃTRANGÃRES
domElemAInserer DBMS_XMLDOM.DOMELEMENT;
NODE dbms_xmldom.DOMNode;
NODE_TMP dbms_xmldom.DOMNode;
BEGIN
domElemAInserer := DBMS_XMLDOM.createElement(XMLDOMDOC, NOM_NOEUD) ;
NODE := DBMS_XMLDOM.MAKENODE(domElemAInserer); --cast
NODE := DBMS_XMLDOM.APPENDCHILD(NODE_ROW,NODE);
NODE_TMP := DBMS_XMLDOM.MAKENODE(DBMS_XMLDOM.CREATETEXTNODE(XMLDOMDOC, VALEUR_NOEUD ) );
NODE := DBMS_XMLDOM.APPENDCHILD(NODE,NODE_TMP );
END; -
Loading data from a CLOB Parameter
Hi,
we have a front end app, in .NET, that passes a file has a CLOB Parameter to an Oracle procedure. What is the beast way to load the content of the CLOB Parameter into an Oracle table? Can SQL LDR be used in this case? If not, how about the UTL FILE utility?
Thanks in advance,
MarcLAF wrote:
we have a front end app, in .NET, that passes a file has a CLOB Parameter to an Oracle procedure. What is the beast way to load the content of the CLOB Parameter into an Oracle table? Can SQL LDR be used in this case? If not, how about the UTL FILE utility?Both of these, SQL*Loader and UTL_FILE, works on external files in an o/s file system. The CLOB is a column value in a row in a database table.
If the CLOB is XML for example, that can be directly parsed into a XML DOM in Oracle. Other formats require one of two basic approaches.
Write a parser in PL/SQL to read the CLOB line by line, tokenise and parse it, and transform it into whatever structured output required. A pipe line table function can be used for this approach, allowing the process and transformation PL/SQL function to be treated as if it is a SQL table that SQL select can be used against.
The 2nd option is to unload the CLOB into an actual external o/s file and running whatever process against it to read, parse and process the file.
The basic approach that suits the requirement the best, depends entirely on the requirement itself. -
XML, XMLType, Clob???
Hi,
In our system we need to interface with an external system using an xml interface. We use a staging table that contains the data that is needed to collect data from our database. For this we used the xmlelement en xmlagg query in a stored procedure into a clob parameter. We are using ODP.net driver 9207.
We query chunks of 100 records from our staging table and retrieve the xml data calling our stored procedure. This will run ok for a while but after an unpredictable amount of time we got ORA-03127: no new operations allowed until the active operation ends.
We switched to an xmltype parameter, that seemed to solve that error. But now after app. 500 successful attempts our .net application crashes. We have correct error handling implemented but it does not even get there. I read about leaking xmltype later on, but I'm not sure if this could be the case. It is running on a server as a windows service.
The strange thing is that the exact same code runs fine on my machine (the famous last words....), same odp.net driver version, against the same database...
Well, we just want xml out of this Oracle database, calling a stored procedure and getting desperate....
Any advice?
Best regards,
RichardI found it!
After going through some posts on this forum, I found an example of the ODP.net team how to use xmltype.
It is crucial to call the dispose method of your parameters, yep I should have thought of that!.
We populated a parametercollection in our data access assembly to return to the client, but failed to dispose the parameter we retrieved the data from.
The explanation for the process not crashing on my laptop vs the service on a server could be that the server has 4 processors and is much faster. The .net garbage collector might not have been able to clear our objects?
Oh well, perhaps some unlucky wandering soul with xmltype problems reads this and can use this stuff ;-)
Richard -
How to set the root path of XML document when calling Inserting procedure
Hi,
I was create a procedure to insert XML Document in to DBMS Tables, but i am not able to set the Start root element in calling procedure.
My calling procedure is
exec insXmldoc('pmc_sample.xml', 'pmc')
When i am calling this procedure i got this error
11:23:54 Error: ORA-29532: Java call terminated by uncaught Java exception: oracle.xml.sql.OracleXMLSQLException: Start of root element expected.
ORA-06512: at "SYS.DBMS_XMLSAVE", line 65
ORA-06512: at "SCOTT.INSPROC", line 8
ORA-06512: at line 2
I am checking my XML file using XML Validator. My XML file was parsed with out errors.
Please give the solution,and tell me where i did wrong in my calling procedure.
suppose i have this XML file in local E drive ,how to set the path for that XML file in my calling procedure.Hi, I am doing the code likthis,please give the solution.
SQL> create or replace procedure insProc(xmlDoc IN CLOB, tableName IN VARCHAR2) is
2 insCtx DBMS_XMLSave.ctxType;
3 l_ctx dbms_xmlsave.ctxtype;
4 rows number;
5 begin
6 insCtx := DBMS_XMLSave.newContext(tableName); -- get the context handle
7 rows := DBMS_XMLSave.insertXML(insCtx,xmlDoc); -- this inserts the document
8 DBMS_XMLSave.closeContext(insCtx); -- this closes the handle
9 end;
10 /
Procedure created.
SQL> begin
2 insProc('/usr/tmp/ROWSET.xml', 'emp');
3 end;
4 /
begin
ERROR at line 1:
ORA-29532: Java call terminated by uncaught Java exception: oracle.xml.sql.OracleXMLSQLException:
Start of root element expected.
ORA-06512: at "SYS.DBMS_XMLSAVE", line 65
ORA-06512: at "SCOTT.INSPROC", line 7
ORA-06512: at line 2
Kishore B -
Migrating V9 to V10: Update XML Fragment CLOB does not work anymore
I have an XML Schema that contains an element, named Operazione, mapped to a CLOB.
I just migrate to Oracle 10.1.0.2.0 from version 9.2.0.2.0 and the code I developed does not work anymore.
To get a CLOB on v 9.2.0.2.0 I issued the following statement:
select extractValue(value(p),'/operazione.log/Operazione') from XMT_OPERAZIONE_LOG p
where existsNode(value(p),'/operazione.log/Journal[NumeroElettronico=1234567890]') = 1
To make it working on V10 I have to change it as follow:
select extract(value(p),'/operazione.log/Operazione').getClobVal() from XMT_OPERAZIONE_LOG p
where existsNode(value(p),'/operazione.log/Journal[NumeroElettronico=1234567890]') = 1
So using extract intead of extractValue and adding getClobVal() I was able to read the CLOB.
The problem that I was not able to solve is related to CLOB update. In V9 just adding the âfor updateâ clause I was able to change the CLOB value on DB.
In V10 if I run the V9 statement I get the error:
ORA-03113: end-of-file on communication channel
If I use the statement modified for V10, adding the âfor updateâ clause, I get the CLOB and I can change the CLOB value but nothing goes on the DB. Probably I am working on a copy of the DB CLOB.
If I remove the getClobVal() I get an OPAQUE type that I can use on a XMLType but, still, nothing is stored on DB.
Any suggestion ?
I tried with both OCI and Thin ClientCan anybody help me ?
Is it better to use different strategies ( eg. Stored Procedure, DBMS_XMLSTORE etc, etc. ) ?
Any experience updatating XML Fragment CLOB on Oracle V10 ? -
Generating an xml from a pl/sql procedure
Hi Friends,
I have come up with a requirement to generate an xml from a pl/sql procedure.
I did some R & D and also got some sample procedures but could not understand the datatypes being used.
The procedure declares variables like this:
doc xmldom.DOMDocument;
mainNode xmldom.DOMNode;
headerElem xmldom.DOMElement; Pls could anyone tell what do these xmldom.DOMDocument, xmldom.DOMNode and xmldom.DOMElement mean?
Later in the procedure, these variables are assigned values like
doc := xmldom.newDOMDocument;
mainNode := xmldom.makenode(doc); This went a bouncer on me.
Pls help.
Thanks in advance ...!You can check this one -- Learned this from michael.
satyaki>
satyaki>
satyaki>select * from v$version;
BANNER
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production
TNS for Linux: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production
satyaki>
satyaki>
satyaki>with person_h
2 as
3 (
4 select 1 id, 'M' gender, 'W' race, '170' weight from dual union all
5 select 1, 'M', 'W', '170' from dual union all
6 select 1, 'M', 'W', '180' from dual union all
7 select 1, 'M', NULL, '175' from dual union all
8 select 1, NULL, 'W', NULL from dual
9 )
10 select xmlelement("Person",(
11 select xmlagg(xmlelement("Sex", gender))
12 from (
13 select distinct gender
14 from person_h
15 where id = 1
16 and gender is not null
17 ) pg
18 ),
19 (
20 select xmlagg(xmlforest(race as "Race"))
21 from (
22 select distinct race
23 from person_h
24 where id = 1
25 ) pg
26 ),
27 (
28 select xmlagg(xmlforest(weight as "Weight"))
29 from (
30 select distinct weight
31 from person_h
32 where id = 1
33 ) pg
34 )
35 ).getstringval() Res
36 from dual;
RES
<Person><Sex>M</Sex><Race>W</Race><Weight>170</Weight><Weight>175</Weight><Weight>180</Weight></Person>
satyaki>Regards.
Satyaki De. -
Storing and searching XML in CLOBs
Speaking to an oracle employee at the Oracle booth at JavaOne
recently. They suggested I store XML in CLOBs
and use the DOM or SAX to reparse the XML later as needed.
I agreed that this was the best solution for my problem
(which was how to manage many different XML documents using many
different DTDs in a document management system)
The big problem was searching this document repository
to locate relevant information.
This is where Intermedia seemed ideal (still does).
It would be nice to see an example of setting this up using
Intermedia in Oracle 8i, demonstrating how to define the
XML_SECTION_GROUP and where to use a ZONE as opposed to a FIELD
etc.
Anybody care to take a shot at this ????
For example:
How would I define Intermedia parameters
so that I would be able to search my CLOB
column for records that had the <keyword>
"aorta" and "damage" in the <caption>
using the following
XML (DTD implied)
<image filename="OurImageName.gif">
<fname>WellKnownFileName.gif</fname>
<keyword>echocardiogram</keyword>
<keyword>aorta</keyword>
<caption>This is an image of the vessel damage</caption>
</image>
Thanks
Thomas Bennett
nullEric (guest) wrote:
: You can't do XML structure-based searches with intermedia. You
: can search for text within a given element, but nothing more
: complicated than that.
The example he gave involves exactly that -- searching for
text within XML elements. interMedia can do this.
: It also does not do attributes.
Upcoming 8.1.6 version allows searching within
attribute text. That's something like:
dog within book@author
We're working on attribute value sensitive search,
more like:
dog within book[@author = "Eric"]
: Thomas Bennett (guest) wrote:
: : How would I define Intermedia parameters
: : so that I would be able to search my CLOB
: : column for records that had the <keyword>
: : "aorta" and "damage" in the <caption>
: : using the following
: : XML (DTD implied)
: : <image filename="OurImageName.gif">
: : <fname>WellKnownFileName.gif</fname>
: : <keyword>echocardiogram</keyword>
: : <keyword>aorta</keyword>
: : <caption>This is an image of the vessel damage</caption>
: : </image>
begin
ctx_ddl.create_section_group('mygrp','basic_section_group');
ctx_ddl.add_field_section('mygrp','keyword','keyword');
ctx_ddl.add_field_section('mygrp','caption','caption');
end;
create index myidx on mytab(mytxtcolumn)
indextype is ctxsys.context
parameters ('section group mygrp');
select * from mytab
where contains(mytxtcolumn, 'aorta within keyword')>0;
options:
* use XML section group instead of basic section group
if your tags have attributes or you need case-sensitive
tag detection
* use zone sections instead of field sections if your
sections overlap, or if you need to distinguish
between instances. For instance, keywords. If keywords
is a field section, then
(aorta and echocardiogram) within keywords
finds the document. if it is a zone section, then it
doesn't, because they are not in the SAME instance of
keywords.
null -
I’m building some ETL process to extract data from XML in CLOB columns. I know that there are solutions to use functions as extractvalue() of WB_XML_LOAD(), but I want to know if there is any other way to deal with XML. The reason for that is because my XML files have multiple namespaces and nodes, and I need something more complex to deal with that, since I already tried those two first solutions.
My first solution was to create a PL/SQL that parses the XML and looks for tags and elements. It populates a relational table, and I might use OWB to extract the data from this table. But I’m dealing with a large table and it takes a while for processing, plus my code is hude!
My question is: Does someone have any experience with complex XML in Clob columns? If so, what was your solution for that?
Thanks a lot!
Angelo Buss
[email protected]CLOB is a fully-updateable, character large object that is stored inside the database. It can be text-indexed using interMedia for document searching.
BFILE is a readonly pointer to a file on the external file system whose content is not physically stored in the database. It can also be text-indexed for document searching, but it can't be updated. -
Could somebody tell me the different between save XML in CLOB and BFILE, addition to generic different between CLOB and BFILE, is there a performance issue?
ThanksCLOB is a fully-updateable, character large object that is stored inside the database. It can be text-indexed using interMedia for document searching.
BFILE is a readonly pointer to a file on the external file system whose content is not physically stored in the database. It can also be text-indexed for document searching, but it can't be updated. -
How to execute the parametered stored procedure in sql *plus ?
how to execute the parametered stored procedure in sql *plus ?
my storedprocedure format
CREATE OR REPLACE PROCEDURE SMS_SELECTMPLOYEE
(empDOB out date, empEmpName out varchar2)
thanks & regards
mk_murOh, sorry... making many reading-too-fast mistakes today...
You can't declare date variables in SQL*Plus (seel help var), but you can cast to varchar2:
TEST> CREATE OR REPLACE PROCEDURE SMS_SELECTMPLOYEE (empDOB out date, empEmpName out varchar2) IS
2 d date := sysdate;
3 e varchar2(10) := 'bob';
4 begin
5 empdob := d;
6 empempname := e;
7 end;
8 /
Procedure created.
TEST> var d varchar2(30)
TEST> var n varchar2(30)
TEST> call SMS_SELECTMPLOYEE(:d,:n);
Call completed.
TEST> print d n
D
11/07/06
N
bobYoann. -
Revision: 4804
Author: [email protected]
Date: 2009-02-02 17:56:22 -0800 (Mon, 02 Feb 2009)
Log Message:
Bugs: LCDS-548: add code to deal with contentType="application/xml" with one parameter (avoid
name/value encoding in that case)
LCDS-405: baseURL on HTTPMultiService should accept URLs which start with "/"
Added convertParametersHandler and convertResultsHandler function hooks to RemoteObject
to support framework code which wants to modify the service behavior.
Moved "properties" from rpc/http/AbstractOperation to rpc/AbstractOperation so we can use
it for customizing the handling of remote object results
Couple of minor ASDoc fixes and one tab -> spaces change
Doc: minor asdoc edits
QE: LCDS QE will verify the bugs in this one
Reviewers: Mete, Pete, Seth, Ed reviewed different parts of this checkin
Ticket Links:
http://bugs.adobe.com/jira/browse/LCDS-548
http://bugs.adobe.com/jira/browse/LCDS-405
Modified Paths:
flex/sdk/trunk/frameworks/projects/rpc/src/mx/rpc/AbstractInvoker.as
flex/sdk/trunk/frameworks/projects/rpc/src/mx/rpc/AbstractOperation.as
flex/sdk/trunk/frameworks/projects/rpc/src/mx/rpc/http/AbstractOperation.as
flex/sdk/trunk/frameworks/projects/rpc/src/mx/rpc/http/HTTPMultiService.as
flex/sdk/trunk/frameworks/projects/rpc/src/mx/rpc/http/Operation.as
flex/sdk/trunk/frameworks/projects/rpc/src/mx/rpc/remoting/Operation.as
flex/sdk/trunk/frameworks/projects/rpc/src/mx/rpc/remoting/RemoteObject.asHello,
How about this as an alternative:
Use a functional global which has 3 cases:
1. open config file - it opens the config file and reads the contents into a string (which is the functional global data), and you only do this one time at the beginning of the program.
2. edit config data - it edits the string, which are really the contents of the file, but doesn't worry about writing to the file. you could even get fancy here, and allow an array of tags and an array of values as input, and it would go update/edit all the tags to have the corresponding values.
3. close config file - it writes the current string data (the functional global data) to the file and closes it.
Using the functions in the string palette, I think you'll find most of the code for that module/functional global will be easy to write.
I hope this helps!
Best Regards,
JLS
Best,
JLS
Sixclear -
How to assign Values to nested table and pass as parameter to procedure?
How to assign Values to nested table and pass as parameter to procedure?
Below is the Object and its type
create or replace type test_object1 as object
val1 varchar2(50),
val2 varchar2(50),
val3 varchar2(50)
create or replace type test_type1 is table of test_object1;
create or replace type test_object2 as object
val1 varchar2(50),
val2 varchar2(50),
val3 varchar2(50)
create or replace type test_type2 is table of test_object2;
GRANT ALL ON test_object1 TO PUBLIC;
GRANT ALL ON test_type1 TO PUBLIC;
GRANT ALL ON test_object2 TO PUBLIC;
GRANT ALL ON test_type2 TO PUBLIC;
here is the table made of object type:
create table test_object_tpe
sl_num NUMBER,
description VARCHAR2(100),
main_val1 test_type1,
main_val2 test_type2
NESTED TABLE main_val1 STORE AS tot1
NESTED TABLE main_val2 STORE AS tot2;
here is the procedure which inserts values into nested table:
PROCEDURE INSERT_TEST_DATA(sl_num IN NUMBER,
description IN VARCHAR2,
p_main_val1 IN test_type1,
p_main_val2 IN test_type2
IS
BEGIN
FOR rec in p_main_val1.first..p_main_val1.last
LOOP
INSERT INTO xxdl.test_object_tpe
sl_num,
description,
main_val1,
main_val2
VALUES
sl_num
,description
,test_type1 (test_object1(
p_main_val1(rec).val1,
p_main_val1(rec).val2,
p_main_val1(rec).val3
,test_type2 (test_object2( p_main_val2(rec).val1,
p_main_val2(rec).val2,
p_main_val2(rec).val3
END LOOP;
commit;
END INSERT_TEST_DATA;
here is the anonymoys block which assigns values to the object type and pass values into the procedure:
set serveroutput on;
declare
p_sl_num NUMBER := 1001;
p_description VARCHAR2(50) := 'Testing Val1';
inval1 test_type1 := test_type1();
inval2 test_type2 := test_type2();
begin
inval1(1).val1 := 'testx1';
inval1(1).val2 := 'testx2';
inval1(1).val3 := 'testx3';
inval2(1).val1 := 'testy1';
inval2(1).val2 := 'testy2';
inval2(1).val3 := 'testy3';
CSI_PKG.INSERT_TEST_DATA(sl_num => p_sl_num,
description => p_description,
p_main_val1 => inval1,
p_main_val2 => inval2
end;
Can anybody correct me.
Thanks,
LavanThanks for posting the DDL and sample code but whenever you post provide your 4 digit Oracle version (result of SELECT * FROM V$VERSION).
>
How to assign Values to nested table and pass as parameter to procedure?
>
Well you are doing almost everything wrong that could be done wrong.
Here is code that works to insert data into your table (the procedure isn't even needed).
declare
p_sl_num NUMBER := 1001;
p_description VARCHAR2(50) := 'Testing Val1';
inval1 test_type1 := test_type1();
inval2 test_type2 := test_type2();
begin
inval1.extend();
inval1(1) := test_object1('testx1', 'testx2', 'testx3');
inval2.extend();
inval2(1) := test_object2('testy1', 'testy2', 'testy3');
INSERT INTO test_object_tpe
sl_num,
description,
main_val1,
main_val2
VALUES
(p_sl_num, p_description, inval1, inval2);
commit;
end;
/See Example 5-15 Referencing a Nested Table Element in Chap 5 Using PL/SQL Collections and Records in the PL/SQL doc
http://docs.oracle.com/cd/B28359_01/appdev.111/b28370/collections.htm#CJABEBEA
1. You don't even need the procedure since all it does is a simple INSERT into the table which you can do directly (see my code above)
inval1(1).val1 := 'testx1';There is no element one (1) of 'inval1' since you haven't created any elements yet. You need to EXTEND the collection to add an element
inval1.extend();And then there is an empty element but 'inval1' is a container for objects of type 'test_object1' not for scalars like 'val1', 'val2', and 'val3'.
So you can't do
inval1(1).val1 := 'testx1';You have to create an instance of 'test_object1'
inval1(1) := test_object1('testx1', 'testx2', 'testx3');And so on for the other collection
You don't need the procedure (as my sample code shows) but once you populate the variables properly it will work. -
Extract part of xml into CLOB or XMLType
I need to extract part of XML into CLOB or some another type. But I don't need only extract data, by whole part od xml with elements. How could I do it in PL/SQL?
For example from this xml:
<bookstore>
<book category="COOKING">
<title lang="en">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="CHILDREN">
<title lang="en">Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
</bookstore>
I need to get:
"<book category="COOKING">
<title lang="en">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.00</price>
</book>"
THXThat's why I need to process every book alone - to know which authors belongs to single book.For that specific requirement, a single query would do.
Assuming variable "v_xml_clob" holds the XML document :
<bookstore>
<name>nameOfBookstore</name>
<address>1st Avenue 24, SF</address>
<book category="COOKING">
<title lang="en">Everyday Italian</title>
<author>
<name>Giada De Laurentiis</name>
<birth>1956</birth>
</author>
<author>
<name>xxx</name>
<birth>1955</birth>
</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="CHILDREN">
<title lang="en">Harry Potter</title>
<author>
<name>Rowning</name>
<birth>1977</birth>
</author>
<author>
<name>xxx</name>
<birth>1955</birth>
</author>
<year>2005</year>
<price>29.99</price>
</book>
</bookstore>You can do :
SELECT *
FROM XMLTable(
'for $i in distinct-values($d//book/author/name)
where count($d//book/author[name=$i]) = 1
return $i'
passing xmltype(v_xml_clob) as "d"
columns author_name varchar2(80) path '.'
AUTHOR_NAME
Rowning
Giada De Laurentiis
Maybe you are looking for
-
Alarms keep reseting back to same time and OFF!
I can't figure out what the trigger is but about once a month my phone will have all the alarms I have setup in the clock application reset to default values. They all go to the same time, ringtone, and are set to off. This is the second phone I h
-
Not able to select audio track.
When unlinked and I click on an audio track nothing happens. I can't clear or move the track.
-
Update ADDRESS PURPOSE DETAILS for Supplier
I am working in R12 EBS with oracle database 10g. I have a requirement to update the 'SUPPLIER ADDRESSBOOK DETAILS'. ACCOUNT PAYABLES RESPONSIBILITY--> SUPPLIER-->ENTRY-->SUPPLIER-->ADDRESS BOOK-->UPDATE ADDRESS Then you can update the supplier addre
-
Error in j1id - Change / Display
Dear All, I am facing a problem in transaction j1id, while changing or displaying customer excise details. could any one help me out on this ?? Regards, Sridhar S The error is as follows.. Short text Syntx error or generation error in a
-
In pre-OSX days, I remember that there was a nice sound when all the extensions were loaded and ones computer was fully "started". It was useful - one didn't jump in and try to do something "too soon". Is there anyway to have this with Tiger?