3

I need to spool the output of tables from db to CSV file. I checked and referred to How do I spool to a CSV formatted file using SQLPLUS?

But it's not working successfully. What I am getting is only the first 3 columns being separated by , and not the remaining. Others are getting separated by newline.

EDIT : Schema Details of Table being Spooled.

WWID               VARCHAR2 (5 Byte) 
TIMELOG_DATE       DATE 
TOTAL_HOURS        NUMBER (10,2) 
ACTIVITY           VARCHAR2 (100 Byte) 
SUBACTIVITY        VARCHAR2 (100 Byte) 
REF_PROJECT_ID     VARCHAR2 (30 Byte) 
REF_PROJECT_DESC   VARCHAR2 (250 Byte)
WORK_REQUEST_ID    VARCHAR2 (30 Byte)
EMP_COMMENTS       VARCHAR2 (100 Byte)
APPROVER_COMMENTS  VARCHAR2 (100 Byte)

Script:

echo "\n>>> ******Data Processing Started at `date '+%d-%m-%Y %T %Z'`******" >>${LOGFILE}

sqlplus $fims_user/$fims_pwd << EOF
set serveroutput on;
set colsep ,     ;-- separate columns with a comma
set pagesize 0   ;-- No header rows
set trimspool on ;-- remove trailing blanks
set headsep off  ;-- this may be useful...depends on your headings.

spool /home/fimsctl/datafiles/outbound/timelog/timelog_file_`date +%y%m%d`.csv

select * from FIMS_OWNER.TIMELOG_EXTRACT_OUTBOUND_T;

commit;
spool off
exit
EOF

echo "\n>>> ******Data Load Completed at `date '+%d-%m-%Y %T %Z'`******" >>${LOGFILE}

echo "End of the script">> ${LOGFILE}

And Output in CSV i am getting is:

SQL> select * from FIMS_OWNER.TIMELOG_EXTRACT_OUTBOUND_T;
iv315,29-DEC-14,          8
DUMMY

REF01
New Ref Project of type CPRM
66
NA


iv315,30-DEC-14,          8
DUMMY

REF01
New Ref Project of type CPRM
66
NA


iv315,31-DEC-14,          8
DUMMY

REF01
New Ref Project of type CPRM
66
NA

That is values are then separated by newline(when seen in wordpad)

Thanks

Community
  • 1
  • 1
Sachin
  • 963
  • 11
  • 31
  • 2
    You may just need to set the linesize much higher, and/or set wrap off; but what is the table structure - what size are the columns that are being wrapped? And do you really want the whitespace padding the string values? – Alex Poole Jan 09 '15 at 12:24
  • Ok, i am editing the description with table structure. For here, the part where `,` delimiter is changed to newline is a column declared as `NUMBER(10,2)` (which is showing value `8` in output as show in description) – Sachin Jan 09 '15 at 12:27
  • Schema details edited – Sachin Jan 09 '15 at 12:32
  • `select *` is a bad idea in any production environment. – Lalit Kumar B Jan 09 '15 at 13:36
  • That's just for debugging champ. Thanks :-) – Sachin Jan 09 '15 at 13:43

1 Answers1

5

The defaut linesize is 80 characters, so by default columns will wrap onto new lines when that length will be exceeded. Your 100-byte columns will cause that behaviour. You can add SQL*Plus commands to change that:

-- any number at least as large as the longest possible output
set linesize 1024
set wrap off

select * is generally frowned up as the output can change unexpectedly if the table definition changes - i.e. a column is added - or if the table has columns in different orders in different environments. (Which arguably shouldn't happen with source control, and generally doesn't matter as long as you don't use *. If you list the columns you want explicitly, it isn't much extra work to concatenate them with manually-added separators, e.g:

select wwid
  ||','|| to_char(timelog_date, 'DD-MON-YY') -- or another format
  ||','|| total_hours
  ||','|| activity
  ||','|| subactivity
  ... -- etc
from FIMS_OWNER.TIMELOG_EXTRACT_OUTBOUND_T;

That will remove extra whitespace that is currently going to pad all the CSV rows to the same length, and reduce the output file size. The output is then a single column, so the colsep setting isn't relevant any more.

Sachin
  • 963
  • 11
  • 31
Alex Poole
  • 183,384
  • 11
  • 179
  • 318
  • It worked. Thanks. And about using `select *`, it was for debugging just. Thanks a lot :-) – Sachin Jan 09 '15 at 12:45
  • @Sachin - thanks; `RR` is a valid date model, but I guess `YY` is just as good for output, if you really want a two-digit year. – Alex Poole Jan 09 '15 at 12:50
  • Yes actually. I changed it coz, for 50-99 are stored as 1950-1999, and dates ending in 00-49 are stored as 2000-2049. And I am developing an enterprise application for much older company existing since 1919 and thus have a lot of data to be migrated. Just in that case ;-) Thanks – Sachin Jan 09 '15 at 12:57
  • may I disturb you for one more thing. Actually my column outputs are listing with so many spaces. e.g. `iv315,31-DEC-14,8,DUMMY,REF01,New Ref Project of type CPRM,66,NA` ..... The same number spaces are being adding as per remaining characters according to column definition... Any solution other than `select trim(col1),trim(col2),trim(col3) from tablename`... As so many times call for `trim()` function is decreasing the performance a bit. – Sachin Jan 09 '15 at 13:33
  • Good point @Alex for mentioning `select *`. Usually considered shortcut by developers, ultimately results into issues. – Lalit Kumar B Jan 09 '15 at 13:38
  • 1
    @Sachin - trim won't help if you're relying on colsep; that's why I prefer concatenation. – Alex Poole Jan 09 '15 at 13:53
  • Done! Thanks... Will go for concatenation. – Sachin Jan 09 '15 at 13:57