En passant énorme XML à partir de C#/.Net à la Procédure Stockée Oracle via CLOB paramètre - ORA-01008: pas toutes les variables liées
Environnement:
Serveur: Oracle 11.2 g server sur une version 64 bits de windows 2008
Client: Oracle 11g client sur Windows XP SP3, ASP.Net 4.0, Visual Studio 2010, C#
Taille d'entrée de XML ~ 1,206,500 caractères (Calculé sur la base du maximum de données que j'aurais).
Scénario:
L'application web génère le fichier XML de la procédure stockée oracle utilise pour mettre à jour une table dans la base de données. Depuis le XML taille est assez grande, la Procédure Stockée type de Paramètre choisi est CLOB au lieu de LONGTEMPS que LONGTEMPS a une limitation de 32760 caractères.
Problème:
À l'aide de CLOB comme le type de paramètre génère l'erreur "ORA-01008: pas toutes les variables liées" pour le même code de procédure stockée qui fonctionne parfaitement pour le paramètre de type LONG (et XML longueur < 32760)
De Code C# pour appeler une procédure stockée:
OracleCommand DbUpdateCommand = null;
OracleLob tempLOB = null;
DbUpdateCommand.CommandText = "declare xx clob; begin dbms_lob.createtemporary(xx, false, 0); :tempclob := xx; end;";
DbUpdateCommand.Parameters.Add(new OracleParameter("tempclob", OracleType.Clob)).Direction = ParameterDirection.Output;
DbUpdateCommand.ExecuteNonQuery();
//Assign the value to the LOB
tempLOB = (OracleLob)DbUpdateCommand.Parameters[0].Value;
tempLOB.BeginBatch(OracleLobOpenMode.ReadWrite);
//Convert the string to byte array to write to LOB
UnicodeEncoding encoding = new UnicodeEncoding();
byte[] renewalDetailXMLBytes = encoding.GetBytes(renewalDetailXML);
tempLOB.Write(renewalDetailXMLBytes, 0, renewalDetailXMLBytes.Length);
tempLOB.EndBatch();
DbUpdateCommand.CommandText = "P_WEB_PRDCR_RNEW_UPDT";
DbUpdateCommand.CommandType = System.Data.CommandType.StoredProcedure;
DbUpdateCommand.Parameters.Add("PN_KEY_AGNT_RNEW_HDR",
System.Data.OracleClient.OracleType.Number, 12).Value = agentRenewalHeader;
DbUpdateCommand.Parameters.Add("PN_KEY_CO",
System.Data.OracleClient.OracleType.Number, 12).Value = companyCode;
DbUpdateCommand.Parameters.Add("PC_RNWL_DETL_XML",
System.Data.OracleClient.OracleType.Clob).Value = tempLOB;
DbUpdateCommand.Parameters.Add("PS_USR_NM",
System.Data.OracleClient.OracleType.VarChar,255).Value = userName;
DbUpdateCommand.ExecuteNonQuery();
Oracle Du Code De Procédure Stockée:
CREATE OR REPLACE PROCEDURE DOIADMIN.P_WEB_PRDCR_RNEW_UPDT (
PN_KEY_AGNT_RNEW_HDR IN NUMBER,
PN_KEY_CO IN NUMBER,
PC_RNWL_DETL_XML IN CLOB,
PS_USR_NM IN VARCHAR2
)
AS
lx_rnew_detl_xml XMLTYPE;
lct_rnew_detl_cntx DBMS_XMLSAVE.ctxtype;
--Construct the complete xml for financial data
lx_rnew_detl_xml := XMLTYPE(PC_RNWL_DETL_XML);
--table to be updated with the xml
lct_rnew_detl_cntx := DBMS_XMLSAVE.newcontext('IL_AGNT_RNEW_DETL');
--Set the key column list
DBMS_XMLSAVE.SETKEYCOLUMN(lct_rnew_detl_cntx, 'KEY_AGNT_RNEW_HDR');
DBMS_XMLSAVE.SETKEYCOLUMN(lct_rnew_detl_cntx, 'KEY_CO');
DBMS_XMLSAVE.SETKEYCOLUMN(lct_rnew_detl_cntx, 'KEY_INDVDL_LIC');
--Set the udpate column
DBMS_XMLSAVE.SETUPDATECOLUMN(lct_rnew_detl_cntx, 'FLG_MARKED_FOR_CANCEL');
--update the table from the rows
ln_cntr := DBMS_XMLSAVE.UPDATEXML(lct_rnew_detl_cntx, lx_rnew_detl_xml.getCLOBVal());
DBMS_XMLSAVE.closecontext(lct_rnew_detl_cntx);
END p_web_prdcr_rnew_updt;
Toute personne qui a travaillé avec le passage de grandes XML via CLOB paramètre et converti que CLOB en XML dans la procédure stockée peut aider s'il vous plaît? Toute autre approche de ce problème pourrait également être très appréciée.
Merci d'avance.
Merci Alex. J'ai revu mon code à la lumière de votre commentaire et a constaté que je n'étais pas de compensation les paramètres de la commande de l'objet que j'ai été réutilisation pour appeler la procédure stockée. (L'objet de commande encore eu le CLOB paramètre de création). Merci beaucoup.
OriginalL'auteur Moiz Tankiwala | 2010-07-30
Vous devez vous connecter pour publier un commentaire.
Voici le code C# qui a résolu le problème. J'ai été absent pour effacer les paramètres avant de réutiliser le même objet de commande.
De Code C#
OriginalL'auteur Moiz Tankiwala