I have a shell with one command line opening sql plus and calling a sql file
$ORACLE_HOME/bin/sqlplus id/psw #SQL_DIRECTORY/myfile.sql
in this file I write this :
spool myfile.csv
select 'column 01', ';', 'column 02' from dual;
select myColumn1, ';', mycolum2 from mytable
spool off
It works good BUT on the first line of the the first column of each select there is a special character.
Why is that? how can I get rid of this
Thanks
From the description it sounds like you have a login.sql or glogin.sql user profile that is issuing set newpage 0:
Sets the number of blank lines to be printed from the top of each page to the top title. A value of zero places a formfeed at the beginning of each page (including the first page) and clears the screen on most terminals. If you set NEWPAGE to NONE, SQL*Plus does not print a blank line or formfeed between the report pages.
In Excel that does show up as an unprintable character with a question mark in a small square; in Notepad++ it seems to show as FF in reverse colouring; and in some editors (e.g. Vim) it shows as ^L. This is the ASCII form feed character, decimal 12 or 0xC.
You can either reset that with set newpage none, or make it irrelevant with set pagesize 0, which has the convenient side effect of removing the column headers and separators. You may also want to set feedback off if you aren't already.
Samples with contrasting settings:
set newpage 0;
set feedback on;
set pagesize 100;
spool ctrl.csv
select 'head 1;head 2' from dual;
select sysdate, ';', systimestamp from dual;
spool off
^L'HEAD1;HEAD2'
-------------
head 1;head 2
1 row selected.
^LSYSDATE ' SYSTIMESTAMP
------------------- - ---------------------------------------------------------------------------
2015-09-16 15:45:42 ; 16-SEP-15 15.45.42.333627 +01:00
1 row selected.
And
set newpage none;
set feedback off;
set pagesize 0;
spool ctrl.csv
select 'head 1;head 2' from dual;
select sysdate, ';', systimestamp from dual;
spool off
head 1;head 2
2015-09-16 15:46:11 ; 16-SEP-15 15.46.11.274863 +01:00
Related
I have a requirement to generate the following summary report that look like the following:
My problem is that,
I have no idea on how do I fill the count data in this custom report.
I do not know how to put it in a table view like the above in a text document. It is not HTML.
So far, I only know how to do the first row, and column without the table view.
Here are my codes.
SET HEADING OFF;
SET LINESIZE 200;
SET SPACE 0;
SET ECHO OFF;
SET FEEDBACK OFF;
SET VERIFY OFF;
SET MARKUP HTML OFF SPOOL OFF;
SET TERMOUT OFF; --Do not show output to the screen.
SET NEWPAGE NONE; --Remove the first blank line at the top of the page and between queries.
TTITLE LEFT "REPORT NAME" RIGHT "PAGE : " SQL.PNO SKIP 1 -
LEFT "--------------------------------" RIGHT "DATE : " _DATE SKIP 1 -
LEFT "A) TOTAL RECORDS " RIGHT total_records; -- Cannot output variable in the title.
LEFT "B) MATCHED RECORDS " RIGHT matched_records; -- Cannot output variable in the title.
LEFT "C) UNMATCHED RECORDS " RIGHT matched_records; -- Cannot output variable in the title.
BTITLE LEFT "E N D";
total_records is an insert into statement.
SELECT COUNT(*) INTO total_records FROM TABLE;
I have not done matched records and unmatched records. But the only way I can think of
Select a statement into a cursor.
Loop into the cursor.
Increase matched count when there is a match.
Once loop finish. unmatched count = total count - matched count.
I don't think this is the most efficient way. But, if you have a better way, let me know.
Does something like this ring a bell? Example is based on Scott's sample schema:
SQL> select 'Total records' name, count(*) cnt
2 from emp
3 union all
4 select 'Matched count', sum(case when deptno = 10 then 1 else 0 end)
5 from emp
6 union all
7 select 'Unmatched count', sum(case when deptno = 10 then 0 else 1 end)
8 from emp;
NAME CNT
--------------- ----------
Total records 14
Matched count 3
Unmatched count 11
SQL>
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;
In Oracle SQL Developer, I can get simple query results returned in the 'Query Results' grid, but if I need to use variable in script, I need to use the 'Run Script' option and my results show up in 'Script Output' window, and I can't export it to csv format. Here is my sample code:
var CatCode char(5) ;
exec :CatCode := 'ZK';
SELECT * FROM Products WHERE CategoryCode = :CatCode;
Any help would be appreciated.
Thanks.
Just add a /*csv*/ to your query, the tool will bring back the output in CSV automatically when executed as a script (F5).
Or use a substitution variable instead. &Var vs :Var, run with F9, SQLDev will prompt you for the value.
VAR stcode CHAR(2);
EXEC :stcode := 'NC';
SELECT /*csv*/
*
FROM
untappd
WHERE
venue_state =:stcode;
Or to go straight to the grid so you can use can use the Grid Export feature.
SELECT
*
FROM
untappd
WHERE
venue_state =:stcode2;
Execute with Ctrl+Enter or F9
Supply the input parameter in the pop up dialog, click OK.
Shazaam.
Here you go you can run this one to be ensure. it's running.
set colsep , -- separate columns with a comma
set pagesize 0 -- No header rows
set trimspool on -- remove trailing blanks
set headsep off -- this may or may not be useful...depends on your headings.
set linesize X -- X should be the sum of the column widths
set numw X -- X should be the length you want for numbers (avoid scientific notation on IDs)
spool C:\Users\**direcotory**\sql\Test1.csv; --this is file path to save data
var CatCode char(5) ;
exec :CatCode := 'ZK';
SELECT * FROM Products WHERE CategoryCode = :CatCode;
spool off;
Thanks #thatjeffsmith and Paras, spool option gave me new direction and it worked. I slightly changed your code and it works great.
var CatCode char(5) ;
exec :CatCode := 'ZK';
set feedback off;
SET SQLFORMAT csv;
spool "c:\temp\spoolTest.csv"
SELECT * FROM Products WHERE CategoryCode = :CatCode;
spool off;
SET SQLFORMAT;
set feedback on;
I am trying to use a PL/SQL script in SQL*Plus to set the linesize and pagesize based on a developer input on whether a report should print in landscape or portrait orientation. If it is landscape, I want linesize 132 and pagesize 60. If it is portrait, I want 88 and 80 respectively.
I am trying to use substitution variables to do so like this:
DEFINE PRINT_ORIENTATION 'PORTRAIT'
COLUMN LINESIZE_VALUE NOPRINT new_value LINE
COLUMN PAGESIZE_VALUE NOPRINT new_value PAGE
SELECT DECODE('&PRINT_ORIENTATION', 'PORTRAIT', 88, 'LANDSCAPE', 132) AS LINE,
DECODE('&PRINT_ORIENTATION', 'PORTRAIT', 80, 'LANDSCAPE', 60) AS PAGE
FROM DUAL
/
SET LINESIZE &LINE
SET PAGESIZE &PAGE
However, the system then just prompts me to manually enter values for line and page. What do I need to do to use a substitution variable in the SET command?
With the column .. new_value ... syntax:
COLUMN Q_LINE NEW_VALUE LINE
COLUMN Q_PAGE NEW_VALUE PAGE
SELECT DECODE('&PRINT_ORIENTATION', 'PORTRAIT', 88, 'LANDSCAPE', 132) AS Q_LINE,
DECODE('&PRINT_ORIENTATION', 'PORTRAIT', 80, 'LANDSCAPE', 60) AS Q_PAGE
FROM DUAL
/
SET LINESIZE &LINE
SET PAGESIZE &PAGE
That allows you to define a substitution value from a query result.
With a "shell" substitution variable: What we do here to handle a similar issue, is we generate the correct sizing settings in a temporary sql file.
Not sure it'll help, but here's a hint on how to set the number of columns from the size of your terminal, with this in #$HOME/sqlmlogin.sql:
def_editor=emacs
set null °
set arraysize 1
set pagesize 0
set serveroutput on
host > $HOME/sqltmp_size.sql ; tty -s && ( eval $( resize ) ; echo "set lines $COLUMNS\n set pages 0" >> $HOME/sql/tmp_size.sql )
-- then call the temp script
#$HOME/sqltmp_size.sql
-- remove afterwards
host rm -f $HOME/sqltmp_size.sql
And call sqlplus like this:
sqlplus / #$HOME/sqlmlogin.sql
So you can also generate the static values you want for your users from a script like that.
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;