• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 2516
  • Last Modified:

How do i open oracle blob field with word using stream

Hello Experts
I have Oracle database that stores .doc files as blob.
Today I fetch those files and save them to temp directory before I open then with
ShellExecute( self.Handle, nil, PCHAR(dir), Nil, Nil, SW_SHOWNORMAL );

Is there any way to save the file into stream and open it with MIcrosoft Word 2007 WITHOUT saving it to my hard disk first?


I am using Delphi 2007 and Oracle 10g.

Best Regards
Albert.
0
Programm
Asked:
Programm
  • 5
  • 5
  • 2
2 Solutions
 
Ephraim WangoyaCommented:

I don't believe its possible unless you are using an OleContainer then you can call CreateObjectFromStream
0
 
ProgrammAuthor Commented:
Hi ewanqoya
Can you show me an example of that function?
My DB function return TLOBLocator.



0
 
Ephraim WangoyaCommented:

Note, using this method you are opening the file in a TOleContainer and not calling Mocrosoft Word

Add this method to the OleContainer as public
procedure CreateObjectFromStream(Stream: TStream);

Drop a TOleContainer component on your form

Then, pass your stream straight to the method instead of creating a file
eg

var
  Stream: TStream;
  Field: TField;
begin
 Field := Dataset.FieldByName('Name of field with Blob');
 Stream := Dataset.CreateBlobStream(Field, bmRead);
 try
   OleContainer1.CreateObjectFromStream(Stream);
 finally
   FreeAndNil(Stream);
 end;
end;

procedure TOleContainer.CreateObjectFromStream(Stream: TStream);
var
  DataHandle: HGLOBAL;
  Buffer: Pointer;
begin
  DataHandle := GlobalAlloc(GMEM_MOVEABLE, Stream.Size);
  if DataHandle = 0 then OutOfMemoryError;
  try
    Buffer := GlobalLock(DataHandle);
    try
      Stream.Read(Buffer^, Stream.Size);
    finally
      GlobalUnlock(DataHandle);
    end;
    OleCheck(CreateILockBytesOnHGlobal(DataHandle, True, FLockBytes));
    DataHandle := 0;
    OleCheck(StgOpenStorageOnILockBytes(FLockBytes, nil, STGM_READWRITE or
      STGM_SHARE_EXCLUSIVE, nil, 0, FStorage));
    OleCheck(OleLoad(FStorage, IOleObject, self, FOleObject));
    FDrawAspect := DVASPECT_CONTENT;
    InitObject;
    FOleObject.SetExtent(DVASPECT_CONTENT, PixelsToHimetric(Point(ClientWidth, ClientHeight)));
    SetDrawAspect(False, 0);
    UpdateView;
  except
    if DataHandle <> 0 then GlobalFree(DataHandle);
    DestroyObject;
    raise;
  end;
end;

Open in new window

0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
Geert GruwezOracle dbaCommented:
the TOleContainer will call Word ...
0
 
Geert GruwezOracle dbaCommented:
from oracle inside blob, you will always to have to save it on local disk

things like olecontainer will save it in temp folder behind the scenes
so what is the point in taking a detour ?
0
 
Ephraim WangoyaCommented:

Actually Geert, many applications create temporary files behind the scene. Does that mean we should never use load from stream methods?
0
 
ProgrammAuthor Commented:
Thanks for the code ewanqoya. It's working great. It dosn't create a .doc file in the temp folder, only .tmp file and that is allright.
Can you please show me how to save it back to the db from the Stream? That would be great.
0
 
Ephraim WangoyaCommented:

You can use LoadFromStream


var
  F: TField;
  Stream: TStream;
begin
  F := Dataset.FindField('Your field name');
  Stream := TStream.Create;
  try
    OleContainer1.SaveToStream(Stream);
    Stream.Seek(0, soFromBeginning);
    TBlobField(F).LoadFromStream(Stream);
  finally
    FreeAndNil(Stream);
  end;
end;

Open in new window

0
 
ProgrammAuthor Commented:
Ok, that almost worked. But I go a Abstract error because TStream is abstract and SaveToStream(Stream) doesn't work.
I tried to change it to TMemoryStream but my blob field was corrupted when I tried to open it again.

 
var
  Stream : TMemoryStream;
  Field : TField;
  iSizeAfter : integer;
begin
    m_qry.Edit;
    Field := m_qry.FindField('BSKRA');
    Stream := TMemoryStream.Create;

    OleContainerP1.SaveToStream(Stream);
    Stream.Seek(0, soFromBeginning);
    TBlobField(Field).LoadFromStream(Stream);
    m_qry.Post;
    Self.Close;
end;

Open in new window


0
 
Ephraim WangoyaCommented:

Add check in the procedure to look for the OLE header


procedure TOleContainer.CreateObjectFromStream(Stream: TStream);
var
  DataHandle: HGLOBAL;
  Buffer: Pointer;
  Header: TStreamHeader;
begin
  Stream.ReadBuffer(Header, SizeOf(Header));
  if (Header.Signature = StreamSignature) then 
  begin
    //if it has OLE header then read the normal way
    Stream.Seek(0, soFromBeginning);
    LoadFromStream(Stream);
    Exit;
  end;

  Stream.Seek(0, soFromBeginning);
  DataHandle := GlobalAlloc(GMEM_MOVEABLE, Stream.Size);
  if DataHandle = 0 then OutOfMemoryError;
  try
    Buffer := GlobalLock(DataHandle);
    try
      Stream.Read(Buffer^, Stream.Size);
    finally
      GlobalUnlock(DataHandle);
    end;
    OleCheck(CreateILockBytesOnHGlobal(DataHandle, True, FLockBytes));
    DataHandle := 0;
    OleCheck(StgOpenStorageOnILockBytes(FLockBytes, nil, STGM_READWRITE or
      STGM_SHARE_EXCLUSIVE, nil, 0, FStorage));
    OleCheck(OleLoad(FStorage, IOleObject, self, FOleObject));
    FDrawAspect := DVASPECT_CONTENT;
    InitObject;
    FOleObject.SetExtent(DVASPECT_CONTENT, PixelsToHimetric(Point(ClientWidth, ClientHeight)));
    SetDrawAspect(False, 0);
    UpdateView;
  except
    if DataHandle <> 0 then GlobalFree(DataHandle);
    DestroyObject;
    raise;
  end;
end;

Open in new window

0
 
ProgrammAuthor Commented:
Great !!!!!! That worked.
Thank you so much ewanqoya for your help.
0
 
ProgrammAuthor Commented:
Great work by ewanqoya
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

  • 5
  • 5
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now