Issues calling stored procedure from C# with large CLOB

前端 未结 4 1022
臣服心动
臣服心动 2020-12-09 03:55

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

相关标签:
4条回答
  • 2020-12-09 04:24

    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

    0 讨论(0)
  • 2020-12-09 04:25

    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;
            }
        }
    
    0 讨论(0)
  • 2020-12-09 04:29

    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)
    {
    }
    
    0 讨论(0)
  • 2020-12-09 04:37

    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();
    }
    
    0 讨论(0)
提交回复
热议问题