I\'m not the first to have these issues, and will list some reference posts below, but am still looking for a proper solution.
I need to call a stored procedure (Ora
I guess I just googled this for you to get cheap points, but there's a great explanation here:
http://www.orafaq.com/forum/t/48485/0/
Basically you cannot use more than 4000 chars in a string literal, and if you need to do more, you must use a stored procedure. Then, you are limited to 32KB at max so you have to "chunk" the inserts. Blech.
-Oisin
chiccodoro is right.
public static int RunProcedure(string storedProcName, IDataParameter[] parameters)
{
using (OracleConnection connection = new OracleConnection(connectionString))
{
int rowsAffected;
OracleCommand command = new OracleCommand(storedProcName, connection);
command.CommandText = storedProcName;
command.CommandType = CommandType.StoredProcedure;
foreach (OracleParameter parameter in parameters)
{
command.Parameters.Add(parameter);
}
connection.Open();
try
{
// start transaction
command.Transaction = connection.BeginTransaction();
rowsAffected = command.ExecuteNonQuery();
command.Transaction.Commit();
}
catch (System.Exception ex)
{
command.Transaction.Rollback();
throw ex;
}
connection.Close();
return rowsAffected;
}
}
In my case, chiccodoro's solution did not work. I'm using ODP.NET ( Oracle.DataAccess
).
For me the solution is using OracleClob
object.
OracleCommand cmd = new OracleCommand("LoadXML", _oracleConnection);
cmd.CommandType = CommandType.StoredProcedure;
OracleParameter xmlParam = new OracleParameter("XMLFile", OracleType.Clob);
cmd.Parameters.Add(xmlParam);
//connection should be open!
OracleClob clob = new OracleClob(_oracleConnection);
// xmlData: a string with way more than 4000 chars
clob.Write(xmlData.ToArray(),0,xmlData.Length);
xmlParam.Value = clob;
try
{
cmd.ExecuteNonQuery();
}
catch (OracleException e)
{
}
I found that there is another way to work around the problem! My fellow employee saved my day pointing me to this blog, which says:
Set the parameter value when BeginTransaction has already been called on the DbConnection.
Could it be simpler? The blog relates to Oracle.DataAccess
, but it works just as well for System.Data.OracleClient
.
In practice this means:
varcmd = new OracleCommand("LoadXML", _oracleConnection);
cmd.CommandType = CommandType.StoredProcedure;
var xmlParam = new OracleParameter("XMLFile", OracleType.Clob);
cmd.Parameters.Add(xmlParam);
// DO NOT assign the parameter value yet in this place
cmd.Transaction = _oracleConnection.BeginTransaction();
try
{
// Assign value here, AFTER starting the TX
xmlParam.Value = xmlWithWayMoreThan4000Characters;
cmd.ExecuteNonQuery();
cmd.Transaction.Commit();
}
catch (OracleException)
{
cmd.Transaction.Rollback();
}