Solved

Restore BLOBs to .PDF-files

Posted on 2013-12-18
8
866 Views
Last Modified: 2014-01-03
I have found/written a script to create pdf files in a specified directory from a document table with a blob column. Can anyone check this and verify that it will work, or eventually help me fix it?
DECLARE
  l_file      UTL_FILE.FILE_TYPE;
  l_buffer    RAW(32767);
  l_amount    BINARY_INTEGER := 32767;
  l_pos       NUMBER := 1;
  l_blob      BLOB;
  l_blob_len  NUMBER;
  l_doc_key   NUMBER;
  l_location  STRING := 'c:\temp\blobs'
  l_filename  STRING
  
   
  
BEGIN
  FOR l_doc_key IN (109823,142980,220194,392380) -- ...etc.)
    LOOP 
    
  SELECT document
  INTO   l_blob
  FROM   tia.archive
  WHERE  document_key = l_doc_key;

  l_blob_len := DBMS_LOB.getlength(l_blob);

  -- Open the destination file.
  l_file := UTL_FILE.fopen(l_location,l_filename||'.pdf','wb', 32767);

  WHILE l_pos < l_blob_len LOOP
    DBMS_LOB.read(l_blob, l_amount, l_pos, l_buffer);
    UTL_FILE.put_raw(l_file, l_buffer, TRUE);
    l_pos := l_pos + l_amount;
  END LOOP;

  -- Close the file.
  UTL_FILE.fclose(l_file);

END LOOP;

Open in new window

I should end up with a directory with files named

109823.pdf
142980.pdf
220194.pdf
392380.pdf
etc.

Thanks a lot!


IVer
0
Comment
Question by:IverErling
  • 4
  • 3
8 Comments
 
LVL 77

Expert Comment

by:slightwv (䄆 Netminder)
ID: 39726459
On a quick scan, it seems like it should do what you want.  I would just try it in a development database and see what it does.
0
 
LVL 74

Assisted Solution

by:sdstuber
sdstuber earned 500 total points
ID: 39726494
WHILE l_pos < l_blob_len 

Open in new window


I think that should be


 WHILE l_pos <= l_blob_len 

Open in new window


so you don't lose the last character


Simple example:   l_blob_len = 1, you'd never enter the loop

also, your block needs a final

END;

Open in new window

0
 
LVL 74

Assisted Solution

by:sdstuber
sdstuber earned 500 total points
ID: 39726511
Another suggestion,

l_location  STRING := 'c:\temp\blobs'

rather than using direct OS paths,  which require the use of utl_file_dir parameter.
Try creating directory objects first

then use the object name for the FOPEN call.
0
PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

 

Author Comment

by:IverErling
ID: 39727112
Thanks a lot!  I will get one of our DBAs to run it tomorrow and let you know how it goes.

IVer
0
 

Author Comment

by:IverErling
ID: 39728701
I needed to do some changes, and the script now looks like this:
DECLARE
  l_file      UTL_FILE.FILE_TYPE;
  l_buffer    RAW(32767);
  l_amount    BINARY_INTEGER := 32767;
  l_pos       NUMBER := 1;
  l_blob      BLOB;
  l_blob_len  NUMBER;
  l_doc_key   NUMBER;
  l_location  STRING(100) := '\\server\temp\blobs\';
  l_filename  STRING(100);
  type nt_type is table of number;
  nt nt_type := nt_type (1766225,1766227);
  
BEGIN
  FOR i IN 1..nt.count LOOP
    
  SELECT document
  INTO   l_blob
  FROM   tia.archive
  WHERE  document_key = nt(i);

  l_blob_len := DBMS_LOB.getlength(l_blob);

  -- Open the destination file.
  l_file := UTL_FILE.fopen(l_location,nt(i)||'.pdf','wb', 32767);

  WHILE l_pos <= l_blob_len LOOP
    DBMS_LOB.read(l_blob, l_amount, l_pos, l_buffer);
    UTL_FILE.put_raw(l_file, l_buffer, TRUE);
    l_pos := l_pos + l_amount;
  END LOOP;

  -- Close the file.
  UTL_FILE.fclose(l_file);

END LOOP;
END;

Open in new window

When I try to run it I get:
ORA-29280: invalid directory path
ORA-06512 at SYS.UTL_FILE line 41
ORA-06512 at SYS,UTL_FILE line 478
ORA-06512 at line 25

I tried changing directory to several verified locations, but it seems that no matter what I put in, with or whitout the trailing backslash, I get this error. Any ideas anyone?

And the 06512-error I gather has to do with how the file is opened. This should be a .pdf file. Should I change anything?

Can someone please help?

Thanks!
0
 
LVL 74

Accepted Solution

by:
sdstuber earned 500 total points
ID: 39728932
try creating a directory object
for your path and use that

otherwise you need to have your dbas change utl_file_dir - which requires shutting down the database
0
 

Author Comment

by:IverErling
ID: 39731191
Hi!
Using a directory object made the script run and create .pdf-files.

BUT:
Only the first file contains data...

So if I remove the first file number, so the second becomes the first and run the script again the second file (now the first) is created ok and the third is empty and so on.

Please help! I have hundreds of files to create ;-)
DECLARE
  l_file      UTL_FILE.FILE_TYPE;
  l_buffer    RAW(32767);
  l_amount    BINARY_INTEGER := 32767;
  l_pos       NUMBER := 1;
  l_blob      BLOB;
  l_blob_len  NUMBER :=0;
  l_doc_key   NUMBER :=0;
  l_location  STRING(100) := 'TEMP_DIR';
  l_filename  STRING(100);
  type nt_type is table of number;
  nt nt_type := nt_type (1766225, 1766227, 1766228, 1766229, 1766230, 1766231, 1766232, 1766233, 1766234, 1766235, 1766236, 1766237, 1766238, 1766240, 1766241, 1766243, 1766710, 1766730, 1766749, 1766751, 176937); --...etc.
  
BEGIN
  FOR i IN 1..nt.count LOOP
    
  SELECT document
  INTO   l_blob
  FROM   tia.archive
  WHERE  document_key = nt(i);

  l_blob_len := DBMS_LOB.getlength(l_blob);

  -- Open the destination file.
  l_file := UTL_FILE.fopen(l_location,nt(i)||'.pdf','wb', 32767);

  WHILE l_pos <= l_blob_len LOOP
    DBMS_LOB.read(l_blob, l_amount, l_pos, l_buffer);
    UTL_FILE.put_raw(l_file, l_buffer, TRUE);
    l_pos := l_pos + l_amount;
  END LOOP;

  -- Close the file.
  UTL_FILE.fclose(l_file);

END LOOP;
END;

Open in new window

Brgds iVer
0
 
LVL 74

Assisted Solution

by:sdstuber
sdstuber earned 500 total points
ID: 39731595
you need to reset your l_pos variable for each new file.


DECLARE
    l_file     UTL_FILE.file_type;
    l_buffer   RAW(32767);
    l_amount   BINARY_INTEGER := 32767;
    l_pos      NUMBER;
    l_blob     BLOB;
    l_blob_len NUMBER := 0;
    l_doc_key  NUMBER := 0;
    l_location STRING(100) := 'TEMP_DIR';
    l_filename STRING(100);

    TYPE nt_type IS TABLE OF NUMBER;

    nt         nt_type
                   := nt_type(
                          1766225,
                          1766227,
                          1766228,
                          1766229,
                          1766230,
                          1766231,
                          1766232,
                          1766233,
                          1766234,
                          1766235,
                          1766236,
                          1766237,
                          1766238,
                          1766240,
                          1766241,
                          1766243,
                          1766710,
                          1766730,
                          1766749,
                          1766751,
                          176937
                      ); --...etc.
BEGIN
    FOR i IN 1 .. nt.COUNT
    LOOP
        SELECT document
          INTO l_blob
          FROM tia.archive
         WHERE document_key = nt(i);

        l_blob_len := DBMS_LOB.getlength(l_blob);

        -- Open the destination file.
        l_file :=
            UTL_FILE.fopen(
                l_location,
                nt(i) || '.pdf',
                'wb',
                32767
            );
        l_pos := 1;
        WHILE l_pos <= l_blob_len
        LOOP
            DBMS_LOB.read(
                l_blob,
                l_amount,
                l_pos,
                l_buffer
            );
            UTL_FILE.put_raw(l_file, l_buffer, TRUE);
            l_pos := l_pos + l_amount;
        END LOOP;

        -- Close the file.
        UTL_FILE.fclose(l_file);
    END LOOP;
END;

Open in new window

0

Featured Post

PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
SQL2016 to ORACLE11G linked-server 6 28
oracle differnce between two timestamps 5 31
storing csv file in table variable in Python 2 28
Error in creating a view. 8 23
A short article about problems I had with the new location API and permissions in Marshmallow
Shell script to create broker configuration file using current broker Configuration, solely for purpose of backup on Linux. Script may need to be modified depending on OS-installation. Please deploy and verify the script in a test environment.
This video shows how to configure and send email from and Oracle database using both UTL_SMTP and UTL_MAIL, as well as comparing UTL_SMTP to a manual SMTP conversation with a mail server.
In this fourth video of the Xpdf series, we discuss and demonstrate the PDFinfo utility, which retrieves the contents of a PDF's Info Dictionary, as well as some other information, including the page count. We show how to isolate the page count in a…

830 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question