Skip to Main Content
  • Questions
  • Extra comma in the heading of my csv

Breadcrumb

Question and Answer

Connor McDonald

Thanks for the question, Joe.

Asked: October 03, 2016 - 11:59 pm UTC

Last updated: October 06, 2016 - 12:59 am UTC

Version: 11.2.0.4

Viewed 1000+ times

You Asked

Hello Tom,

I have a plsql block that writes the records from a table into mulitple csv's. It is based on a condition(code) and if the csv has got more than 500,000 records then it will spool to another csv.

The question is my first CSV has got the output column headers printed correctly whereas the subsequent CSV's has got a comma in front of the first column header. I have enclosed the excerpt of the plsql block

PROCEDURE DUMP_CSV
AS
L_FILE         UTL_FILE.FILE_TYPE   DEFAULT NULL;
    L_ROW_PER_FILE INTEGER              DEFAULT 500000;
    L_FILE_NAME    VARCHAR2(100)        DEFAULT 'CR4440_CONVERTED_{FILENO}.CSV';
    L_FILE_DIR     VARCHAR2(100)        DEFAULT 'EXPDP_DIR';
    L_FILE_NO      INTEGER              DEFAULT 0;
    L_CUST VARCHAR2(30) DEFAULT 'CUST000';
    L_FILENAME VARCHAR2(50);

      L_THECURSOR     INTEGER DEFAULT DBMS_SQL.OPEN_CURSOR;
     L_COLUMNVALUE   VARCHAR2(4000);
      L_STATUS        INTEGER;
      L_QUERY         VARCHAR2(1000)
                      DEFAULT 'SELECT VOLUME, FOLIO, SURNAME_COMPANY_NAME,FIRST_NAME,MIDDLE_NAME,UNIT_NBR,STREET_NBR ,STREET_NAME ,CITY , STATE, POST_CODE,DEALING_NBR,MORTGAGEE_NAME,REGISTRATION_DATE FROM BULK_RESULT_DTL';
      L_COLCNT        NUMBER := 0;
       L_SEPARATOR     VARCHAR2(1);
       L_DESCTBL       DBMS_SQL.DESC_TAB;
  BEGIN
    FOR I IN (SELECT CEIL(ROWNUM/500000) FILE_NO, CUSTOMER_CODE,VOLUME, FOLIO, SURNAME_COMPANY_NAME,FIRST_NAME,MIDDLE_NAME,UNIT_NBR,STREET_NBR ,STREET_NAME ,CITY , STATE, POST_CODE,DEALING_NBR,MORTGAGEE_NAME,REGISTRATION_DATE
FROM BULK_RESULT_DTL ORDER BY CUSTOMER_CODE)
    LOOP
         IF  L_CUST!=I.CUSTOMER_CODE OR L_FILE_NO != I.FILE_NO
         THEN
  
             IF UTL_FILE.IS_OPEN(L_FILE)
             THEN
                UTL_FILE.FCLOSE(L_FILE);
             END IF;
             

             L_FILE_NO := I.FILE_NO;
             L_CUST:=I.CUSTOMER_CODE;
              L_FILENAME :=TO_CHAR(L_FILE_NO, 'FM099999')||'_'||L_CUST;
             
  
            L_FILE    := UTL_FILE.FOPEN
                          (
                             L_FILE_DIR
  
                           , REPLACE(L_FILE_NAME, '{FILENO}', L_FILENAME)
                           , 'W'
                         );

  
       EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_DATE_FORMAT=''DD-MON-YYYY HH24:MI:SS''
';

       DBMS_SQL.PARSE(  L_THECURSOR,  L_QUERY, DBMS_SQL.NATIVE );
       DBMS_SQL.DESCRIBE_COLUMNS( L_THECURSOR, L_COLCNT, L_DESCTBL );

       FOR I IN 1 .. L_COLCNT LOOP
  
          UTL_FILE.PUT( L_FILE, L_SEPARATOR || '"' ||  L_DESCTBL(I).COL_NAME || '"'||L_SEPARATOR  );
      
           DBMS_SQL.DEFINE_COLUMN( L_THECURSOR, I, L_COLUMNVALUE, 4000 );
      L_SEPARATOR := ',';
       END LOOP;
    
       UTL_FILE.NEW_LINE( L_FILE );

        /*         IF ISEMPTY(L_FILE_DIR,V_FILE_NAME)THEN

 DESC_COLUMN(L_FILE_DIR,V_FILE_NAME);
                 END IF;*/
  
             END IF;
  
UTL_FILE.PUT_LINE(L_FILE, TRIM(I.VOLUME)|| ',' || TRIM(I.FOLIO)|| ',' || TRIM(I.SURNAME_COMPANY_NAME)|| ',' || TRIM(I.FIRST_NAME)|| ',' ||TRIM(I.MIDDLE_NAME)||','|| TRIM(I.UNIT_NBR)|| ',' || TRIM(I.STREET_NBR)||','|| TRIM(I.STREET_NAME)|| ',' ||TRIM(I.CITY)||','|| TRIM(I.STATE)|| ',' || TRIM(I.POST_CODE)|| ',' || TRIM(I.DEALING_NBR)|| ',' || TRIM(I.MORTGAGEE_NAME)|| ',' || TRIM(I.REGISTRATION_DATE));
        --UTL_FILE.PUT_LINE(L_FILE, I.FOLIO_REF || ',' || I.CUSTOMER_CODE);
  
      END LOOP;

      IF UTL_FILE.IS_OPEN(L_FILE)
     THEN
         UTL_FILE.FCLOSE(L_FILE);
      END IF;

     END DUMP_CSV;




OUTPUT of the first CSV:

"VOLUME","FOLIO","SURNAME_COMPANY_NAME"


OUTPUT of the subsequent CSV'S:

,"VOLUME","FOLIO","SURNAME_COMPANY_NAME"


and Connor said...

Notice that l_separator starts as null, then after the first column we set it:

       FOR I IN 1 .. L_COLCNT LOOP
          UTL_FILE.PUT( L_FILE, L_SEPARATOR || '"' ||  L_DESCTBL(I).COL_NAME || '"'||L_SEPARATOR  );
           DBMS_SQL.DEFINE_COLUMN( L_THECURSOR, I, L_COLUMNVALUE, 4000 );
           L_SEPARATOR := ',';    <<<<=========
       END LOOP;


So you need to reset it to null when you go to a new file.

Hope this helps.

Rating

  (2 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Joe Swamidass, October 04, 2016 - 4:15 am UTC

Thanks a lot Connor. It works!
Connor McDonald
October 04, 2016 - 11:24 am UTC

glad we could help

Joe Swamidass, October 05, 2016 - 11:44 pm UTC

Thanks for the help and the swift response connor, I have already replied to your answer don't know why it is not displayed yet(new user :-))

That procedure is to divide csv's each having 500000 records based on the customer code however I'm getting multiple csv's with the same customer code less than 500000 records.

for example: customer code - A has got 550000 records. According to the procedure it should have generated 2 csv's one with 500000 and other with 50000 but It has generated three csv's one with 256000,244000 and 50000. Please help me in fixing this.

Joe

Connor McDonald
October 06, 2016 - 12:59 am UTC

Well, the code:

IF  L_CUST!=I.CUSTOMER_CODE OR L_FILE_NO != I.FILE_NO


suggests a new file for new customer but ALSO a new file number.


More to Explore

Data Pump

All of the database utilities including Data Pump are explained in the Utilities guide.