Export SQLPluse Query from Oracle to CSV with UTF-8 encoding - oracle

I am using the below SQLPluse Script to export data out of Oracle into CSV files. The issue is I need the files to be in UTF-8 and its currently ANSI. How do i go about getting the files to be UTF-8?
SET colsep ';'
SET TERMOUT OFF
SET NEWPAGE 0
SET SPACE 0
SET LINESIZE 800
SET PAGESIZE 0
SET ECHO OFF
SET FEEDBACK OFF
SET HEADING OFF
SET NUMW 50
column timecol new_value timestamp
column spool_extension new_value suffix
SELECT '.csv' spool_extension
FROM dual;
/
SPOOL C:\job_files\production\Data_Upload\TEST_1&&suffix
##"C:\job_files\production\Data_Upload\TEST_1";
/
Exit;

Not entirely clear from your question what you mean, but I assume the issue is the data your query returns contains UTF8 data but your output does not show the UTF8 characters correctly.
The NLS_LANG environment variable controls how Oracle tools/programs including SQL*Plus handle such data.
You would normally set the variable to something that matches the database, e.g
export NLS_LANG=AMERICAN_AMERICA.AL32UTF8
Then run SQL*Plus.
You can query NLS_DATABASE_PARAMETERS to see what language settings are in the database and experiment with the NLS_LANG variable as above.
NLS_LANG value format is LANGUAGE_COUNTRY.CHARSET.

Related

Special characters (german umlauts) are displayed as ASCII

In our database german umlauts are displayed as ASCII.
Here some examples
Ü is displayed as "š"
ä is displayed as "„"
Ä is displayed as "Ž"
ö is displayed as "”"
Ö is displayed as "™"
Here some Oracle enviroment variables:
SELECT distinct client_charset FROM v$session_connect_info
WHERE sid = sys_context('USERENV','SID');
retuns Unknown
select * from v$NLS_PARAMETERS;
NLS_LANGUAGE GERMAN
NLS_CHARACTERSET WE8MSWIN1252
I have also noticed, that there is no NLS_LANG setted up.
Can someone give me any clue how to check if this is a problem of env variable or character-encoding itself? Or how to fix it so that the umlauts would be displayed correctly?
Thanks in advance!
The first sentence is already wrong, it must be "my client application displays german umlauts as ..." Characters like Ž are not ASCII either. The Oracle environment variables have nothing to do how your client displays any characters.
There could be two reasons:
Characters like š „ Ž ” ™ are really stored in your database because they are inserted wrong, and you just think it should be Ü ä Ä ö Ö
Your client uses the wrong character set.
NLS_LANG is used to tell the database "my client uses character set XYZ" - no more, no less! Well, some clients inherit the NLS_LANG value for own character set setting but that is not always the case.
Actual answer:
You have wrong data in your database! When you inserted the data then your client was using CP437 (Oracle Character Set US8PC437) but you did not tell this the database.
Most likely data was inserted by sqlplus which inherits the codepage from cmd.exe which is by default 437 on English Windows machines. NLS_LANG character set was set to WE8MSWIN1252. When character set of client and database is the same then data is transferred byte-by-byte without any conversion - there is the mismatch!
Solutions:
Before you run your sqlplus script Set NLS_LANG accordingly, e.g.
SET NLS_LANG=.US8PC437
sqlplus ...
Language and Territory are optional and thus can be skipped.
Your database uses character set WE8MSWIN1252, then it would be beneficial to use it also by your client. By this you can insert and display any character which is supported by the database (no less but also no more)
chcp 1252
SET NLS_LANG=.WE8MSWIN1252
sqlplus ...
Correction of wrong data:
In order to correct the wrong data try this:
UPDATE table_name SET column_name = CONVERT(column_name, 'WE8MSWIN1252', 'US8PC437');
Note, this should be a one-time correction only. Do not put such update as part of your application code!
Update
For correction of PL/SQL code, try this one (not tested):
Create a SQL script like this:
SET HEADING OFF
SET FEEDBACK OFF
SET NEWPAGE NONE
SET VERIFY OFF
SET TRIMSPOOL ON
SET DEFINE OFF
SET ECHO OFF
SET TERMOUT OFF
SET PAGESIZE 0
SET LINESIZE 32767
SET LONG 2000000000
SET LONGCHUNKSIZE 32767
spool PACKAGE_NAME.sql;
SELECT DBMS_METADATA.GET_DDL('PACKAGE', 'PACKAGE_NAME', USER) FROM DUAL t;
spool OFF;
EXIT
And the run it like this
c:\> chcp 437
c:\> SET NLS_LANG=.WE8MSWIN1252
c:\> sqlplus -s ... #<above script>
c:\> SET NLS_LANG=.US8PC437
c:\> sqlplus ... #PACKAGE_NAME.sql

Oracle command line to export table data to csv using spool having issues when data has double quotes(") in it

I am having ORACLE 11 version installed on my linux machine. I am trying to export data using below. It is working fine for all the tables except for tables having double quotes(") as data in any of column. Below is my code
set echo off
set feedback off
set linesize 30000
set recsep off
set trimspool off
set verify off
set pagesize off
spool "/home/rsau12/file.csv";
SELECT '"'||COLUMN_1||'"'||','
'"'||COLUMN_2||'"'||','
'"'||COLUMN_3||'"'||','
...
'"'||COLUMN_N||'"'
FROM TABLE;
spool off;
Please let me know how to handle if data has (") in it
You need to replace double quotes(") with two double quotes(""):
select chr(34)||replace(COLUMN_1,chr(34),chr(34)||chr(34))||chr(34)
||','||chr(34)||replace(COLUMN_2,chr(34),chr(34)||chr(34))||chr(34)
||','||chr(34)||replace(COLUMN_3,chr(34),chr(34)||chr(34))||chr(34) as data
from table_1
Example:
if some columns are numeric you don't need doble quotes (").
"Los Angeles","California, USA","""Hello World"" say John"

How to spool file1 or file2 from a single SQL file based on the input?

I have a SQL file like the following:
SET ECHO OFF
set feed off
set verify off
set head off
set pagesize 0
set space 0
set trimspool on
set line 250
spool subir.rpt
select 'Subir' from dual;
spool off
SET ECHO OFF
set feed off
set verify off
set head off
set pagesize 0
set space 0
set trimspool on
set line 250
spool vishal.rpt
select 'vishal' from dual;
spool off
Let's call this file spool.sql. I need to enable creation of spool file based on the input spool.sql file receives. For example, if it receives "subir.rpt" The first portion of the SQL file should run and subir.rpt should be produced; if it is vishal.rpt, the second portion should run and vishal.rpt should get generated.
How can this be achieved?
Edit: This SQL file is getting called from a shell script. The shellscript is like the following:
sqlplus -s dbread$HOST_CONNECT_STR/dbread<<endplus
#spool.sql
endplus
What is launching this spool.sql? A shell script? Database function?
If it's a shell script, I would either use a parameter to this script or split it into two separate .sql files and call the appropriate one.
You could also save the file value into a temporary table prior to calling this script and select it before spooling the file.
There are a lot of options but it all depends on how you call this script and how extensible you want it to be.
The simplest way would be to use the supplied parameter dynamically as the spoolfile:
set echo off
set feed off
set verify off
set head off
set pagesize 0
set space 0
set trimspool on
set line 250
spool &1
spool
select 'Subir' from dual where '&1' = 'Subir.rpt';
select 'vishal' from dual where '&1' = 'vishal.rpt';
spool off
(The spool command on its own is just to print the current spoolfile name for demo purposes.)

remove blank lines from csv using shell script for oracle

Hi am using following shell script to create csv from oracle database
export ORACLE_HOME=/usr/lib/oracle/xe/app/oracle/product/10.2.0/server
export PATH=$PATH:$ORACLE_HOME/bin
sqlplus -s user1/user1<<!
Spool on
set heading off
SET FEEDBACK OFF
set wrap off
set colsep ,
SET LINESIZE 200
set trims on
Spool /home/ist/username.csv
select 'username','userid' from dual;
select username,userid from users;
Spool off
EXIT
!
I am getting following output
as you can see there is blank line at first and third row
but am expecting file without blank lines.
Any help will be appreciated.
Use the
SET PAGESIZE 0
command to avoid the blank lines. this also suppresses column headings, so you can remove
SET HEADING OFF
The command
SPOOL on
does not make sense because it starts spooling in a file named on.lst. So remove this command, too.
If you want to display the heading with the column name
you can try the following settings
set HEADING ON
SET FEEDBACK OFF
set WRAP OFF
set COLSEP ,
SET LINESIZE 32767
set NEWPAGE none
set UNDERLINE OFF
set TRIMSPOOL ON
set TRIMOUT ON
set PAGESIZE 50000
´heading on´ is the default so you must not set it. It enables the display of the column names when a select starts. underline off suppresses the '---' line between column names and data of a select. pages 50000 sets the pagesize to its maximum value (Oracle 11.2). linesize 32767 sets the linesize to its maximum value (Oracle 11.2). newpage none is necessary to suppress this empty line at the beginning of a page that was the primary concern of your posting.
All this can be found in the SQL*Plus Command Reference
The termout off parameter suppresses only output created by a scripts that is executed with the # or ## command. It dos not suppress out by a command entered in the SQL*plus console. If you use
sqlplus user/passw#connect <<!
...
!
you use the here-document syntax of the shell language which simulates the interactive input. So put your sql commands in a script, e.g. script.sql, and execute
sqlplus user/passw#connect #script.sql
then termout off will suppress terminal output.
Instead of
colsep ,
select username,userid
...
which returns something like
user1 , 14
nextuser , 236
myuser , 11
...
you can use leave the COLSEP unchanged and execute
select username||','||userid
...
to get the following output
user1,14
nextuser,236
myuser,11
...
Maybe this is useful
https://dba.stackexchange.com/a/64620/2047
set trimspool on
this will work for you
put this on your script
sed -i '/^\s*$/d'/home/ist/username.csv
Remove lines in /home/ist/username.csv without a , using
grep "," /home/ist/username.csv > /home/ist/username2.csv
# or
sed -i '/^[^,]*$/ d' /home/ist/username.csv
SQLPLUS 12.2 has an feature to output CSV, but you need to configure some settings to remove blank lines on it. Here is my approach
SET HEADING OFF;
SET PAGES 0;
SET SQLBLANKLINES ON;
set echo off;
set autotrace off;
set feedback off;
SET TRIM ON;
SET MARKUP CSV ON DELIMITER | QUOTE OFF;

Export to a csv file

I try many times to export my result into .csv file but I'm always fail. I read lot of articles related in my problem.
Look at my query:
spool sample.csv
SELECT /*html*/(CODE_SALESROOM) POS_ID, (NAME_SALESROOM) POS_NAME
FROM OWNER_DWH.DC_SALESROOM
WHERE CODE_SALESROOM NOT IN ('XAP', 'XNA', '10001');
spool off;
The output of this, when I export in a csv file is only the query not the real result.
What's wrong in my command to export the result?
Please help me. Thanks
Make sure that your query returns values. You can set various parameters of Sql plus before spooling to get desired out put. Below is the list that I use before spooling. And since your are generating csv, it should be comma separated
set echo off
set termout off
set define off
set heading off
set pagesize 10000
set linesize 500
set feedback off
set verify off
set trimspool on
spool sample.csv
SELECT 'POS_ID,POS_NAME' from dual; -- header list
SELECT CODE_SALESROOM || ',' || NAME_SALESROOM
FROM OWNER_DWH.DC_SALESROOM
WHERE CODE_SALESROOM NOT IN ('XAP', 'XNA', '10001');
spool off;
You can modify the set parameters based on your requirement.

Resources