Oracle spool issues - oracle

currently i use below code to spool csv file but i have find some line length more than 4000 characters , so it will no propey display
set echo off
set feedback off
set heading on
set linesize 32000
set pagesize 0
set termout off
set trim off
set trimspool on
set array 100
set underline off
set wrap off
set flush off
set verify off
set embedded on
select cloumnA||','||ColumnB ||','||ColumnC ..... from my_tab_name ;
so i modify my code but the result is not my want.
set echo off
set feedback off
set heading on
set linesize 32000
set pagesize 0
set termout off
set trim off
set trimspool on
set array 100
set underline off
set wrap off
set flush off
set verify off
set embedded on
select cloumnA,ColumnB ,ColumnC ..... from my_tab_name ;
the result 1:
A_value,B_value,C_value..... (the result is correct ,but only can show 4000 characters)
the result 2:
A_value
B_value
C_value
....
Anyone can help,thanks a lot!

When you concatenate columns (cloumnA||','||ColumnB ||','||ColumnC), the result is a VARCHAR2, which can't be more than 4000 characters (in typical circumstances).
See this similar question for some different options.
You could use COLSEP:
set colsep ','
spool myfile.csv
select cloumnA,ColumnB,ColumnC ..... from my_tab_name;
Which will get you something like
A_value ,B_value ,C_value
A_value ,B_value ,C_value
A_value ,B_value ,C_value
Which most people don't like, but it doesn't have a 4000-character line limit.
If you're using SQL Developer, you can use the easy /*csv*/ hint
select /*csv*/ cloumnA,ColumnB,ColumnC ..... from my_tab_name;
And if it's possible for you to use the newer SQLcl instead of SQL*Plus, you can use set sqlformat:
set sqlformat csv
spool myfile.csv
select cloumnA,ColumnB,ColumnC ..... from my_tab_name;

Related

Oracle SQL Spool Result file add spaces in columns

I am spooling a big result in a file but the spool add a lot of space between columns :
one line is more than 6850 characters (mostly empty space), one column take 500 characters, for instance the first one :
23053607 ;
Here is the query :
spool result.txt;
set pagesize 0
set linesize 8000
SET TRIMSPOOL ON
set heading off
set space 0
set trimout off
set termout off
set verify off
set echo off
set feed off
set trimspool on
-- set echo off;
-- set termout off;
set colsep ';'
set feedback off;
set pages 0;
spool result.txt;
select
trim(rec.Code) AS Code,
trim(A.label) AS Number,
trim(B.text) AS Syst
FROM record rec
join tableA A on A.rec_id = rec.rec_id
join tableB B on B.kla_id = rec.kla_id;
spool off;
exit;
In the database there is no space.
How to avoid any spaces ?
Simplest thing to do is to just concatenate the values. Remove colsep and try out:
SELECT rec.Code ||';'||
A.label ||';'||
B.text
FROM record rec
JOIN tableA A ON A.rec_id = rec.rec_id
JOIN tableB B ON B.kla_id = rec.kla_id;

SQLPLUS - ORACLE 12 - Trim extra columns white space

I've a problem with a sqlplus spool (oracle 12c/18c).
I want trim extra white space in columns.
This is the expected result
01JHON BROWN 30RED
02MARIO ROSSI 25WHITE
this is my result
01 JHON BROWN 30 RED
02 MARIO ROSSI 25 WHITE
this is the sql code
SET ECHO OFF
SET VERIFY OFF
SET FEEDBACK OFF
SET SERVEROUTPUT ON
SET HEADING OFF
SET PAGESIZE 0
SET LINESIZE 2000
SET SQLBLANKLINES ON
SET FEEDBACK OFF
SET TIME OFF
SET TIMING OFF
SET COLSEP ''
SET TRIMSPOOL OFF
SET TERMOUT OFF
ALTER SESSION SET NLS_DATE_FORMAT='YYYYMMDD';
ALTER SESSION SET NLS_NUMERIC_CHARACTERS='.,';
spool pippo.txt
SELECT TRIM(NUM), RPAD(NAME,12), TRIM(AGE), RPAD(COLOR,7)
FROM PLUTO;
spool off
exit
THX
That's just how column formatting works with spool - each row's values are padded to the full width of the columns. See this similar question to get an idea of your options.
If you don't want any spaces between column values, you'll generally have to concatenate them into a single column, e.g.
SELECT TRIM(NUM) || RPAD(NAME,12) || TRIM(AGE) || RPAD(COLOR,7)
FROM PLUTO;

sqlplus to csv scientific number conversion

I have the following in Unix under my shell script:
SET linesize 2000
SET pagesize 50000
SET ECHO OFF
SET FEEDBACK OFF
SET VERIFY OFF
SET MARKUP HTML OFF
set numwidth 17
set colsep ","
select accountnum, cardnum, name, address, number from employee;
Once it generates the output in .csv, cardnum and accountnum becomes scientific like:
5.30706E+15
I want it to be:
501889176278289
I know how to change it in Excel but since I am sending these reports to a client. I want it to go to them in the correct format so they don't have to change anything.
I would suggest this:
SELECT TO_CHAR(accountnum,'9999999999999999999') accountnum
, TO_CHAR(cardnum,'9999999999999999999') cardnum
, name, address, number
FROM employee;
Except of TO_CHAR suggested in other answer you can try:
set numformat 9999999999999999999 that should solve your problem.
Another way is COLUMN accountnum FORMAT 9999999999999999999

How to set headers in SQLPLUS?

I have set following SQLPLUS commands:
SET ECHO OFF
SET FEEDBACK OFF
SET HEADING ON
SET LINESIZE 100
SET PAGESIZE 1000
SET SPACE 0
SET TERMOUT OFF
SET TRIMOUT OFF
SET TRIMSPOOL ON
SET VERIFY OFF
But i am getting the result as:
ERROR_CODE
----------
ERROR_DESC
----------------------------------------------------------------------------------------------------
ERROR_COUNT
-----------
EXCP098
EXCEPTION: Processing not allowed
2
EXCP014
EXCEPTION: UNKNOWN STATUS
11
i.e. all the column headings and column values are in a new line instead of all column header should be in the same row and then record 1 should be in the first row and then record 2 should be in the second row.
I want it should be displayed as:
ERROR_CODE ERROR_DESC ERROR_COUNT
-----------------------------------------------------------------------
EXCP098 EXCEPTION: Processing not allowed 2
EXCP014 EXCEPTION: UNKNOWN STATUS 11
If "ERROR_DESC" is too long to fit on a line (together with "ERROR_CODE" and "ERROR_COUNT"), you have a few options to try:
return just a substring,
TRIM the value, or
change the data type for "ERROR_DESC".
What's working and appropriate, depends on your overall context. After all, the display in SQLPlus is usually not the most important aspect.

Header formatting while spooling a csv file in sqlplus

I am required to spool a csv from a table in Oracle, using sqlplus. Following is the format required:
"HOST_SITE_TX_ID","SITE_ID","SITETX_TX_ID","SITETX_HELP_ID"
"664436565","16","2195301","0"
"664700792","52","1099970","0"
Following is the relevant piece of the shell script I wrote:
sqlplus -s $sql_user/$sql_password#$sid << eof >> /dev/null
set feedback off
set term off
set linesize 1500
set pagesize 11000
--set colsep ,
--set colsep '","'
set trimspool on
set underline off
set heading on
--set headsep $
set newpage none
spool "$folder$filename$ext"
select '"'||PCL_CARRIER_NAME||'","'||SITETX_EQUIP_ID||'","'||SITETX_SITE_STAT||'","'||SITETX_CREATE_DATE||'","'||ADVTX_VEH_WT||'"'
from cvo_admin.MISSING_HOST_SITE_TX_IDS;
spool off
(I have used some commented statements in, to signify the things that I tried but couldn't get to work)
The output I receive is:
'"'||PCL_CARRIER_NAME||'","'||SITETX_EQUIP_ID||'","'||SITETX_SITE_STAT||'","'||SITETX_CREATE_DATE||'","'||ADVTX_VEH_WT||'"'
"TRANSPORT INC","113","00000000","25-JAN-13 10.17.51 AM",""
"TRANSPORT INC","1905","00000000","25-JAN-13 05.06.44 PM","0"
Which shows that the header is messed up - it is literally printing the whole string that should have been interpreted as an sql statement, as is the case with the data displayed.
Options I am considering:
1) Using colsep
set colsep '","'
spool
select * from TABLE
spool off
This introduces other problems as the data having leading and trailing spaces, first and the last values in the files are not enclosed by quotes
HOST_SITE_TX_ID"," SITE_ID"
" 12345"," 16"
" 12345"," 21
I concluded that this method gives me more heartburn than the one I described earlier.
2) Getting the file and use a regex to modify the header.
3) Leaving the header altogether and manually adding a header string at the beginning of the file, using a script
Option 2 is more doable, but I was still interested in asking, if there might be a better way to format the header somehow, so it comes in a regular csv, (comma delimited, double quote bounded) format.
I am looking to do as less hard coding as possible - the table I am exporting has around 40 columns and I am currently running the script for around 4 million records - breaking them in a batch of around 10K each. I would really appreciate any suggestions, even totally different from my approach - I am a programmer in learning.
One easy way to have a csv with just one header is to do
set embedded on
set pagesize 0
set colsep '|'
set echo off
set feedback off
set linesize 1000
set trimspool on
set headsep off
the embedded is a hidden option but it is important to have JUST one header
This is how I created a header:
set heading off
/* header */
SELECT '"'||PCL_CARRIER_NAME||'","'||SITETX_EQUIP_ID||'","'||SITETX_SITE_STAT||'","'||SITETX_CREATE_DATE||'","'||ADVTX_VEH_WT||'"'
FROM
(
SELECT 'PCL_CARRIER_NAME' AS PCL_CARRIER_NAME
, 'SITETX_EQUIP_ID' AS SITETX_EQUIP_ID
, 'SITETX_SITE_STAT' AS SITETX_SITE_STAT
, 'SITETX_CREATE_DATE' AS SITETX_CREATE_DATE
, 'ADVTX_VEH_WT' AS ADVTX_VEH_WT
FROM DUAL
)
UNION ALL
SELECT '"'||PCL_CARRIER_NAME||'","'||SITETX_EQUIP_ID||'","'||SITETX_SITE_STAT||'","'||SITETX_CREATE_DATE||'","'||ADVTX_VEH_WT||'"'
FROM
(
/* first row */
SELECT to_char(123) AS PCL_CARRIER_NAME
, to_char(sysdate, 'yyyy-mm-dd') AS SITETX_EQUIP_ID
, 'value3' AS SITETX_SITE_STAT
, 'value4' AS SITETX_CREATE_DATE
, 'value5' AS ADVTX_VEH_WT
FROM DUAL
UNION ALL
/* second row */
SELECT to_char(456) AS PCL_CARRIER_NAME
, to_char(sysdate-1, 'yyyy-mm-dd') AS SITETX_EQUIP_ID
, 'value3' AS SITETX_SITE_STAT
, 'value4' AS SITETX_CREATE_DATE
, 'value5' AS ADVTX_VEH_WT
FROM DUAL
) MISSING_HOST_SITE_TX_IDS;
This is how you add a pipe delimited header to SQL statements. Once you spool it out that "something" wont be there
-- this creates the header
select 'header_column1|header_column2|header_column3' as something
From dual
Union all
-- this is where you run the actual sql statement with pipes in it
select
rev.value1 ||'|'||
rev.value2 ||'|'||
'related_Rel' as something
from
...
In Oracle 19 you can use set markup csv on to ensure that csv outputs are created.
You can also set the delimiter and optional quote or even spool html if you prefer
You can read more here
set markup csv on
spool "$folder$filename$ext"
select q'|wow, I can't beleive he said "hello, how are you?", can you beleive it!|' as text
from dual;
spool off
quit;

Resources