bingohua
asked on
SOS,how can dynamically insert images(.jpg,.bmp,.gif)into a blob field in oracle ?
hi,dear experts:
Here I need your kind help very much.
Suppose I have created a table,as follows:
create table imagetest(id number(8) not null primary key,image blob);
My questions are as follows:
Now,I don't know how I can dynamically insert the images(.jpg,.bmp,.gif)into the image field,and if done,how I can
display them and how I can get the image's filename of the blobfield image.
Have you got it?If so,please help me.Some detailed code with delphi is the best.Thank you very much.
Here I need your kind help very much.
Suppose I have created a table,as follows:
create table imagetest(id number(8) not null primary key,image blob);
My questions are as follows:
Now,I don't know how I can dynamically insert the images(.jpg,.bmp,.gif)into
display them and how I can get the image's filename of the blobfield image.
Have you got it?If so,please help me.Some detailed code with delphi is the best.Thank you very much.
First create this Oracle package:
create or replace package root.utl as
blob1 blob;
blob2 blob;
blob3 blob;
function blob_is_null(b in blob) return number;
PRAGMA RESTRICT_REFERENCES(blob_i s_null, WNDS, RNDS, WNPS);
end;
/
create or replace package body root.utl as
function blob_is_null(b in blob)
return number is
begin
if b is null then
return 1;
else
return 0;
end if;
end;
end;
/
grant all on root.utl to public;
create public synonym utl for root.utl;
then use this unit to read and write blobs:
unit blobs;
interface
uses SysUtils, Windows, Classes, dbcore, oci73;
function BlobIsNull(TableName, KeyField, BlobField: String; KeyValue: Double): Boolean;
function LoadBlob(TableName, KeyField, BlobField: String; KeyValue: Double): String;
procedure ClearBlob(TableName, KeyField, BlobField: String; KeyValue: Double);
procedure SaveBlob(Text: String; TableName, KeyField, BlobField: String; KeyValue: Double);
implementation
function BlobIsNull(TableName, KeyField, BlobField: String; KeyValue: Double): Boolean;
var
FQuery: TNativeQuery;
IsEmpty: Integer;
begin
FQuery := Connection.GetQuery;
try
FQuery.ParseSQL('select utl.blob_is_null('+BlobFie ld+')'+
' from '+TableName+' where '+KeyField+' = '+FloatToStr(KeyValue), nil);
FQuery.DefInteger(1, IsEmpty);
FQuery.Execute;
Result := not FQuery.Fetch or (IsEmpty = 1);
FQuery.Close;
finally
FQuery.Free;
end;
end;
function LoadBlob(TableName, KeyField, BlobField: String; KeyValue: Double): String;
var
Stream: TStream;
FQuery: TNativeQuery;
Buffer: array [0..4095] of Byte;
amt, pos: Integer;
begin
Result := '';
if BlobIsNull(TableName, KeyField, BlobField, KeyValue) then
Exit;
FQuery := Connection.GetQuery;
try
FQuery.ParseSQL('begin select '+BlobField+' into utl.blob1'+
' from '+TableName+' where '+KeyField+' = '+FloatToStr(KeyValue)+'; end;', nil);
FQuery.Execute;
Stream := TMemoryStream.Create;
try
FQuery.ParseSQL('begin dbms_lob.read(utl.blob1, :amt, :pos, :buffer); end;');
FQuery.BindInteger('amt', amt);
FQuery.BindInteger('pos', pos);
FQuery.BindRaw('buffer', Buffer, sizeof(Buffer));
pos := 1;
Stream.Seek(0, 0);
FQuery.ErrorMode := ociReturnStatus;
while true do
begin
amt := sizeof(Buffer);
FQuery.Execute;
if FQuery.Status <> 0 then
if FQuery.Status = NO_DATA_FOUND then
break
else Connection.RaiseOracleExce ption(FQue ry.Status) ;
Stream.Write(Buffer, amt);
pos := pos + amt;
end;
Stream.Seek(0, 0);
FQuery.Close;
SetString(Result, nil, Stream.Size);
Stream.Read(Pointer(Result )^, Stream.Size);
Connection.ExecSQL('begin utl.blob1 := null; end;');
finally
Stream.Free;
end;
finally
FQuery.Free;
end;
end;
procedure SaveBlob(Text: String; TableName, KeyField, BlobField: String; KeyValue: Double);
var
Query: TNativeQuery;
Stream: TMemoryStream;
Buffer: array [0..1024-1] of Byte;
amt, pos, Size, l: Integer;
p: PChar;
begin
Query := Connection.GetQuery;
try
// Init blob field
Query.ParseSQL('begin update '+TableName+' set '+BlobField+'= EMPTY_BLOB()'+
' where '+KeyField+' = '+FloatToStr(KeyValue)+
' returning '+BlobField+' into utl.blob1; end;', nil);
Query.Execute;
Query.Close;
Stream := TMemoryStream.Create;
try
l := length(Text);
p := PChar(Text);
Stream.SetSize(l);
Stream.Write(p^, l);
Stream.Seek(0, 0);
Query.ParseSQL('begin dbms_lob.write(utl.blob1, :amt, :pos, :buffer); end;', nil);
Query.BindInteger('amt', amt);
Query.BindInteger('pos', pos);
Query.BindRaw('buffer', Buffer, sizeof(Buffer));
pos := 1;
Query.ErrorMode := ociRaiseException;
Size := Stream.Size;
while (pos - 1) < Size do
begin
amt := Stream.Read(Buffer, sizeof(Buffer));
Query.Execute;
pos := pos + amt;
end;
Query.Close;
finally
Stream.Free;
end;
finally
Query.Free;
end;
end;
procedure ClearBlob(TableName, KeyField, BlobField: String; KeyValue: Double);
var
FQuery: TNativeQuery;
begin
FQuery := Connection.GetQuery;
try
FQuery.ParseSQL('update '+TableName+' set '+BlobField+' = null '+
' where '+KeyField+' = '+FloatToStr(KeyValue), nil);
FQuery.Execute;
FQuery.Close;
finally
FQuery.Free;
end;
end;
end.
create or replace package root.utl as
blob1 blob;
blob2 blob;
blob3 blob;
function blob_is_null(b in blob) return number;
PRAGMA RESTRICT_REFERENCES(blob_i
end;
/
create or replace package body root.utl as
function blob_is_null(b in blob)
return number is
begin
if b is null then
return 1;
else
return 0;
end if;
end;
end;
/
grant all on root.utl to public;
create public synonym utl for root.utl;
then use this unit to read and write blobs:
unit blobs;
interface
uses SysUtils, Windows, Classes, dbcore, oci73;
function BlobIsNull(TableName, KeyField, BlobField: String; KeyValue: Double): Boolean;
function LoadBlob(TableName, KeyField, BlobField: String; KeyValue: Double): String;
procedure ClearBlob(TableName, KeyField, BlobField: String; KeyValue: Double);
procedure SaveBlob(Text: String; TableName, KeyField, BlobField: String; KeyValue: Double);
implementation
function BlobIsNull(TableName, KeyField, BlobField: String; KeyValue: Double): Boolean;
var
FQuery: TNativeQuery;
IsEmpty: Integer;
begin
FQuery := Connection.GetQuery;
try
FQuery.ParseSQL('select utl.blob_is_null('+BlobFie
' from '+TableName+' where '+KeyField+' = '+FloatToStr(KeyValue), nil);
FQuery.DefInteger(1, IsEmpty);
FQuery.Execute;
Result := not FQuery.Fetch or (IsEmpty = 1);
FQuery.Close;
finally
FQuery.Free;
end;
end;
function LoadBlob(TableName, KeyField, BlobField: String; KeyValue: Double): String;
var
Stream: TStream;
FQuery: TNativeQuery;
Buffer: array [0..4095] of Byte;
amt, pos: Integer;
begin
Result := '';
if BlobIsNull(TableName, KeyField, BlobField, KeyValue) then
Exit;
FQuery := Connection.GetQuery;
try
FQuery.ParseSQL('begin select '+BlobField+' into utl.blob1'+
' from '+TableName+' where '+KeyField+' = '+FloatToStr(KeyValue)+'; end;', nil);
FQuery.Execute;
Stream := TMemoryStream.Create;
try
FQuery.ParseSQL('begin dbms_lob.read(utl.blob1, :amt, :pos, :buffer); end;');
FQuery.BindInteger('amt', amt);
FQuery.BindInteger('pos', pos);
FQuery.BindRaw('buffer', Buffer, sizeof(Buffer));
pos := 1;
Stream.Seek(0, 0);
FQuery.ErrorMode := ociReturnStatus;
while true do
begin
amt := sizeof(Buffer);
FQuery.Execute;
if FQuery.Status <> 0 then
if FQuery.Status = NO_DATA_FOUND then
break
else Connection.RaiseOracleExce
Stream.Write(Buffer, amt);
pos := pos + amt;
end;
Stream.Seek(0, 0);
FQuery.Close;
SetString(Result, nil, Stream.Size);
Stream.Read(Pointer(Result
Connection.ExecSQL('begin utl.blob1 := null; end;');
finally
Stream.Free;
end;
finally
FQuery.Free;
end;
end;
procedure SaveBlob(Text: String; TableName, KeyField, BlobField: String; KeyValue: Double);
var
Query: TNativeQuery;
Stream: TMemoryStream;
Buffer: array [0..1024-1] of Byte;
amt, pos, Size, l: Integer;
p: PChar;
begin
Query := Connection.GetQuery;
try
// Init blob field
Query.ParseSQL('begin update '+TableName+' set '+BlobField+'= EMPTY_BLOB()'+
' where '+KeyField+' = '+FloatToStr(KeyValue)+
' returning '+BlobField+' into utl.blob1; end;', nil);
Query.Execute;
Query.Close;
Stream := TMemoryStream.Create;
try
l := length(Text);
p := PChar(Text);
Stream.SetSize(l);
Stream.Write(p^, l);
Stream.Seek(0, 0);
Query.ParseSQL('begin dbms_lob.write(utl.blob1, :amt, :pos, :buffer); end;', nil);
Query.BindInteger('amt', amt);
Query.BindInteger('pos', pos);
Query.BindRaw('buffer', Buffer, sizeof(Buffer));
pos := 1;
Query.ErrorMode := ociRaiseException;
Size := Stream.Size;
while (pos - 1) < Size do
begin
amt := Stream.Read(Buffer, sizeof(Buffer));
Query.Execute;
pos := pos + amt;
end;
Query.Close;
finally
Stream.Free;
end;
finally
Query.Free;
end;
end;
procedure ClearBlob(TableName, KeyField, BlobField: String; KeyValue: Double);
var
FQuery: TNativeQuery;
begin
FQuery := Connection.GetQuery;
try
FQuery.ParseSQL('update '+TableName+' set '+BlobField+' = null '+
' where '+KeyField+' = '+FloatToStr(KeyValue), nil);
FQuery.Execute;
FQuery.Close;
finally
FQuery.Free;
end;
end;
end.
Sorry. I forget what you don't have a TNativeQuery.
This is our own libriry for native access to Oracle.
So, you can't use this code :)
This is our own libriry for native access to Oracle.
So, you can't use this code :)
hello,bingohua, are you here?
ASKER
hi,kretzschmar ,thank you for you kind help very much.
Here I also met with some questions in your code:
If I run this program again,the line code as follows always show error(if I delete from this table,that is to say,if this table is empty,the error won't show.why?
JPegImage.LoadFromStream(M yBlobStrea m);
Plus:There doesn't exist a field which holds the image's name,then how I can cope with different images(.bmp,.gif etc.)?
Hope to hear from you.By the way,reward is no problem.:))
Here I also met with some questions in your code:
If I run this program again,the line code as follows always show error(if I delete from this table,that is to say,if this table is empty,the error won't show.why?
JPegImage.LoadFromStream(M
Plus:There doesn't exist a field which holds the image's name,then how I can cope with different images(.bmp,.gif etc.)?
Hope to hear from you.By the way,reward is no problem.:))
ASKER
And how I can insert a .gif image into the blob field in oracle8i?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thank you for your instant help.I appreciate it.
for other formats, you've to include at least the suffix of the filename, where you can then decide which conversion is needed for display, for the filename you must also include a field in your table, which holds this name
unit db_pict_u;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Db, DBTables, ExtCtrls, DBCtrls, StdCtrls, Mask, Menus, jpeg; // JPeg unit is used
type
TForm1 = class(TForm)
DBEdit1: TDBEdit; // A other DBField
DBNavigator1: TDBNavigator;
Table1: TTable;
DataSource1: TDataSource;
PopupMenu1: TPopupMenu; // a Popup linked to Image1
LoadPicture1: TMenuItem; // the MenuItem of the Popup
OpenDialog1: TOpenDialog; // OpenDialog
Image1: TImage; // Visual Output for the JPeg
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure LoadJPEG1Click(Sender: TObject); // File Load and Store in DB
procedure Table1AfterScroll(DataSet:
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;
var
Form1: TForm1;
JPegImage : TJpegImage; //A temporary JPeg-Object
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
begin
JpegImage := TJPegImage.Create; // Create JPeg-Object
Table1.Open;
end;
procedure TForm1.FormDestroy(Sender:
begin
Table1.Close;
JPegImage.Free; // Free JPeg-Object
end;
procedure TForm1.LoadJPEG1Click(Send
Var
MyBlobStream : TBlobStream; // Streams
MyJPegStream : TMemoryStream;
begin
if Table1.State in [dsEdit,dsInsert] then // Do only if in edit or insert mode
begin
If opendialog1.Execute then // If file selected
begin
if Table1.FieldByName('Bild2'
begin
MyJPegStream := TMemoryStream.Create; // Handle JPegFile
JPegImage.LoadFromFile(ope
JPegImage.SaveToStream(MyJ
// Prepare Blob
MyBlobStream := TBlobStream.Create(TBlobFi
MyBlobStream.CopyFrom(MyJP
Image1.Picture.Assign(JPeg
MyJPegStream.Free; //Free all
MyBlobStream.Free;
end;
end;
end else ShowMessage('Table is not in Edit Mode!');
end;
procedure TForm1.Table1AfterScroll(D
Var
MyBlobStream : TBlobStream;
begin
// Do Only if a JPeg available
if (Table1.FieldByName('Bild2
begin
// Prepare Streams
MyBlobStream := TBlobStream.Create(TBlobFi
JPegImage.LoadFromStream(M
Image1.Picture.Assign(JPeg
MyBlobStream.Free; // Free Stream
end
else image1.Picture := Nil; // No JPeg saved disable display
end;
end.
meikl ;-)))