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

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

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;

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

Select consecutive values with interval

I am stuck with this code:
REM AWR-Generator.sql: Script for creating multiple consecutive Oracle AWR Reports
REM
REM Creates an output SQL script which, when run, will generate all AWR Reports
REM between the specificed start and end snapshot IDs, for all instances
REM
REM For educational purposes only - no warranty is provided
REM Test thoroughly - use at your own risk
REM
set feedback off
set echo off
set verify off
set timing off
-- Set AWR_FORMAT to "text" or "html"
define AWR_FORMAT = 'text'
define DEFAULT_OUTPUT_FILENAME = 'awr-generate.sql'
define NO_ADDM = 0
-- Get values for dbid and inst_num before calling awrinput.sql
set echo off heading on
column inst_num heading "Inst Num" new_value inst_num format 99999;
column inst_name heading "Instance" new_value inst_name format a12;
column db_name heading "DB Name" new_value db_name format a12;
column dbid heading "DB Id" new_value dbid format 9999999999 just c;
prompt
prompt Current Instance
prompt ~~~~~~~~~~~~~~~~
select d.dbid dbid
, d.name db_name
, i.instance_number inst_num
, i.instance_name inst_name
from v$database d,
v$instance i;
-- Call the Oracle common input script to setup start and end snap ids
##?/rdbms/admin/awrinput.sql
-- Ask the user for the name of the output script
prompt
prompt Specify output script name
prompt ~~~~~~~~~~~~~~~~~~~~~~~~~~
prompt This script produces output in the form of another SQL script
prompt The output script contains the commands to generate the AWR Reports
prompt
prompt The default output file name is &DEFAULT_OUTPUT_FILENAME
prompt To accept this name, press <return> to continue, otherwise enter an alternative
prompt
set heading off
column outfile_name new_value outfile_name noprint;
select 'Using the output file name ' || nvl('&&outfile_name','&DEFAULT_OUTPUT_FILENAME')
, nvl('&&outfile_name','&DEFAULT_OUTPUT_FILENAME') outfile_name
from sys.dual;
set linesize 800
set serverout on
set termout off
-- spool to outputfile
spool &outfile_name
-- write script header comments
prompt REM Temporary script created by awr-generator.sql
prompt REM Used to create multiple AWR reports between two snapshots
select 'REM Created by user '||user||' on '||sys_context('userenv', 'host')||' at '||to_char(sysdate, 'DD-MON-YYYY HH24:MI') from dual;
set heading on
-- Begin iterating through snapshots and generating reports
DECLARE
c_dbid CONSTANT NUMBER := :dbid;
c_inst_num CONSTANT NUMBER := :inst_num;
c_start_snap_id CONSTANT NUMBER := :bid;
c_end_snap_id CONSTANT NUMBER := :eid;
c_awr_options CONSTANT NUMBER := &&NO_ADDM;
c_report_type CONSTANT CHAR(4):= '&&AWR_FORMAT';
v_awr_reportname VARCHAR2(100);
v_report_suffix CHAR(5);
CURSOR c_snapshots IS
select inst_num, start_snap_id, end_snap_id
from (
select s.instance_number as inst_num,
s.snap_id as start_snap_id,
lead(s.snap_id,1,null) over (partition by s.instance_number order by s.snap_id) as end_snap_id
from dba_hist_snapshot s
where s.dbid = c_dbid
and s.snap_id >= c_start_snap_id
and s.snap_id <= c_end_snap_id
)
where end_snap_id is not null
order by inst_num, start_snap_id;
BEGIN
dbms_output.put_line('');
dbms_output.put_line('prompt Beginning AWR Generation...');
dbms_output.put_line('set heading off feedback off lines 800 pages 5000 trimspool on trimout on');
-- Determine report type (html or text)
IF c_report_type = 'html' THEN
v_report_suffix := '.html';
ELSE
v_report_suffix := '.txt';
END IF;
-- Iterate through snapshots
FOR cr_snapshot in c_snapshots
LOOP
-- Construct filename for AWR report
v_awr_reportname := 'awrrpt_'||cr_snapshot.inst_num||'_'||cr_snapshot.start_snap_id||'_'||cr_snapshot.end_snap_id||v_report_suffix;
dbms_output.put_line('prompt Creating AWR Report '||v_awr_reportname
||' for instance number '||cr_snapshot.inst_num||' snapshots '||cr_snapshot.start_snap_id||' to '||cr_snapshot.end_snap_id);
dbms_output.put_line('prompt');
-- Disable terminal output to stop AWR text appearing on screen
dbms_output.put_line('set termout off');
-- Set spool to create AWR report file
dbms_output.put_line('spool '||v_awr_reportname);
-- call the table function to generate the report
IF c_report_type = 'html' THEN
dbms_output.put_line('select output from table(dbms_workload_repository.awr_report_html('
||c_dbid||','||cr_snapshot.inst_num||','||cr_snapshot.start_snap_id||','||cr_snapshot.end_snap_id||','||c_awr_options||'));');
ELSE
dbms_output.put_line('select output from table(dbms_workload_repository.awr_report_text('
||c_dbid||','||cr_snapshot.inst_num||','||cr_snapshot.start_snap_id||','||cr_snapshot.end_snap_id||','||c_awr_options||'));');
END IF;
dbms_output.put_line('spool off');
-- Enable terminal output having finished generating AWR report
dbms_output.put_line('set termout on');
END LOOP;
dbms_output.put_line('set heading on feedback 6 lines 100 pages 45');
dbms_output.put_line('prompt AWR Generation Complete');
-- EXCEPTION HANDLER?
END;
/
spool off
set termout on
prompt
prompt Script written to &outfile_name - check and run in order to generate AWR reports...
prompt
--clear columns sql
undefine outfile_name
undefine AWR_FORMAT
undefine DEFAULT_OUTPUT_FILENAME
undefine NO_ADDM
undefine OUTFILE_NAME
set feedback 6 verify on lines 100 pages 45
This piece of code generates a spool file with consecutive snap ids between start snap and end snap. I want to modify it, such that it asks for an interval value and calculate start_snap and end_snap with that interval.
For eg.
If I give start_snap as 1400 and end_snap as 1404 with interval as 2, then it should give reports with 1400 to 1402, 1403 to 1404.
Regards,
Kaushal.

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;

remove spaces or tab when spooling

I am trying to extract data(spooling) from oracle and it got spaces or tab between the data.
My script is like this.
set head off;
set feed off;
set lines 32767;
set trimspool on;
set trimout on;
set pages 0;
set space 0;
set tab off;
set wrap off;
set colsep "|";
spool FNAME;
select select id, name, job from table;
spool off;
exit
The data should be like this:
ID|NAME |JOB
Suppose ID and NAME should not have any spaces or tab between it
but instead, i have data like this:
ID<--spaces/tab-->|NAME |JOB
There's additional spaces or tab added between ID and NAME. i already set the parameters. I dont know what to change.
SQL*Plus is formatting the results into aligned columns for you. You can avoid this by doing the formatting yourself:
select select id || '|' || name || '|' || job from table;

Resources