Question

I'm trying to insert a clob into Oracle. If I try this with an OdbcConnection it does not insert the data into the database. It returns 1 row affected and no errors but nothing is inserted into the database.

It does work with an OracleConnection. However, using the Microsoft OracleClient makes our webservices often crash with an AccessViolationException (Attempted to read or write protected memory. This is often an indication that other memory is corrupt.). This happens a lot when we use OracleDataAdapter.Fill(dataset). So using this doesn't seem like an option.

Is there any way to insert/update clobs with more then 4.000 characters from .Net with an OdbcConnection?

Was it helpful?

Solution

I haven't worked on the .NET platform in awhile, so this is from memory.

To the best of my knowledge, OdbcConnection's adapter for Oracle is ancient and you cannot insert/update more than 4,000 characters at a time. You can write a stored procedure to transfer and update the CLOB 4,000 characters at a time, but that seems like a arduous and inefficient means to support an aging library.

So, MS's OracleConnection may be a better path to debug. AccessViolationException is most often cause by the Distributed Transaction Controller (msdtc.exe) not being started, though there are numerous other potential causes (including faulty hardware).

Before you investigate the exception, there is a third connection library to consider. Oracle's DataAccess Components (ODAC ODP.NET), which should be included with your database license. It's much better supported than OdbcConnection and should bypass OracleConnection's exception throwing.

OTHER TIPS

In my table I changed my clob into a blob. convert your text going into table blob to byte array. then when reading value convery byte array tostring.

//insert code
System.Text.Encoding enc = System.Text.Encoding.ASCII;
byte[] blobByteArray = enc.GetBytes(text);

string sql = "insert into xxxxx (id,name,script_blob) values (?,?,?)";
cmd = new OdbcCommand(sql, conn);
cmd.CommandTimeout = _cmdtimeout;
cmd.Parameters.Add("id", OdbcType.VarChar);
cmd.Parameters["id"].Value = script_id;
cmd.Parameters.Add("name", OdbcType.VarChar);
cmd.Parameters["name"].Value = name;
cmd.Parameters.Add("script_blob", OdbcType.Binary);
cmd.Parameters["script_blob"].Value = blobByteArray;
int i = cmd.ExecuteNonQuery();

//read blob back from db
System.Text.Encoding enc = System.Text.Encoding.ASCII;
string sql = "select id,name,script_blob from bc_script";
cmd = new OdbcCommand(sql, conn);
cmd.CommandTimeout = _cmdtimeout;    
OdbcDataReader dr2 = cmd.ExecuteReader();
if (dr2.HasRows)
{
    rtn = new List<BCScript>();
    while (dr2.Read())
    {
        string Script_text = enc.GetString((byte[])dr2["script_blob"]);
    }
}

cmd.Dispose();

I don't think this is a problem with odbc but rather a limitation on oracles part. If you are inserting or updating using a select statement you cannot use more that 4000 chars. The recommended way to do this is using bind variables and plsql. I know this sounds like a very ugly solution but it is all I have found so far ;(.

http://www.evilcyborg.com/lounge/?ID=1245

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top