In This Topic
This article describes how to work with BLOB data in dotConnect Universal.
LOB basics
LOB stands for Large OBject, a stream of data stored in a database. LOBs are represented
as UniBlob objects.
There three two kinds of LOB data type:
- BLOB datatype stores unstructured binary large objects.
BLOB objects can be thought of as bitstreams with no character set semantics.
Corresponding UniDbType is Blob.
- The CLOB datatype stores single-byte and multibyte character data
using database character set. Corresponding UniDbType is Clob.
- The NCLOB datatype stores unicode or national character set data.
Corresponding UniDbType is NClob.
You can use any of the data types with dotConnect Universal.
Working with BLOB data
Binary data is generally represented as stream of bytes, or buffers. dotConnect Universal
allows to manipulate BLOB data in most convenient ways. You can work with
UniBlob.Value property or use UniBlob.Read() and UniBlob.Write() methods to handle BLOB
data. Both ways are presented in the samples below. Note that when
UniBlob.LobType property is UniDbType.Blob, the UniBlob.Value is treated as
array of bytes (byte[]), whereas UniDbType.Clob represents
UniBlob.Value as string.
The next sample routines show how to upload a file from hard disk to server and download
it back. To execute these routines you have to create a table that is described as follows:
CREATE TABLE pictures (
id INT,
PicName VARCHAR(20),
Picture BLOB
)
static void UploadBlob(UniConnection myConnection)
{
FileStream fs = new FileStream("D:\\Tmp\\test.bmp", FileMode.Open, FileAccess.Read);
BinaryReader r = new BinaryReader(fs);
myConnection.Open();
UniBlob myLob = new UniBlob(myConnection,UniDbType.Blob);
int streamLength = (int)fs.Length;
myLob.Write(r.ReadBytes(streamLength), 0, streamLength);
UniCommand myCommand = new UniCommand(
"INSERT INTO pictures (id, PicName, Picture) VALUES(1,'pict1',:Pictures)", myConnection);
UniParameter myParam = myCommand.Parameters.Add("Pictures", UniDbType.Blob);
myParam.Value = myLob;
try
{
Console.WriteLine(myCommand.ExecuteNonQuery() + " rows affected.");
}
finally
{
myConnection.Close();
r.Close();
fs.Close();
}
}
static void DownloadBlob(UniConnection myConnection)
{
UniCommand myCommand = new UniCommand("SELECT * FROM pictures", myConnection);
myConnection.Open();
UniDataReader myReader = myCommand.ExecuteReader(System.Data.CommandBehavior.Default);
try {
while (myReader.Read()) {
int colind = myReader.GetOrdinal("Picture");
if (!myReader.IsDBNull(colind)) {
UniBlob myLob = myReader.GetUniBlob(colind);
string FN = myReader.GetString(myReader.GetOrdinal("PicName"));
FileStream fs = new FileStream("D:\\Tmp\\" + FN + ".bmp", FileMode.Create);
byte[] b = new byte[myLob.Length];
myLob.Read(b, 0, (int)myLob.Length);
fs.Write(b, 0, (int)myLob.Length);
fs.Close();
Console.WriteLine(FN + " downloaded.");
}
}
}
finally {
myReader.Close();
myConnection.Close();
}
}
Public Sub UploadBlob(ByVal myConnection As UniConnection)
Dim fs As FileStream = New FileStream("D:\Tmp\test.bmp", FileMode.Open, FileAccess.Read)
Dim r As BinaryReader = New BinaryReader(fs)
myConnection.Open()
Dim myLob As UniBlob = New UniBlob(myConnection, UniDbType.Blob)
Dim streamLength As Int32 = fs.Length
myLob.Write(r.ReadBytes(streamLength), 0, streamLength)
Dim myCommand As UniCommand = New UniCommand("INSERT INTO Pictures (id, PicName, Picture) VALUES(1,'pict1',:Pictures)", myConnection)
Dim myParam As UniParameter = myCommand.Parameters.Add("Pictures", UniDbType.Blob)
myParam.Value = myLob
Try
Console.WriteLine(myCommand.ExecuteNonQuery() & " rows affected.")
Finally
myConnection.Close()
r.Close()
fs.Close()
End Try
End Sub
Public Sub DownloadBlob(ByVal myConnection As UniConnection)
Dim myCommand As New UniCommand("SELECT * FROM Pictures", myConnection)
myConnection.Open()
Dim myReader As UniDataReader = myCommand.ExecuteReader(System.Data.CommandBehavior.Default)
Try
While myReader.Read()
Dim colind As int= myReader.GetOrdinal("Picture");
If Not myReader.IsDBNull(colind) Then
Dim myLob As UniBlob = myReader.GetUniBlob(colind)
Dim FN As String = myReader.GetString(myReader.GetOrdinal("PicName"))
Dim fs As FileStream = New FileStream("D:\Tmp\" + FN + ".bmp", FileMode.Create)
Dim w As BinaryWriter = New BinaryWriter(fs)
w.Write(myLob.Value)
w.Close()
fs.Close()
Console.WriteLine(String.Concat(FN, " downloaded."))
End If
End While
Finally
myReader.Close()
myConnection.Close()
End Try
End Sub
Working with CLOB data
Working with CLOB data generally is same as working with BLOB data. The difference
is in representation of Value property. For CLOB data type when you read
from UniBlob.Value property, you get strings. The data is
transparently decoded so you do not have to take care about its
character set. If you need raw data however you can use streaming capabilities
of UniBlob, that being UniBlob.Read and UniBlob.Write methods. Note that since
UniBlob.Value is a read-only property, you can write data to LOB only with
UniBlob.Write method, and no encoding is performed.
For example, consider this table definition.
CREATE TABLE clobtable (
Id INT,
Name VARCHAR(30),
Value CLOB
)
If you need to perform simple tasks like fetch record set in most cases you do not need
to know about UniBlob. When calling UniDataReader.GetValue on fetch you get array of bytes
for BLOB column and string for CLOB one. In addition you can use UniDataReader.GetChars,
UniDataReader.GetBytes to get pieces of LOB value.
For example,
...
UniCommand myCommand = new UniCommand("SELECT * FROM clobtable", myConnection);
UniDataReader reader = myCommand.ExecuteReader();
while (reader.Read())
Console.WriteLine(reader.GetValue(2));
...
...
Dim myCommand As UniCommand = new UniCommand("SELECT * FROM clobtable", myConnection)
Dim reader As UniDataReader = myCommand.ExecuteReader()
while (reader.Read())
Console.WriteLine(reader.GetValue(2))
end while
...
You can do the same thing using UniBlob object directly.
...
UniCommand myCommand = new UniCommand("SELECT * FROM clobtable", myConnection);
UniDataReader reader = myCommand.ExecuteReader();
UniBlob clob;
while (reader.Read()) {
clob = reader.GetUniBlob(2);
Console.WriteLine(clob.Value);
}
...
...
Dim myCommand As UniCommand = new UniCommand("SELECT * FROM clobtable", myConnection)
Dim reader UniDataReader = myCommand.ExecuteReader()
Dim clob As UniBlob
while (reader.Read())
clob = reader.GetUniBlob(2)
Console.WriteLine(clob.Value)
end while
...
As we see first code cut was shorter. So, usually, you need to access UniBlob directly
in more complicated cases (e.g using Oracle temporary LOBs, advanced streaming operations).
Working with NCLOB data
NCLOB type represents text data in national character set. You have to use this
BLOB type when data requires some transformation. For Oracle and MS SQL Server,
dotConnect Universal uses database encoding. The MySQL server does not have suitable BLOB
type, so the data provider converts data to Unicode.
For PostgreSQL, NCLOB is just a synonym for CLOB.
Additional information
Keep in mind that UniBlob class is not supported for OleDB, ODBC, DB2 and MS Access.
Instead you can use GetBytes method of UniDataReader object.
The UniBlob functionality is limited for dotConnect for Oracle 3.50 and older versions.
Use dotConnect for Oracle 4.00 and higher.
See Also
UniBlob Class
| Devart.Data.Universal Namespace
| dotConnect Universal articles