UNIX script Fetch the SQL query output to a file - oracle

I have a SQL script
select fh.box_name
from file_update_history fh,update_file_vw ff
WHERE
ff.file_id=fh.file_id
and fh.act_record_count IS NULL
AND FF.STATUS_CD <> 'OLD'
and to_char(fh.access_date,'YYYYMMDD') between to_char(SYSDATE, 'YYYYMMDD') and to_char(SYSDATE+1, 'YYYYMMDD')
order by fh.exp_arr_time_update_file,FF.FILE_NAME;
I need to get/spool the output of this SQL into a flat file. Which should have the query output. I am not getting the output of the query into the file.
I have used
sqlplus /NOLOG <<My_DB > $DB_OUTPUT_FILE
set feedback on;
set term on;
set echo on;
set heading off;
set underline off;
set pagesize 10000;
set linesize 999;
set wrap off;
WHENEVER SQLERROR EXIT 20;
connect ${My_DB_USER}/${My_DB_PASSWORD} ;
select fh.box_name
from file_update_history fh,update_file_vw ff
WHERE
ff.file_id=fh.file_id
and fh.act_record_count IS NULL
AND FF.STATUS_CD <> 'OLD'
and to_char(fh.access_date,'YYYYMMDD') between to_char(SYSDATE, 'YYYYMMDD') and to_char(SYSDATE+1, 'YYYYMMDD')
order by fh.exp_arr_time_update_file,FF.FILE_NAME;
exit
My_DB

It's probably easier to use the spool command:
sqlplus /NOLOG <<My_DB
set feedback on
set term on
set echo on
set heading off
set underline off
set pagesize 10000
set linesize 999
set wrap off
WHENEVER SQLERROR EXIT 20
connect ${My_DB_USER}/${My_DB_PASSWORD}
SET ECHO OFF
SET TERM OFF
SPOOL ${DB_OUTPUT_FILE}
select fh.box_name
from file_update_history fh,update_file_vw ff
WHERE
ff.file_id=fh.file_id
and fh.act_record_count IS NULL
AND FF.STATUS_CD <> 'OLD'
and to_char(fh.access_date,'YYYYMMDD') between to_char(SYSDATE, 'YYYYMMDD') and to_char(SYSDATE+1, 'YYYYMMDD')
order by fh.exp_arr_time_update_file,FF.FILE_NAME;
SET SPOOL OFF
exit
My_DB

You don't need the ; a the end of the connect statement; can't check right now but is it possible that is causing an error, or that the credentials are wrong? Is the output file completely empty? And what is the return code from the sqlplus command - zero or 20?
You can change the WHENEVER SQLERROR to EXIT SQL.SQLCODE to get a better idea what went wrong - though it should be in the output anyway - but some shells don't understand big numbers.

Related

Adding extra data/information to filename using spool in sqlplus

I'm trying to achieve the below requirements in the filename being exported as csv
FILENAME: filename_yyyymmdd_nnnnnn_xxxxxx.csv
where
yyyymmdd = Datestamp on when the Account file was generated
nnnnnn = 6-byte random generated batch ID
xxxxxx = 6-byte zero-padded string that contains the number of records in the file
So far, I have the below query saved as a script which I run on sqlplus.
set head off;
set feedback off;
set term off;
set pagesize 0;
set linesize 3000;
set trimspool on;
set colsep ,;
set verify off;
set echo off;
ALTER SESSION SET NLS_DATE_FORMAT= 'MM-DD-YYYY';
whenever sqlerror exit sql.sqlcode;
whenever oserror exit failure;
column date_stamp new_value sys_date noprint
column rnd_num new_value random noprint
column row_count new_value rc noprint
select to_char(sysdate,'mmddYYYY') date_stamp
from dual;
select lpad(round(dbms_random.value(1,999999)),6,'0') rnd_num from dual;
/* select count(*) as row_count
from table a, table b join on a.id = b=id where condition; */
spool filepath.&sys_date..&random..&rc..&1..csv
select statement fetching the actual data;
spool off;
exit;
The problem is:
I am able to generate the random no,but not able to add record count (xxxxxx part of the filename requirement). When the part commented is uncommented and run, the sql script runs but no file is generated. When it is run with the "select count(*)" part as commented, the file is generated as expected, has the random no bit(nnnnnn) but doesn't have the no of records(xxxxxx), obviously because it is commented out. How to include the no of records in the filename as well?
So, with enough reading around the web, I found the solution. The row_count for some reason in my query was returning with a 5 empty spaces padded value then the actual row_count. Posting the answer below:
set head off;
set feedback off;
set term off;
set pagesize 0;
set linesize 3000;
set trimspool on;
set colsep ,;
set verify off;
set echo off;
ALTER SESSION SET NLS_DATE_FORMAT= 'MM-DD-YYYY';
whenever sqlerror exit sql.sqlcode;
whenever oserror exit failure;
column date_stamp new_value sys_date noprint
column rnd_num new_value random noprint
column row_count new_value rc noprint
select to_char(sysdate,'mmddYYYY') date_stamp
from dual;
select lpad(round(dbms_random.value(1,999999)),6,'0') rnd_num from dual;
select row_count from (select trim(count(*)) as row_count
from table a ...;
spool filepath.&sys_date..&random..&rc..&1..csv
select statement fetching the actual data;
spool off;
exit;

Is there any PL/SQL script to modify column value of each table in each schema of Oracle Database

I have written pl/sql code to modify column values in a table of one schema. But I need to execute the same script in each table of each schema. I will take the list of the table name, column name from spreadsheet.
define schema_name = 'D';
define hours_offset = '(-3/24)';
set echo off;
set timi off;
set heading off;
set feedback off;
set linesize 250;
spool convert_01.sql
select 'set echo on;' from dual;
select 'set timi on;' from dual;
select 'set heading on;' from dual;
select 'set feedback on;' from dual;
select 'set linesize 250;' from dual;
select 'spool convert_01.log;' from dual;
select 'update '||owner||'.'||table_name||' set '||column_name||'
='||column_name||' + &hours_offset;'
from dba_tab_columns where owner = '&schema_name' and
(
data_type = 'DATE' or
data_type like 'TIMESTAMP%'
) and
data_type not like 'TIMESTAMP%WITH TIME ZONE'
order by owner, table_name, column_name;
select 'spool off;' from dual;
spool off;
I need to execute the same script in each table of each schema
That's most probably not true. There are users (schemas) you shouldn't modify at all, e.g. SYS, SYSTEM, CTXSYS, APEX180200 and such.
Therefore, you'd rather collect list of users you want to skip (or the ones you want to affect; it's up to you). That list would then be used instead of '&schema_name'.
A simple option is to store list of users into a table and use its contents as a subquery in your current script.
Unrelated, but:
I have written pl/sql code ...
Nope; what you wrote is a pure SQL script readable by SQL*Plus (and, possibly, some other tools which understand commands you used).

How to do dynamic spool's using sqlplus by batch-file

I'm trying save multiples txt archives with querye result using a single .sql archive called by a batch-file for automate-work.
My Batch-file:
set d=%location%result.txt
set f=%location%result2.txt
echo exit | sqlplus GOVMANPATCHORACLE/GOVMANPATCHORACLE#%SERVER%/%SERVICE% #C:\Users\enrique.erbs\Desktop\JOB\Tools\extrator_parametros\queryoracle.sql '%d%' '%f%'
*'%d%' contains the save locale to spool
My archive .sql (queryoracle.sql):
SET PAGESIZE 50000
SET LINESIZE 800
SET VERIFY OFF
SET ECHO ON
SET HEAD ON
SET SERVEROUTPUT ON;
SET PAGES 0
SET DEFINE ON;
COLUMN COD_PARAMETRO FORMAT a100 HEADING COD_PARAMETRO;
COLUMN DES_PARAMETRO FORMAT a100 HEADING DES_PARAMETRO;
COLUMN DES_VALOR FORMAT a100 HEADING DES_VALOR;
DECLARE
myvar1 varchar2(30);
myvar2 varchar2(30);
BEGIN
myvar1 := '$1';
myvar2 := '$2';
SPOOL 'myvar1'
SELECT TDFE_PARAMETRO_APLICACAO.COD_PARAMETRO AS COD_PARAMETRO, TDFE_PARAMETRO.DES_PARAMETRO AS DES_PARAMETRO, TDFE_PARAMETRO_APLICACAO.DES_VALOR AS DES_VALOR FROM TDFE_PARAMETRO_APLICACAO INNER JOIN TDFE_PARAMETRO ON(TDFE_PARAMETRO_APLICACAO.COD_PARAMETRO=TDFE_PARAMETRO.COD_PARAMETRO);
SPOOL OFF
SPOOL 'myvar2'
SELECT * FROM TDFE_PARAMETRO_APLICACAO;
SPOOL OFF
END;
I tryed some options and the most closest to get the result what i want is using ">> %location%\result.txt" at end of sqlplus call.
Somebody can help me ?
You were not far at all. Actually, When executing SQLPLUS and passing him a file to execute and arguments, It will replace every single occurence of &1 By your first Argument, Every occurence of &2 by your second argument, etc ...
This should work :
SET PAGESIZE 50000
SET LINESIZE 800
SET VERIFY OFF
SET ECHO ON
SET HEAD ON
SET SERVEROUTPUT ON;
SET PAGES 0
SET DEFINE ON;
COLUMN COD_PARAMETRO FORMAT a100 HEADING COD_PARAMETRO;
COLUMN DES_PARAMETRO FORMAT a100 HEADING DES_PARAMETRO;
COLUMN DES_VALOR FORMAT a100 HEADING DES_VALOR;
SPOOL '&1'
SELECT TDFE_PARAMETRO_APLICACAO.COD_PARAMETRO AS COD_PARAMETRO, TDFE_PARAMETRO.DES_PARAMETRO AS DES_PARAMETRO, TDFE_PARAMETRO_APLICACAO.DES_VALOR AS DES_VALOR FROM TDFE_PARAMETRO_APLICACAO INNER JOIN TDFE_PARAMETRO ON(TDFE_PARAMETRO_APLICACAO.COD_PARAMETRO=TDFE_PARAMETRO.COD_PARAMETRO);
SPOOL OFF
SPOOL '&2'
SELECT * FROM TDFE_PARAMETRO_APLICACAO;
SPOOL OFF
For reference : https://docs.oracle.com/cd/E11882_01/server.112/e16604/ch_twelve044.htm#SQPUG127

SQL developer query results to dynamic csv file

I am trying to export my query results to csv file with spool command in SQL Developer. It works when csv file name is static, but now I need to create file name dynamically and I tried as follow but obviously its not working. Can anyone please help?
var CatCode char(5) ;
exec :CatCode := 'ZK';
exec :csvFile := 'c:\temp\MyCSV_' || trim(:CatCode) || '.csv';
set feedback off;
SET SQLFORMAT csv;
spool csvFile
SELECT * FROM Products WHERE CategoryCode = :CatCode;
spool off;
SET SQLFORMAT;
set feedback on;
I tried spool command with spool :csvFile or spool &csvFile but did not help.
VAR CatCode CHAR ( 5 );
EXEC :CatCode := 'ZK';
SET FEEDBACK OFF;
SET SQLFORMAT csv;
SET TERMOUT OFF
column filename new_value filename
SELECT 'c:\temp\MyCSV_' || trim(:CatCode) || '.csv' as filename FROM DUAL;
SPOOL &filename
SELECT * FROM Products WHERE CategoryCode = :CatCode;
SPOOL OFF;
SET SQLFORMAT;
SET FEEDBACK ON;
Also you might want to check this askTOM article.
https://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:3581757800346555562

Column Values shifting to next row while creating a CSV using SQL *Plus

I want the output of a SQL query in a csv file. While other such jobs are running successfully, here is a job, one of them, which gives me a csv like this. I have checked the loader control file - it seems fine. I have also checked the SQL query - also, perfectly fine. What could be the problem?
SPOOL CSV_TO_BE_GENERATED.csv;
SET LINESIZE 1000;
SET PAGESIZE 0;
SET TRIMSPOOL ON;
SET FEEDBACK OFF;
SET SQLBLANKLINES ON;
WHENEVER SQLERROR EXIT SQL.SQLCODE
select
'COLUMN_1'||','||
'COLUMN_2'||','||
'COLUMN_3'||','||
'COLUMN_4'||','||
'COLUMN_5'||','||
'COLUMN_6'||','||
'COLUMN_7'||','||
'COLUMN_8'
from DUAL;
select COLUMN_1||','||
COLUMN_2||','||
COLUMN_3||','||
COLUMN_4||','||
COLUMN_5||','||
COLUMN_5||','||
COLUMN_7||','||
COLUMN_8
from some_table ;
SPOOL OFF
EXIT;

Resources