通过CLOB参数将巨大的XML从C#/.Net传递到Oracle存储过程 – ORA-
发布时间:2020-12-15 23:59:55 所属栏目:百科 来源:网络整理
导读:环境: 服务器: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存储过程用于更新数据
环境:
服务器: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(); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |