Running C#, .NET 4.5 - I am attempting to write a byte[]
to an Oracle 11g database using the devart driver for Oracle (NuGet pkg: dotConnect.Express.for.Oracle
, version: 8.4.201).
In a special case, I am experiencing that my buffer offset is ignored and I am a bit unsure if I am missing something really obvious or if I have found a bug in the driver. The case goes as follows:
DDL:
CREATE TABLE MYTABLE (MYID NUMBER(12), MYDATA BLOB);
My NUnit test looks as follows:
[Test]
public void BlobQuestionTest()
{
var buffer = Encoding.UTF8.GetBytes("ABCDEFGHIJKLMNOPQ");
// Insert record with empty blob
using (var con = new OracleConnection(Config.ConnectionString))
{
con.Open();
const string sql = "INSERT INTO MYTABLE (MYID, MYDATA) VALUES (:MyId, :MyData)";
var cmd = new OracleCommand(sql, con);
cmd.Parameters.Add("MyId", 42);
var lob = new OracleLob(con, OracleDbType.Blob);
cmd.Parameters.Add("MyData", lob);
var affectedRows = cmd.ExecuteNonQuery();
Assert.AreEqual(1, affectedRows); // Passes
con.Commit();
}
// Later on, lock the row and update the record with the blob data
using (var con = new OracleConnection(Config.ConnectionString))
{
con.Open();
const string sql = "SELECT MYDATA FROM MYTABLE WHERE MYID = :MyId FOR UPDATE";
var cmd = new OracleCommand(sql, con);
cmd.Parameters.Add("MyId", 42);
var reader = cmd.ExecuteReader();
reader.Read();
var lob = reader.GetOracleLob(0);
Assert.AreEqual(0, lob.Length); // Passes
lob.Write(buffer, offset: 4, count: 4);
var actual = Encoding.UTF8.GetString((byte[])lob.Value, index: 0, count: 4);
Assert.AreEqual("EFGH", actual); // <--- Fails (actual: ABCD) - why??
con.Commit();
}
}
As you can see from the comments, the last Assert
fails because the offset of 4
appears to have been ignored but I have no idea why?
I have tracked down that if I change my insert statement to: INSERT INTO MYTABLE (MYID) VALUES (:MyId)
and don't add the empty blob as parameter to the INSERT
statement, then the offset is respected when I write to the blob stream, and the assert Assert.AreEqual("EFGH", actual);
passes.
So yeah, I have tried searching for a good explanation on this, but as far as I can tell, the devart documentation does not cover this.