Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

In PL SQL, an uncompress of a too big file raise an error

166 views
Skip to first unread message

binp...@gmail.com

unread,
Sep 4, 2015, 11:41:03 AM9/4/15
to
Hello,
I try to uncompress file using the commands utl_compress.lz_uncompress.
I manage to uncompress small file, lesser than a blob max size.
But when I test the program with a bigger file, I'm having the error ORA-29294: A data error occurred during compression or uncompression.

I don't manage to test the size of the blob, before the command "utl_compress.lz_uncompress".

I have put some dbms_output to follow what happens. Here is the results when just before the error raise :

SH.20150402182321.dat.gz ouvert
taille_restant_1309178
taille_a_lire_32000
postion_lecture_32001
taille_restant_1277178
taille_a_lire_32000
postion_lecture_64001

I don't know what to do more, help !

Ben

===================================================================
FUNCTION decompression_fichier (interface_ IN VARCHAR2,
nom_fichier_src_ IN VARCHAR2,
nom_fichier_cible_ IN VARCHAR2,
chemin_ IN VARCHAR2)
RETURN BOOLEAN IS
pointeur_fic_src_ BFILE;
contenu_compresse_ BLOB;
contenu_decompresse_ RAW (32000);
pos_depart_src_ INTEGER := 1;
pos_depart_dst_ INTEGER := 1;
taille_contenu_ INTEGER;
taille_restant_ INTEGER;
taille_a_lire_ INTEGER;
taille_lecture_ INTEGER := 32000;
taille_maxlob_ INTEGER := 32000;
v_file UTL_FILE.file_type;
contenu_lu_ RAW (32000);
postion_lecture_ INTEGER := 1;
lecture_ BOOLEAN;
----
BEGIN
BEGIN

DBMS_LOB.CREATETEMPORARY (contenu_compresse_, TRUE);
DBMS_LOB.OPEN (contenu_compresse_, DBMS_LOB.LOB_READWRITE);
pointeur_fic_src_ := BFILENAME (chemin_, nom_fichier_src_);
DBMS_LOB.fileopen (pointeur_fic_src_, DBMS_LOB.file_readonly);

IF DBMS_LOB.fileexists (pointeur_fic_src_) = 1
THEN
DBMS_OUTPUT.put_line (nom_fichier_src_ || ' ouvert');
v_file := UTL_FILE.fopen (chemin_, nom_fichier_cible_, 'wb');
taille_restant_ := DBMS_LOB.getlength (pointeur_fic_src_);

DBMS_LOB.loadblobfromfile (contenu_compresse_,
pointeur_fic_src_,
DBMS_LOB.GETLENGTH (pointeur_fic_src_),
pos_depart_src_,
pos_depart_dst_);
lecture_ := TRUE;

WHILE lecture_
LOOP
IF taille_restant_ < taille_maxlob_
THEN
taille_a_lire_ := taille_restant_;
lecture_ := FALSE;
ELSE
taille_restant_ := taille_restant_ - taille_maxlob_;
taille_a_lire_ := taille_maxlob_;
END IF;

DBMS_OUTPUT.put_line ('taille_restant_' || taille_restant_);
DBMS_OUTPUT.put_line ('taille_a_lire_' || taille_a_lire_);
DBMS_LOB.READ (contenu_compresse_,
taille_a_lire_,
postion_lecture_,
contenu_lu_);
postion_lecture_ := postion_lecture_ + taille_a_lire_;
DBMS_OUTPUT.put_line ('postion_lecture_' || postion_lecture_);
--
contenu_decompresse_ := utl_compress.lz_uncompress (contenu_lu_);

DBMS_OUTPUT.put_line (UTL_RAW.cast_to_varchar2 (contenu_decompresse_));
UTL_FILE.put_raw (v_file, contenu_decompresse_);
UTL_FILE.fflush (v_file);
END LOOP;

UTL_FILE.fclose (v_file);
DBMS_LOB.fileclose (pointeur_fic_src_);
END IF;


DBMS_LOB.FREETEMPORARY (contenu_compresse_);

-----------------
RETURN TRUE;
EXCEPTION
WHEN OTHERS
THEN
IF UTL_FILE.is_open (v_file)
THEN
UTL_FILE.fclose (v_file);
END IF;
--
IF (DBMS_LOB.fileisopen (pointeur_fic_src_) = 1)
THEN
DBMS_LOB.fileclose (pointeur_fic_src_);
END IF;


RETURN FALSE;
END;
END decompression_fichier;

A. Mehoela

unread,
Sep 6, 2015, 4:12:30 PM9/6/15
to
binp...@gmail.com wrote:
> Hello,
> I try to uncompress file using the commands utl_compress.lz_uncompress.
> I manage to uncompress small file, lesser than a blob max size.
> But when I test the program with a bigger file, I'm having the error ORA-29294: A data error occurred during compression or uncompression.
>
> I don't manage to test the size of the blob, before the command "utl_compress.lz_uncompress".
>
> I have put some dbms_output to follow what happens. Here is the results when just before the error raise :
>
> SH.20150402182321.dat.gz ouvert
> taille_restant_1309178
> taille_a_lire_32000
> postion_lecture_32001
> taille_restant_1277178
> taille_a_lire_32000
> postion_lecture_64001
>
> I don't know what to do more, help !
>
> Ben
> contenu_decompresse_ RAW (32000);
> contenu_lu_ RAW (32000);
> --
> contenu_decompresse_ := utl_compress.lz_uncompress (contenu_lu_);
>

Are you really trying to "uncompress" 32000 characters into 32000 characters, or am I missing something?

bin ush

unread,
Sep 7, 2015, 4:56:36 AM9/7/15
to
Hello,
no, I'm trying to uncompress a file with a size greater than 32000 characters. I want to put the content into a text file that has the necessary size (greater than 32000).

Noons

unread,
Sep 7, 2015, 10:05:19 AM9/7/15
to
I think you need to use an output of type BLOB, not RAW.
RAW is not really supported anymore (unless this is a very old release).


A. Mehoela

unread,
Sep 7, 2015, 3:03:50 PM9/7/15
to
I'll try once more: look at the lines I copied from your code, once you're awake.

You ARE trying to uncompress 32000 bytes into a variable that can also only hold 32000 bytes.

bin ush

unread,
Sep 8, 2015, 8:14:41 AM9/8/15
to
Oups !!!
Indeed, my eyes were so in code that I was blind ...
I have found the solution.
My major problem was the fact that I haven't understood a BLOB could have any quantity of bytes : I thought BLOB was limited to 32767 bytes.
After that everything was clearer.
Here is my solution :
FUNCTION decompression_fichier (nom_fichier_src_ IN VARCHAR2,
nom_fichier_cible_ IN VARCHAR2,
chemin_ IN VARCHAR2)
RETURN BOOLEAN IS
pointeur_fic_src_ BFILE := NULL;
contenu_compresse_ BLOB;
contenu_decompresse_ BLOB;
pos_depart_src_ INTEGER := 1;
pos_depart_dst_ INTEGER := 1;
taille_blob_ INTEGER;
fic_cible_ UTL_FILE.file_type;
contenu_lu_ RAW (32767);
debut_lecture_ NUMBER := 1;
taille_a_lire_ BINARY_INTEGER := 32767;
----
BEGIN
BEGIN

DBMS_LOB.createtemporary (contenu_compresse_, TRUE);
-- Initialise le pointeur correspondant au fichier source compressé
pointeur_fic_src_ := BFILENAME (chemin_, nom_fichier_src_);

IF DBMS_LOB.fileexists (pointeur_fic_src_) = 1
THEN
DBMS_LOB.fileopen (pointeur_fic_src_, DBMS_LOB.file_readonly);
-- Copie de tout le fichier compressé dans un BLOB
DBMS_LOB.loadblobfromfile (contenu_compresse_,
pointeur_fic_src_,
DBMS_LOB.lobmaxsize,
pos_depart_src_,
pos_depart_dst_);
-- Le BLOB ayant le contenu compressé est décompressé dans un BLOB
contenu_decompresse_ := utl_compress.lz_uncompress (contenu_compresse_);
fic_cible_ :=
UTL_FILE.fopen (chemin_,
nom_fichier_cible_,
'wb',
32767);
taille_blob_ := DBMS_LOB.getlength (contenu_decompresse_);

-- Si la taille de la décompression passe en une seule écriture
IF taille_blob_ < 32767
THEN
UTL_FILE.put_raw (fic_cible_, contenu_decompresse_, TRUE);
-- UTL_FILE.fflush (fic_cible_);
ELSE
-- Parcours morceau par morceau de la décompression
-- la taille de chaque morceau correspond à la taille maxi d'un RAW
WHILE debut_lecture_ < taille_blob_
LOOP
--
IF debut_lecture_ + taille_a_lire_ > taille_blob_
THEN
taille_a_lire_ := (taille_blob_ + 1) - debut_lecture_;
END IF;

DBMS_LOB.read (contenu_decompresse_,
taille_a_lire_,
debut_lecture_,
contenu_lu_);
UTL_FILE.put_raw (fic_cible_, contenu_lu_, TRUE);
debut_lecture_ := debut_lecture_ + taille_a_lire_;
--
END LOOP;
END IF;

UTL_FILE.fclose (fic_cible_);
DBMS_LOB.FILECLOSE (pointeur_fic_src_);
END IF;

DBMS_LOB.FREETEMPORARY (contenu_compresse_);
RETURN TRUE;
EXCEPTION
WHEN OTHERS
THEN
IF UTL_FILE.is_open (fic_cible_)
THEN
UTL_FILE.fclose (fic_cible_);
END IF;

--
IF (DBMS_LOB.fileisopen (pointeur_fic_src_) = 1)
THEN
DBMS_LOB.fileclose (pointeur_fic_src_);
END IF;

-- ...

RETURN FALSE;
END;
END decompression_fichier;

Thank you A.Mehoela for your help.

A. Mehoela

unread,
Sep 8, 2015, 3:18:31 PM9/8/15
to
De rien, de rien.

Attantion avec utl_file - je n'ai pas d'expérience avec put_raw - mais il fait parfois des choses qu'on n'a pas demandé.
0 new messages