How to: Read and Write BLOB Data to a Database Table Through an Anonymous PL/SQL Block
How to: Read and Write BLOB Data to a Database Table Through an Anonymous PL/SQL Block


Date: 18-Oct-2004


Objective

After reading this how-to document you should be able to:

  • Execute an Anonymous PL/SQL block using ODP.NET

  • Save Image data from a file to database

  • Write Image data to a file from database

Prerequisite

The reader is assumed to be familiar with MS Visual Studio.NET, and also possess an understanding of the rudimentaries of ODP.NET and databases.

Introduction

This document illustrates how to use an Anonymous PL/SQL block to insert BLOB (Binary Large OBject) data in a file into a database table and then retrieve the same data from the database and write to a file. Anonymous PL/SQL block is an unnamed block of PL/SQL statements. This block is not stored as an object in the database, but is executed once and removed.

In this how-to document, an Anonymous PL/SQL block is created that inserts BLOB data from an image file into a database table and then retrieves the inserted image and writes it to another file on the local filesystem. One has to provide the location of the source image file and the destination image file. Parameters of OracleDbType.Blob type is bound to the Anonymous PL/SQL block. Note: To test this how-to , any image file of type like .jpg, .gif etc can be used. No image file is supplied with this how-to.

Value Proposition

The primary advantage of using anonymous PL/SQL blocks is improved performance -they can be used to batch a series of SQL calls together in a single round-trip. This feature allows multiple commands, separated by semi-colons, to be executed one after another. Further, the batch SQL can include a number of SELECT or non-SELECT statements; if the batch contains multiple SELECT statements, multiple number of result sets will be returned.

Anonymous Pl/SQL blocks can be used for the retrieval of LOBs. They can also be used to fill a Dataset with multiple tables, by setting multiple commands in the OracleCommand (one for each table in the Dataset). In such a scenario you can return multiple REF cursors from a PL/SQL Anonymous Block, for example, like this:

BEGIN
OPEN :1 FOR SELECT * FROM A;
OPEN :2 FOR SELECT * FROM B;
OPEN :3 FOR SELECT * FROM C;
END;

Requirements

Creating Database Objects

Listing 1
DROP TABLE TestBlob;

CREATE TABLE TestBlob (id number, photo BLOB);

Code Walk-Through

using System;
using System.Data;
using Oracle.DataAccess.Client;
using Oracle.DataAccess.Types;
using System.IO;
using System.Text;
Imports System
Imports System.Data
Imports Oracle.DataAccess.Client
Imports Oracle.DataAccess.Types
Imports System.IO
Imports System.Text

//Step 1
// Connect to database
// Note: Modify User Id, Password, Data Source as per your database setup
string constr = "User Id=Scott;Password=tiger;Data Source=orcl9i";

OracleConnection con = new OracleConnection(constr);
con.Open();
Console.WriteLine("Connected to database!");
'Step 1
' Connect to database
' Note: Modify User Id, Password, Data Source as per your database setup
Dim constr As String = "User Id=Scott;Password=tiger;Data Source=orcl9i"
Dim con As OracleConnection = New OracleConnection(constr)
con.Open()
Console.WriteLine("Connected to database!")
// Step 2
// Note: Modify the Source and Destination location
// of the image as per your machine settings
String SourceLoc  = "D:/Images/photo.jpg";
String DestinationLoc = "D:/Images/TestImage.jpg";

// provide read access to the file

FileStream fs = new FileStream(SourceLoc, FileMode.Open,FileAccess.Read);

// Create a byte array of file stream length
byte[] ImageData = new byte[fs.Length];

//Read block of bytes from stream into the byte array
fs.Read(ImageData,0,System.Convert.ToInt32(fs.Length));

//Close the File Stream
fs.Close();
' Step 2

' Note: Modify the Source and Destination location
' of the image as per your machine settings
Dim SourceLoc As String = "D:/Images/photo.jpg"
Dim DestinationLoc As String = "D:/Images/TestImage.jpg"

' provide read access to the file
Dim Fs As FileStream = New FileStream(SourceLoc,
                       FileMode.Open, FileAccess.Read)

' Create a byte array of file stream length
Dim ImageData As Byte()
ReDim imagedata(fs.Length)

'Read block of bytes from stream into the byte array
fs.Read(ImageData, 0, System.Convert.ToInt32(fs.Length))

'Close the File Stream
fs.Close()
 // Step 3
// Create Anonymous PL/SQL block string
String block = " BEGIN " +
	           " INSERT INTO testblob (id, photo) VALUES (100, :1); " +
	           " SELECT photo into :2 from testblob WHERE id = 100; " +
	           " END; ";
        					
// Set command to create Anonymous PL/SQL Block
OracleCommand cmd = new OracleCommand();
cmd.CommandText = block;
cmd.Connection = con;
								

// Since executing an anonymous PL/SQL block, setting the command type
// as Text instead of StoredProcedure
cmd.CommandType = CommandType.Text;
' Step 3
' Create Anonymous PL/SQL block string
Dim block As String =
   " BEGIN " & _
   " INSERT INTO testblob (id, photo) VALUES (100, :1) ;" & _
   " SELECT photo into :2 from testblob WHERE id = 100 ;" & _
   " end ;"

' Set command to create Anonymous PL/SQL Block
Dim cmd As OracleCommand = New OracleCommand()
cmd.CommandText = block
cmd.Connection = con


' Since executing an anonymous PL/SQL block, setting the command type
' as Text instead of StoredProcedure
cmd.CommandType = CommandType.Text
// Step 4
// Setting Oracle parameters

// Bind the parameter as OracleDbType.Blob to command for inserting image
OracleParameter param = cmd.Parameters.Add("blobtodb", OracleDbType.Blob);
param.Direction = ParameterDirection.Input;


// Assign Byte Array to Oracle Parameter
param.Value = ImageData;

// Bind the parameter as OracleDbType.Blob to command for retrieving the image
OracleParameter param2 = cmd.Parameters.Add("blobfromdb", OracleDbType.Blob);
param2.Direction = ParameterDirection.Output;
' Step 4
' Setting Oracle parameters

' Bind the parameter as OracleDbType.Blob
' to command for inserting image
Dim param As OracleParameter = cmd.Parameters.Add("blobtodb", OracleDbType.Blob)
param.Direction = ParameterDirection.Input

' Assign Byte Array to Oracle Parameter
param.Value = ImageData


' Bind the parameter as OracleDbType.Blob
' to command for retrieving the image
Dim param2 As OracleParameter = cmd.Parameters.Add("blobfromdb", OracleDbType.Blob)
param2.Direction = ParameterDirection.Output

// Step 5
// Execute the Anonymous PL/SQL Block

// The anonymous PL/SQL block inserts the image to the
// database and then retrieves the images as an output parameter
cmd.ExecuteNonQuery();
Console.WriteLine("Image file inserted to database from " + SourceLoc);
' Step 5
' Execute the Anonymous PL/SQL Block
' The anonymous PL/SQL block inserts the image to the database and then retrieves
' the images as an output parameter
cmd.ExecuteNonQuery()
Console.WriteLine("Image file inserted to database from "+ SourceLoc)

// Step 6
// Save the retrieved image to the DestinationLoc in the file system

// Create a byte array
byte[] byteData = new byte[0];

// fetch the value of Oracle parameter into the byte array
byteData = (byte[])((OracleBlob)(cmd.Parameters[1].Value)).Value;

// get the length of the byte array
int ArraySize = new int();
ArraySize = byteData.GetUpperBound(0);

// Write the Blob data fetched from database to the filesystem at the
// destination location
FileStream fs1 = new FileStream(@DestinationLoc,
                                FileMode.OpenOrCreate, FileAccess.Write);
fs1.Write(byteData, 0,ArraySize);
fs1.Close();

Console.WriteLine("Image saved to " + DestinationLoc + " successfully !");
Console.WriteLine("");
Console.WriteLine("***********************************************************");
Console.WriteLine("Before running this application again, execute 'Listing 1' ");
Console.WriteLine("given in 'Create Database Objects' section in the How-to.");
Console.WriteLine("***********************************************************");
' Step 6
' Save the retrieved image to the DestinationLoc in the file system
' Create a byte array
Dim byteData As Byte()
Dim Paramvalue As OracleBlob
Paramvalue = cmd.Parameters(1).Value

' fetch the value of Oracle parameter into the byte array
byteData = CType((Paramvalue.Value), Byte())

' get the length of the byte array
Dim ArraySize As Integer = New Integer()
ArraySize = byteData.GetUpperBound(0)

' Write the Blob data fetched from database to the filesystem at
' the destination location
Dim fs1 As FileStream = New FileStream(DestinationLoc, 
                                       FileMode.OpenOrCreate, FileAccess.Write)
fs1.Write(byteData, 0, ArraySize)
fs1.Close()

Console.WriteLine("Image saved to " + DestinationLoc + " successfully !")
Console.WriteLine("")
Console.WriteLine("***********************************************************")

Console.WriteLine("Before running this application again, execute 'Listing 1' "
Console.WriteLine("given in 'Create Database Objects' section in the How-to.")
Console.WriteLine("***********************************************************") 

Set up and Run the How-To

Resources


Please enter your comments on this How-To in the OTN Sample Code Discussion Forum.

E-mail this page
Printer View Printer View
Oracle Is The Information Company About Oracle | Oracle RSS Feeds | Careers | Contact Us | Site Maps | Legal Notices | Terms of Use | Privacy