sql*plus is truncating the columns names according to the values in that columns - oracle

I have two broad questions:
Q1. Are executing the lines of code in Oracle SQL Developer and executing the same code in sqlplus command prompt same things?
(reason I ask this that I heard that not all the sqlplus commands are executable in SQL Developer. If answer to above question is yes then please then few useful links will help).
Q2. I am spooling the results of a sql query to a .csv file, but the thing is that columns names are truncated according the maximum length of the values in that column.
My code is:
set colsep ","
spool C:\Oracle\sample.csv
select * from acct_clas_rule;
spool off;
Output of above code is (middle column is having null values)
ABCD_,ABCD_,ABC
-----,-----,---
AB , ,WSD
ABCD , ,WSD
ABCD , ,WSD
SG , ,WSD
KD , ,WSD
WD , ,LKJ
KLHGF, ,LKO
WSDFG, ,LOK
WSDF , ,LKO
WS , ,GH
In above output, columns names have been truncated. I want full names of the columns to be displayed. Can anyone help?
I have seen the question in this link, but I didn't understand how to apply the answers provided there as there was no particular example cited. I am new to these things so I couldn't understand.
Original names of my columns (from left to right in above table) are :
ABCD_DFGT_SDF, ABCD_EDF_GH, ABCD_DFRE
PS -
1. I am using Oracle SQL developer to run sqlplus commands. I think because of which few of my commands are not working (like set underline, set linesize etc.).Please let me know if this is the case. I actually want remove those underlines beneath the columns names.
2. Also let me know that whether you answer is applicable to Oracle SQL Developer or sqlplus.
Thank You

There are a couple of things you can do, in addition to #JChomel's approach - that will work in either SQL Develoepr or SQL*Plus, while these suggestions are specific to SQL Developer.
Let's start with a dummy query based on a CTE to get something like your situation:
set colsep ","
with acct_clas_rule (abdc_1, abcd_2, abcd_3) as (
select cast('AB' as varchar2(5)), cast(null as varchar2(5)), cast('WSD' as varchar2(4)) from dual
union all select 'ABCD', null, 'WSD' from dual
-- ...
union all select 'WS', null, 'GH' from dual
)
select * from acct_clas_rule;
When run as a script in SQL Developer (from the document+arrow icon, or F5) the output is:
ABDC_,ABCD_,ABCD
-----,-----,----
AB , ,WSD
ABCD , ,WSD
WS , ,GH
If you change the query to include the SQL Developer-specific formatting hint /*csv*/ then you get the output you want:
select /*csv*/ * from acct_clas_rule;
"ABDC_1","ABCD_2","ABCD_3"
"AB","","WSD"
"ABCD","","WSD"
"WS","","GH"
except that the strings are all enclosed in double-quotes, which might not be what you really want. (It depends what you're doing with the spooled file and whether any of your string values contain commas, which would confuse Excel for instance).
With more recent versions of SQL Developer you can get exactly the same result without modifying the query using the sqlformat option:
set sqlformat csv
select * from acct_clas_rule;
but again you get the double-quotes. You could change the double-quotes to different enclosure characters, but that probably doesn't help.
A different approach is to use the built-in export tools instead of spool. If you run the query as a statement (green 'play button' icon, or control-enter) then rather than appearing in the Script Output panel, a new Query Result panel will open next to that, showing the results as a grid.
If you right-click on the results you'll get a contextual menu, and choosing Export... from that will give you a wizard to export the results in a format of your choice, including CSV:
You can leave the left and right enclosures as double-quotes to get the same results as the options above, except that null values use the word 'null' instead of an empty string:
"ABDC_1","ABCD_2","ABCD_3"
"AB",null,"WSD"
"ABCD",null,"WSD"
"WS",null,"GH
or you can change them, or remove them by choosing 'none', which gives you:
ABDC_1,ABCD_2,ABCD_3
AB,null,WSD
ABCD,null,WSD
WS,null,G
#thatjeffsmith has commented on how to change the null-replacement text for the /*csv*/ approach. For export it looks like having the word 'null' might have been a bug in 17.2.0; in 17.3.1 that does not appear, and instead you see:
ABDC_1,ABCD_2,ABCD_3
AB,,WSD
ABCD,,WSD
WS,,GH
or enclosed empty strings ("") if you leave the enclosures set.

Q1: TI'm not an expert of SQL Developer. There might be a mode like "command line" or something where you could get similar result, but unsure.
Q2: You have to set the right option to sqlplus: here is a trick I know of (it will also remove the --- --- --- that will cause other issue):
SET HEADING OFF`, to avoid column name to be printed
Union all the column names at the beginning of your script:
set colsep ","
spool C:\Oracle\sample.csv
select 'ABCD_DFGT_SDF', 'ABCD_EDF_GH', 'ABCD_DFRE' from dual
UNION ALL
select * from acct_clas_rule;
spool off;

use the sql plus set command -----> set underline off

Related

Oracle SQL Developer How to export via a command line the result of a SQL script?

This is my first question on StackOverflow (but not the first question I asked to myself on Oracle SQL Developer :p)
My needs :
I first tried to do all my works exclusively on Oracle SQL Dev but it asks to much ressources to be done.
In consequences, I decided to only export all the data I need and then import all in R and do my work on it.
Finally, it takes about 2 minutes to do the job :D
My problem is :
I run about 10 different SQL script which are really simple. Please find below two of them :
select japolip_wnupo wnupo,japolip_socpo socpo,japolip_jasccdp_winag winag,japolip_wnpro wnpro,jaagenp_ainag,jaagenp_nomag
from sunapicf.japolip japolip
left join sunapicf.jaagenp jaagenp on jaagenp_winag = japolip_jasccdp_winag
;
select distinct socpr socpo,jaagenp.jaagenp_winag winag,JACRCFP.JACRCFP_wnpro wnpro,jaagenp_ainag,jaagenp_nomag
from sunapicp.JACRCFP JACRCFP
left join
(
select japrodp_wnpro,socpr
from sunapicp.japrodp japrodp
cross join xmltable('//JAPRODP' passing xmltype(japrodp.ficxml) columns SOCPR)
) japrodp on japrodp.japrodp_wnpro = JACRCFP.JACRCFP_wnpro
left join sunapicf.jaagenp jaagenp on jaagenp.jaagenp_winag = jacrcfp.jacrcfp_winit
;
Then I have to launch the Export function for every results, change the formatting and the type of file to be delivered to .dsv (just to have the right comma :D), and also change the folder directory and the name.
It is too much repetitive and can generate some mistakes.
That's why I would like to add a command line where I would specify the folder directory, the name, the formatting and what so ever.
Do you have any information about that ?
Thank you very much.
I did not try anything because I don't have any idea to try.
I tried to connect R to Oracle but I guess I have to pay for it (and the company does not want to :D).
Using SQLcl is definitely the way to go. Build a script (or set of scripts) that run all of the queries that you want to export data into CSV files. Below is an example script that will connect to the database, set formatting, generate the files then disconnect.
The script would get launched with a command like this:
sql /nolog #start_export.sql
start_export.sql example contents:
--Connect to the database
connect <username>/<password>#<TNSalias>
--Set format to CSV for results from SELECT statements
set sqlformat csv;
--Turn off the number of rows that get returned by the select
set feedback off;
--Create 1st report
spool report1.csv
select japolip_wnupo wnupo,japolip_socpo socpo,japolip_jasccdp_winag winag,japolip_wnpro wnpro,jaagenp_ainag,jaagenp_nomag
from sunapicf.japolip japolip
left join sunapicf.jaagenp jaagenp on jaagenp_winag = japolip_jasccdp_winag;
--Create 2nd report
spool report2.csv
select distinct socpr socpo,jaagenp.jaagenp_winag winag,JACRCFP.JACRCFP_wnpro wnpro,jaagenp_ainag,jaagenp_nomag
from sunapicp.JACRCFP JACRCFP
left join
(
select japrodp_wnpro,socpr
from sunapicp.japrodp japrodp
cross join xmltable('//JAPRODP' passing xmltype(japrodp.ficxml) columns SOCPR)
) japrodp on japrodp.japrodp_wnpro = JACRCFP.JACRCFP_wnpro
left join sunapicf.jaagenp jaagenp on jaagenp.jaagenp_winag = jacrcfp.jacrcfp_winit;
--Disconnect
exit

Avoid double quotes around column while spooling to csv from oracle

I need to export a select query output to text file using spool. The output by default adds double quotes around the column. How to Prevent it?
The query returns only one column.
Ideally i need to remove headers as well as the double quotes from the output. below is the script file i use in oracle Developer. but heading is also not removed.
set echo off
SET HEADING OFF
SET PAGESIZE 0
SET COLSEP ''
spool 'D:\public\cvs_txPCG.txt'
select /*csv*/
pcg from temptx;
spool off;
output
"PCG"
"76259737020150320000504281565213310052440093515652109.2909.290101"
"19519905620160502000504283153419040044861008644759203.3903.390101"
"49424051620160220000504284594314590009220713032964404.3804.380202"
"88761197020151025000504284594315180036700812132964401.9901.990101"
You can't get rid of the double-quotes with the /*csv*/ directive. The slightly more convenient way of doing this now is with the sqlformat command, but even with sqlformat delimited you have to have the string enclosed.
Using CSV format for a single column seems rather pointless anyway though, unless you have delimiters in your string you want to escape. If you are really exporting that one column and don't have delimiters then just leave out the /*csv*/ directive. If you have multiple columns or strings that may contain delimiters then the enclosures are useful to stop those delimiters being misinterpreted when opening in Excel or some other external tool.
If you really want CSV format without enclosures you can either build up the output manually by concatenating the column(s) with comma literals, which still allows you to spool to a file:
select pcg ||','|| some_other_col ||','|| etc from ...
Or you can run the query using Run Statement (Ctrl-Enter) and then export the results from the data grid, from the context menu that appears when you right-click on the output. When you export and choose CSV or delimited format you can choose whether to include the header and which delimiter and enclosures to use - and you're allowed to choose 'none'. If you don't want to set that on each export you can set it as a default, from Tools->Preferences:
You can't do it with the /*csv*/ directive or sqlformat csv though.
I know it is too old but got the answer with my search today, simply use
set markup csv on quote off
select 1 id, 'Venkat' name from dual;
Output will be
ID,NAME
1,Venkat
Didn't even think of any other SET commands
If the double quotes are part of the data you can use the trim() function to remove them.
select /*csv*/
trim(both '"' from pcg) as pcg from temptx;
Oracle documentation for the trim function:
https://docs.oracle.com/cd/B19306_01/server.102/b14200/functions199.htm

Search for a column in a DB

I received help from a very great person (#TonyAndrews) yesterday concerning this query...
ACCEPT column_name CHAR PROMPT 'Please insert column name'
SELECT DISTINCT owner, table_name
FROM all_tab_columns
WHERE column_name IN ('&column_name');
ACCEPT response CHAR PROMPT 'Would you like to search for another column? '
SELECT CASE LOWER('&response.') WHEN 'yes' THEN 'table_search' ELSE 'stop' END AS script
FROM DUAL;
SET TERM ON
#&script.
I have two scripts created (table_search & stop). It just is not running right. He has given me the right info, I'm just to dumb to figure it out.
Im using Oracle Developer and running the script using the run script button. When I run it, it immediately comes up "Would you like to search for another column". In the script output window it shows "old:SELECT DISTINCT owner, table name" I type in "yes'" and in the script output window it appears to show the results of the initial search request. It does show the requestor window asking to input another column
You have not qualified "not running right" with any information we can use to accurately diagnose your problem. If you do that then someone could help out.
In the meantime, looking at your script, it seems that if someone enters the column name in lowercase then your search will not find it as the Oracle data dictionary holds values in uppercase by default. Therefore, you should wrap your ('&column_name') in an UPPER.
Also, you should probably trim any whitespace from the input just in case someone copies and pastes some by mistake.
Finally, you are using IN rather than =, is this deliberate? If you are searching for a column and offering the option to search again afterwards, I'd assume you would only search for one column at a time like this:
ACCEPT column_name CHAR PROMPT 'Please insert column name'
SELECT DISTINCT owner, table_name
FROM all_tab_columns
WHERE column_name = TRIM(UPPER('&column_name'));
Hope it helps!
EDIT: I've been and looked at #Tony_Andrews answer and it seems pretty comprehensive to me. Have you created the two separate files "myscript.sql" and "stop.sql"?
Have you also stored those files in the default directory your SQL*Plus or SQL Developer installation is looking in when it is trying to run them?
Tony's answer is good, please describe in detail what issue you are having with it.
EDIT2: OK, following on from the information you have supplied, it seems that your initial variable is already set try adding UNDEFINE column_name response to your myscript.sql file before the ACCEPT column_name CHAR PROMPT ... line. I would also add some SET commands to reduce the output to the screen to just what you want.
Your myscript.sql file should look like this (Note I have also added a double "#" when running the stop.sql as I am assuming it is in the same directory as the myscript.sql file):
SET ECHO OFF
SET VERIFY OFF
UNDEFINE column_name response
ACCEPT column_name CHAR PROMPT 'Please insert column name'
SELECT DISTINCT owner, table_name
FROM all_tab_columns
WHERE column_name = TRIM(UPPER('&column_name'));
ACCEPT response CHAR PROMPT 'Would you like to search for another column? '
SELECT CASE LOWER('&response.') WHEN 'yes' THEN 'table_search' ELSE 'stop' END AS script
FROM DUAL;
SET TERM ON
##&script.
SET ECHO ON
SET VERIFY ON
This works for me.
Hope it helps

Another client to replace sqlplus for access to oracle?

I have some issues with how sqlplus output is formatted for the terminal and I am just thinking of writing a script around sqlplus and fixing these.
On the other hand, wow that seems really lame. Because Oracle has several tons of tools written. Yet it seems difficult to get what I want. Does anyone have another suggestion?
First, I want smarter column widths. If I create a table with a column whose max size is 200 characters but then I put "abc", "xyz" and "123" in it, do I need a 200-space wide column on the terminal to display the contents? I do not think so. I think I need 3 characters plus a couple for padding. Yet Oracle insists on giving me a 200-character wide column. Unless there is somewhere to fix this.
Second, I want easy access to a sideways display of the columns, like using \G at the end of the command in MySQL. I know there is a way to do this in Oracle but it seemed complicated. Why could there not just be a simple switch? Like a \G at the end of the command? There can be if I wrap the output to sqlplus and do this myself.
So, the question seems to be this. Should I write a simple script around sqlplus to give me what I want, or is there a way to get Oracle to give me this behavior In sqlplus? And if there is, how much extra information will I have to stuff into my head to make this work? Because it does not seem as though it should be very complicated. But Oracle is certainly not making it easy.
First of all I suggest you look over the SQL*plus reference - you might find some useful tips there like adjusting a column width
COL column_name for a20
you can set up your own settings in the GLOGIN file. over time, like any other CMD, you'll get your preferences just right.
To describe a table you can use DESC. if you want more data write your own script and reuse it with #.
If all this doesn't work for you, you can always switch to a GUI like Toad or SQL developer.
EDIT:
I'm adding one of my own scripts to show you some tricks on how to make SQL*Plus more friendly on the command line. This one is for getting segment sizes.
/* This is the trick - clears &1 and &2 if received an empty string */
set ver off feed off
col 1 new_v 1
col 2 new_v 2
select 1,2 from dual where 1=0;
variable p_owner varchar2(30)
variable p_segment varchar2(30)
/* set bind variables */
begin
:p_owner := '&1';
:p_segment := '&2';
end;
/
set feed 1
break on segment_type skip 1
column MB for a25
select
segment_type,
decode(gi_segment_name + gi_segment_type + gi_tablespace_name , 3 ,'...Grand Total', segment_name) SEGMENT_NAME,
to_char(round(MB,3),'99,999,999.99') MB ,
nvl(tablespace_name,'-*-') tablespace_name
from (
select tablespace_name , segment_type , segment_name , sum(bytes/1024/1024) MB ,
grouping_id(segment_name) gi_segment_name ,
grouping_id(segment_type) gi_segment_type ,
grouping_id(segment_type) gi_tablespace_name
from dba_segments
where ((:p_owner is null and owner = user) or owner like upper(:p_owner))
and (:p_segment is null or segment_name like upper('%'||:p_segment||'%'))
group by rollup(tablespace_name, segment_type , segment_name)
)
where not (gi_segment_name = 1 and gi_segment_type = 0 and gi_tablespace_name = 0)
order by decode(segment_type,'TABLE','0','TABLE PARTITION','1','INDEX','2','INDEX PARTITION','3',segment_type) ,
(case when segment_name like '.%' then 'z' else 'a' end) ,
gi_segment_name ,
MB desc ,
segment_name;
clear break
/* clear definition for &1 and &2 after being used.
allows the variable to be null the next run. */
undefine 1
undefine 2
I'll walk you through some of the things iv'e done here
The script accepts two parameters. The first 4 lines clears the
parameter if none received. if you don't do this SQL*Plus will prompt
you for them. And we dont want that.
Setting the binds was more of a big deal in past version. It's
intended to save Hard / Soft parse. latest version solve this
problem. It's still a best practice though.
The break is a nice touch. You'll see it.
The grouping Id show me the sub totals on several levels.
I've added two parameter, owner and segment name. both can contain
wild card. both can be null. If non provided the query will fetch the
current user segments.
Order by decode enabled me to set a custom sort order for different
segment types. You can change it as you wish.
I'm executing the script like this
my segments :
#seg
Scott's segments
#seg scott
Scott's Emp related segments
#seg scott emp
I have similar scripts for session, longops, wait events, tables, constraints, locks, kill session etc .... during my daily routine i rarely write SQL for querying this stuff any more.

How to export query result to csv in Oracle SQL Developer?

I'm using Oracle SQL Developer 3.0. Trying to figure out how to export a query result to a text file (preferably CSV). Right clicking on the query results window doesn't give me any export options.
Version I am using
Update 5th May 2012
Jeff Smith has blogged showing, what I believe is the superior method to get CSV output from SQL Developer. Jeff's method is shown as Method 1 below:
Method 1
Add the comment /*csv*/ to your SQL query and run the query as a script (using F5 or the 2nd execution button on the worksheet toolbar)
select /*csv*/ *
from emp;
That's it.
You can also use spool to automatically save it as a CSV file:
spool "/path/to/file.csv";
select /*csv*/ *
from emp;
spool off;
Just be sure to "Run as Script" or press F5.
Method 2
Run a query
Right click and select unload.
Update. In Sql Developer Version 3.0.04 unload has been changed to export
Thanks to Janis Peisenieks for pointing this out
Revised screen shot for SQL Developer Version 3.0.04
From the format drop down select CSV
And follow the rest of the on screen instructions.
Not exactly "exporting," but you can select the rows (or Ctrl-A to select all of them) in the grid you'd like to export, and then copy with Ctrl-C.
The default is tab-delimited. You can paste that into Excel or some other editor and manipulate the delimiters all you like.
Also, if you use Ctrl-Shift-C instead of Ctrl-C, you'll also copy the column headers.
FYI, you can substitute the /*csv*/
for other formats as well including /*xml*/ and /*html*/.
select /*xml*/ * from emp would return an xml document with the query results for example.
I came across this article while looking for an easy way to return xml from a query.
FYI to anyone who runs into problems, there is a bug in CSV timestamp export that I just spent a few hours working around. Some fields I needed to export were of type timestamp. It appears the CSV export option even in the current version (3.0.04 as of this posting) fails to put the grouping symbols around timestamps. Very frustrating since spaces in the timestamps broke my import. The best workaround I found was to write my query with a TO_CHAR() on all my timestamps, which yields the correct output, albeit with a little more work. I hope this saves someone some time or gets Oracle on the ball with their next release.
To take an export to your local system from sql developer.
Path : C:\Source_Table_Extract\des_loan_due_dtls_src_boaf.csv
SPOOL "Path where you want to save the file"
SELECT /*csv*/ * FROM TABLE_NAME;
CSV Export does not escape your data. Watch out for strings which end in \ because the resulting \" will look like an escaped " and not a \. Then you have the wrong number of " and your entire row is broken.

Resources