by benvandijk » Mon Feb 26, 2007 6:50 am
Mario,
Your method is restricted to 32k because that is the maximum size of the Oracle raw field. We solved this in Vast 6.02 using an Oracle stored procedure which reads chunks of about 30k bytes from the blob.
In smalltalk we call this procedure repeatedly to get all data.
We use a similar process to write data to the blob from smalltalk.
Our smalltalk code (with excuses for the dutch comments and variable names, if neeed i can translate them for you )
=========
leesBlobInByteArray
" Maak van de Blob waarop de ontvanger betrekking heeft weer een byteArray
"
| eenInputOutputRow eenInputDict einde positie byteArray eenOutputDict |
eenInputOutputRow :=
(AbtCompoundType new
name: '' ;
addField: ((#AbtDatabaseLongVarBinaryField asClass) new name: 'P_RAUW'; nullsOk: true; procBindType: 4; count: 32767) ;
addField: ( (#AbtDatabaseDoubleFloatField asClass) new name: 'P_ID'; nullsOk: true; procBindType: 1; isFloat: false) ;
addField: ( (#AbtDatabaseDoubleFloatField asClass) new name: 'P_POSITIE'; nullsOk: true; procBindType: 1; isFloat: false) ;
addField: ((#AbtDatabaseVarCharField asClass) new name: 'P_EINDE'; nullsOk: true; procBindType: 4; count: 1)).
eenInputDict := Dictionary new.
self byteArrayCollectie: OrderedCollection new.
eenInputDict at: 'P_ID' put: (self id).
positie := 1.
einde := 'N'.
[ einde = 'N' ]
whileTrue: [
eenInputDict at: 'P_POSITIE' put: positie.
eenOutputDict := (self class dataStore)
invokeStoredProcNamed: 'lees_blob'
withInputDictionary: eenInputDict
inputRow: eenInputOutputRow
ifError: [ :anError | self businessError: 'fout in proc lees_blob' . ].
byteArray := eenOutputDict at: 'P_RAUW'.
einde := eenOutputDict at: 'P_EINDE'.
positie := positie + (byteArray size).
self byteArrayCollectie add: byteArray.
].
==========
invokeStoredProcNamed: aStoredProcName withInputDictionary: aDictionary inputRow: aRow ifError: anErrorBlock
| aStoredProcSpec |
aStoredProcSpec := AbtStoredProcSpec new
name: aStoredProcName ;
procName: aStoredProcName ;
databaseMgrName: AbtDatabaseManager name ;
useSqlCall: true ;
inputStringLabel: nil ;
inputRow: aRow ;
yourself.
^self connection
invokeStoredProcSpec: aStoredProcSpec
withInputDictionary: aDictionary
ifError: anErrorBlock
==========
And here is the oracle stored procedure
==========
CREATE OR REPLACE procedure lees_blob
( p_rauw out raw, p_id number, p_positie number, p_einde out varchar2)
is
v_blob_loc BLOB;
v_aantal BINARY_INTEGER;
begin
select object
into v_blob_loc
from blob_tabel
where id = p_id;
DBMS_LOB.OPEN (v_blob_loc, DBMS_LOB.LOB_READONLY);
v_aantal := DBMS_LOB.GETLENGTH (v_blob_loc);
v_aantal := v_aantal + 1 - p_positie;
if v_aantal > 30000 then
v_aantal := 30000;
p_einde := 'N';
else
p_einde := 'Y';
end if;
DBMS_LOB.READ (v_bLob_loc, v_aantal, p_positie, p_rauw);
DBMS_LOB.CLOSE (v_blob_loc);
end lees_blob;
=========