0

I would like to check if there's no data coming from SQL query then file should not be created.

Here is my code:

CREATE OR REPLACE PROCEDURE VR_AD_INTEGRATION_EXPORT AS
    l_v_file UTL_FILE.file_type
BEGIN
 l_v_file := UTL_FILE.fopen('integration', 'HRMtoAD1_'||to_char(sysdate,'YYYYMMDD')||'_'||to_char(sysdate,'HH24MISS'), 'w', 32767);
FOR x IN (SELECT * FROM (SELECT 
           decode(pid, NULL, RPAD(' ',7,' '), RPAD(user_id, 7, ' '))|| '' ||
           decode(name_last, NULL, RPAD(' ',50,' '), RPAD(name_last, 50, ' '))
           str FROM vr_ad_integration WHERE integrated = 'N') str WHERE rownum <= 1000 ORDER BY rownum)
LOOP
    BEGIN
        UTL_FILE.put_line(l_v_file, x.str);
    END;
END LOOP;
UTL_FILE.fflush(l_v_file);
UTL_FILE.fclose(l_v_file);
END VR_AD_INTEGRATION_EXPORT;

Now I can create file successfully in a remote location. However, what if there's no data in select query? no file should be created. If I am correct, I need to include exception code but I have no idea how to do it in this case. Any suggestion?

Cheers! :-)

Jaanna
  • 1,620
  • 9
  • 26
  • 46

2 Answers2

1

There are several ways to achieve this. One is to adopt a more procedural approach with a explicit cursor and only open the file once a record is fetched. A second is to modify your code to include a count inside the loop and delete the file if the count is zero.

Here is a third choice, which is a variant on the previous option. It tests the size of the file and if it is zero deleted it using the UTL_FILE.FREMOVE() command. Note the need to store the generated file name in a variable for reference later.

CREATE OR REPLACE PROCEDURE VR_AD_INTEGRATION_EXPORT AS
     l_v_file UTL_FILE.file_type;
     l_filename varchar2(128);  
     f_exists boolean;
     f_size pls_integer;
     f_blk_size pls_integer;
BEGIN  
    l_filename := 'HRMtoAD1_'||to_char(sysdate,'YYYYMMDD')||'_'||to_char(sysdate,'HH24MISS');
    l_v_file := UTL_FILE.fopen('integration',  l_filename , 'w', 32767); 
    FOR x IN (SELECT * FROM (SELECT
             decode(pid, NULL, RPAD(' ',7,' '), RPAD(user_id, 7, ' '))|| '' ||            decode(name_last, NULL, RPAD(' ',50,' '), RPAD(name_last, 50, ' '))
            str 
                 FROM vr_ad_integration 
                 WHERE integrated = 'N') str 
         WHERE rownum <= 1000 ORDER BY rownum) LOOP
     BEGIN
         UTL_FILE.put_line(l_v_file, x.str);
     END; 
    END LOOP; 
    utl_file.fgetattr('integration',  l_filename , f_exists, f_size, f_blk_size);
    if f_size > 0 then
        UTL_FILE.fflush(l_v_file); 
        UTL_FILE.fclose(l_v_file); 
    else
        UTL_FILE.fclose(l_v_file); 
        utl_file.fremove('integration',  l_filename);
    end if;
END VR_AD_INTEGRATION_EXPORT; 

There is some useful functionality in the UTL_FILE package beyond reading and writing lines. I suggest you read the documentation to find out more.

APC
  • 144,005
  • 19
  • 170
  • 281
  • After a few changes in your script, I was able to make it work – Jaanna Jul 30 '12 at 10:26
  • What changes did you need to make? It will be helpful for future seekers if my answer is as good as it can be. – APC Jul 30 '12 at 11:30
0

Use a flag to check if the file is created, and only create it once on the first run through your loop. Pseudocode:

bool fileCreatedFlag = false;
for x in (SELECT ...):
    if(!fileCreatedFlag):
        l_v_file = fopen(...);
        fileCreatedFlag = true;

    put_line(...);

if(fileCreatedFlag):
    fflush;
    fclose;
lc.
  • 113,939
  • 20
  • 158
  • 187