服务器: 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)
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();
Run Code Online (Sandbox Code Playgroud)
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;
Run Code Online (Sandbox Code Playgroud)
任何通过CLOB参数传递大型XML并在存储过程中将CLOB转换为XML的人都可以帮忙吗?对此问题的任何替代方法也将受到高度赞赏.
提前致谢.
以下是解决该问题的 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, 0, 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",
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();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
16110 次 |
| 最近记录: |