微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

通过CLOB参数将巨大的XML从C#/.Net传递到Oracle存储过程 – ORA-01008:并非所有变量都绑定

环境:

服务器:64位Windows 2008上的Oracle 11.2g服务器

客户端:Windows XP SP3,ASP.Net 4.0,Visual Studio 2010,C#上的Oracle 11g客户端

输入大小为XML~1,206,500个字符(根据我将拥有的最大数据计算).

场景:

Web应用程序生成oracle存储过程用于更新数据库中的表的XML.由于XML大小非常大,因此选择的存储过程参数类型是CLOB而不是LONG,因为LONG具有32760个字符的限制.

问题:

使用CLOB作为参数类型会抛出错误“ORA-01008:并非所有变量绑定”对于相同的存储过程代码,该代码完全适用于参数类型LONG(和XML长度<32760) 用于调用存储过程的C#代码

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,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",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存储过程代码

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;

任何通过CLOB参数传递大型XML并在存储过程中将CLOB转换为XML的人都可以帮忙吗?对此问题的任何替代方法也将受到高度赞赏.

提前致谢.

这是解决问题的C#代码.在重用相同的命令对象之前,我遗漏了清除参数.

C#代码

OracleCommand dbupdateCommand = null;
OracleLob tempLOB = null;

dbupdateCommand.CommandText = "declare xx clob; begin dbms_lob.createtemporary(xx,renewalDetailXMLBytes.Length);
tempLOB.EndBatch();

dbupdateCommand.CommandText = "P_WEB_PRDCR_RNEW_UPDT";
dbupdateCommand.CommandType = System.Data.CommandType.StoredProcedure;

//Missing line - start
dbupdateCommand.Parameters.Clear();
//Missing line - end

dbupdateCommand.Parameters.Add("PN_KEY_AGNT_RNEW_HDR",12).Value = 
        agentrenewalHeader;
dbupdateCommand.Parameters.Add("PN_KEY_CO",12).Value = 
        companyCode;
dbupdateCommand.Parameters.Add("PC_RNWL_DETL_XML",System.Data.OracleClient.OracleType.Clob).Value =
        tempLOB;
dbupdateCommand.Parameters.Add("PS_USR_NM",255).Value = 
        userName;

dbupdateCommand.ExecuteNonQuery();

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。