Problem with TOracleDirectPathLoader and BLOB on Oracle 8.1.7.0.0 Standard Edition

capelle

Member
Hello,
I try to load BLOB field with JPEG files, with your demo project DirectPath.dpr that i have modified.
The file size of each JPEG is greater than 300 kilo-bytes.
I loading the data without errors, but each BLOB field is incomplete, i have just the begining with incremental JPEGs (+/-50 kilo-bytes, by using DBMS_LOB.GETLENGTH).
If I save the memory stream to disk the JPEG file is fine.
I Have the same problem with LONG RAW columns instead of BLOB
Each JPEG file is ok on IE5. The table that I try to load is this one :
CREATE TABLE T1_FG_4 (
ESE NUMBER(6) ,
SECTION VARCHAR2(15),
ATB404 BLOB)

I can't find the cause of the problem.
Please help me.

Versions informations (Oracle Standard Edition) :
Oracle8i : Release 8.1.7.0.0 - Production
PL/SQL : Release 8.1.7.0.0 - Production
CORE : 8.1.7.0.0 Production
TNS for 32-bit Windows: Version 8.1.7.0.0 - Production
NLSRTL Version 3.4.1.0.0 - Production
SQL*NET : 8.1.7.0.0
DOA : Version 3.4.5 July 2001

Here is my unit derived from the example :

unit MainUnit;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Oracle, OracleData, StdCtrls, OracleCI, OracleMonitor, Db, DBTables;

type
// Some collection classes to store the import data
TFileItem = class(TCollectionItem)
public
ESE : Integer;
SECTION : string;
ATB404 : TMemoryStream;
end;
TFileItems = class(TCollection)
private
function GetFileItem(Index: Integer): TFileItem;
public
property FileItem[Index: Integer]: TFileItem read GetFileItem; default;
end;
// The Main Form
TMainForm = class(TForm)
CreateTableQuery: TOracleQuery;
MainSession: TOracleSession;
MainLogon: TOracleLogon;
CreateTableBtn: TButton;
DropTableBtn: TButton;
DropTableQuery: TOracleQuery;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
SelectFileBtn: TButton;
BenchmarkBtn: TButton;
OpenDialog: TOpenDialog;
FilenameLabel: TLabel;
TruncateTableQuery: TOracleQuery;
ResultsMemo: TMemo;
Loader: TOracleDirectPathLoader;
procedure CreateTableBtnClick(Sender: TObject);
procedure LoadJPEGFiles;
procedure DropTableBtnClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure SelectFileBtnClick(Sender: TObject);
procedure BenchmarkBtnClick(Sender: TObject);
private
FileItems: TFileItems;

FileCount : Integer;

procedure TruncateTable;
procedure DirectPathLoadBenchmark;
end;

var
MainForm: TMainForm;

implementation

uses OracleDPColumnsEdit;

{$R *.DFM}

function TFileItems.GetFileItem(Index: Integer): TFileItem;
begin
Result := Items[Index] as TFileItem;
end;

procedure TMainForm.FormCreate(Sender: TObject);
begin
if not MainSession.Connected then MainLogon.Execute;
if not MainSession.Connected then Halt;
FileCount := 0;
end;

// Create the table
procedure TMainForm.CreateTableBtnClick(Sender: TObject);
begin
CreateTableQuery.Execute;
end;

// Drop the table
procedure TMainForm.DropTableBtnClick(Sender: TObject);
begin
DropTableQuery.Execute;
end;

// Truncate the table
procedure TMainForm.TruncateTable;
begin
TruncateTableQuery.Execute;
end;

// Select the text file that we will load into the database for the benchmark
procedure TMainForm.SelectFileBtnClick(Sender: TObject);
begin
LoadJPEGFiles;
end;

// Load the text file that we will load into the database for the benchmark

// Perform the Direct Path Loading Benchmark
procedure TMainForm.DirectPathLoadBenchmark;
var i, Row : Integer;
TempDir : String;
begin
SetLength(TempDir,1000);
SetLength(TempDir,GetTempPath(Length(TempDir),@TempDir[1]));

// Prepare the loader
Loader.BufferSize := 5242880; // 5Mb
Loader.Prepare;

// Process all data in batches of records
Row := 0;

for i := 0 to FileItems.Count-1 do
begin

// Copy record to array
Loader.Columns[0].SetData(Row, @FileItems.Ese, 0); // NUMBER(6)
Loader.Columns[1].SetData(Row, @FileItems.Section[1], Length(FileItems.Section) ); // VARCHAR2(15)
//Loader.Columns[2].SetData(Row, NIL, 0); // BLOB (max=315 Kilo-bytes)
Loader.Columns[2].SetData(Row, FileItems.ATB404.Memory, FileItems.ATB404.Size); // BLOB (max=315 Kilo-bytes)
Inc(Row);
// We have filled the array, or we are at the end of the file: load it
if (Row = Loader.MaxRows) or (i = FileItems.Count - 1) then
begin
try
Loader.Load(Row);
except
on E:EOracleError do
begin
ShowMessage(E.Message + #13#10#13#10 +
'Row = ' + IntToStr(Loader.LastRow) + ', ' +
'Col = ' + IntToStr(Loader.LastColumn));
Loader.Abort;
Exit;
end;
end;
Row := 0;
end;
end;
// Commit the loaded data
Loader.Finish;
Loader.Session.Commit;

end;

// Perform all benchmarks
procedure TMainForm.BenchmarkBtnClick(Sender: TObject);
var T3: dword;
s: string;
i:Integer;
begin
Screen.Cursor := crHourGlass;
try
// Clear the benchmark results
ResultsMemo.Text := '';

if not OCI81 then
s := 'Direct Path Loading requires Net8 8.1'
else begin
// Truncate the table again without influencing the benchmark
TruncateTable;
// Perform benchmark with array insert statements
T3 := GetTickCount;
DirectPathLoadBenchmark;
T3 := GetTickCount - T3;
s := 'Direct Path Loading: ' + FloatToStr(T3 / 1000) + ' sec';
end;
ResultsMemo.Lines.Add(s);
finally
for i := 0 to FileItems.Count - 1 do
FileItems.FileItem.ATB404.Free;
FileItems.Free;
FilenameLabel.Caption := 'No file loaded';
Screen.Cursor := crDefault;
end;
end;

procedure TMainForm.LoadJPEGFiles;
var i: Integer;
TempDir : String;
begin
SetLength(TempDir,1000);
SetLength(TempDir,GetTempPath(Length(TempDir),@TempDir[1]));

FileItems := TFileItems.Create(TFileItem);
if FileCount=0 then FileCount:=119; // 119 files to load from temp path
for i := 0 to FileCount - 1 do
begin
with TFileItem.Create(FileItems) do
begin
Ese := 1;
Section := Format('SEC%d',[i+1]);
ATB404 := TMemoryStream.Create;
ATB404.LoadFromFile(Format('%sIMG%d.JPG',[TempDir,i+1]));
end;
end;
FilenameLabel.Caption := Format('%d JPEG files loaded in memory',[FileCount]);
end;

end.

[This message has been edited by capelle (edited 25 October 2001).]
 
I don't immediately see anything wrong with this. There should not be any size limitation as far as I know. Do things work correctly for smaller jpg images?

------------------
Marco Kalter
Allround Automations
 
Originally posted by mkalter:
I don't immediately see anything wrong with this. There should not be any size limitation as far as I know. Do things work correctly for smaller jpg images?


Yes, it works correctly with smaller jpg files.
However, After calling the Prepare method, I remark that the MaxRows is very less than then MaxRow I expected : For example if sum of the fileSize if 10Mb and the BufferSize 20Mo, there is 2 calls to the Load method.
Thanks for your help.
 
The value of MaxRows primarily depends on the DataSize of your BLOB column. It should probably be (BufferSize div Loader.Columns[2].DataSize).

------------------
Marco Kalter
Allround Automations
 
Originally posted by mkalter:
The value of MaxRows primarily depends on the DataSize of your BLOB column. It should probably be (BufferSize div Loader.Columns[2].DataSize).


I have maden others tests, If the bufferSize is greater than the total size to load, all rows are loaded in one pass while there isn't any LOB/LONG field.

If there is on LOB/LONG field (like this example) I always obtain 64 for MaxRows (I think it's de default value for loading in conventionanal path). Does Oracle change the loading mode ? I can't understand...
 
Hi all,
we also REALLY need this feature (directpathloader + many jpegs, gifs > 64 KB).
It seems, that in the newest version (3.4.6.1, standard, registered) that bug has still unsolved.

Any quick help or any idea ?

greetings, sorry my BAD English
frown.gif


Jurek.
Originally posted by mkalter:
The value of MaxRows primarily depends on the DataSize of your BLOB column. It should probably be (BufferSize div Loader.Columns[2].DataSize).

 
As far as we know this is a problem in the Direct Path Interface. If you are primarily loading large binary objects, you could use the TLOBLocator instead. It should be quite efficient.

------------------
Marco Kalter
Allround Automations
 
Hi,
Originally posted by mkalter:
As far as we know this is a problem in the Direct Path Interface. If you are primarily loading large binary objects,

MANY (ca. 300 - 500) records with text fields and single blob field (SMALL jpeg's, gif's, png's, etc.).

you could use the TLOBLocator instead. It should be quite efficient.
QUOTE]

greetings,

Jurek.

[This message has been edited by jurekl (edited 16 May 2002).]
 
Back
Top