Vorbei an riesigen XML-Code aus C# -/.Net, Oracle-Gespeicherten Prozedur via CLOB-parameter - ORA-01008: nicht allen Variablen gebunden

Umgebung:

Server: Oracle 11.2 g server auf einem 64-bit-windows 2008

Client: Oracle 11g-client auf Windows XP SP3, ASP.Net 4.0, Visual Studio 2010, C#

Input-Größe des XML - ~ 1,206,500 Zeichen (Berechnet auf der Basis der maximalen Daten, die ich habe).

Szenario:

Web-Anwendung, die XML generiert, dass die oracle-gespeicherten Prozedur verwendet zum aktualisieren einer Tabelle in der Datenbank. Da die XML-size ist ziemlich groß, die Gespeicherte Prozedur Parameter Typ ausgewählt ist, CLOB, statt LANGE wie LANGE ist eine Einschränkung des 32760 Zeichen.

Problem:

Mit CLOB-Datentypen, die als parameter-Typ wirft den Fehler "ORA-01008: nicht allen Variablen gebunden" für die gleiche gespeicherte Prozedur code funktioniert perfekt für die parameter geben Sie wie LANGE (und XML Länge < 32760)

C# - Code für das aufrufen der gespeicherten Prozedur:

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-Gespeicherten Prozedur-Code:

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;

Jeder, der gearbeitet hat mit dem bestehen große XML via CLOB parameter und umgebaut, dass CLOB-XML in der gespeicherten Prozedur können Sie bitte helfen? Alternativer Ansatz für dieses problem wäre auch sehr geschätzt.

Vielen Dank im Voraus.

Ist die ORA-01008 kommen aus dem Prozedur-Aufruf, oder CLOB-Erstellung nennen? Sind Sie auf der Wiederverwendung der gleichen DbUpdateCommand-Objekt, und daher Sitzung, für das Paket nennen? (Wie es aussieht, aber nicht sicher, ob es ' s code fehlt)
Vielen Dank Alex. Ich überprüfte meine code in das Licht Ihres Kommentars und fand, dass ich Sie nicht deaktivieren Sie die Parameter in der command-Objekt, dass ich wiederverwenden, zum aufrufen der gespeicherten Prozedur. (Das command-Objekt noch die CLOB-Erstellung-parameter). Vielen Dank.

InformationsquelleAutor Moiz Tankiwala | 2010-07-30

Schreibe einen Kommentar