Oracle SQL Script - Why spool creates file twice - oracle

I run the following SQL-script using Oracle SQL Developer. I don't know why it creates two spool file and it also displays the entire operations in the Oracle SQL Developer console which it should not. Maybe it is due to the SET FEEDBACK ON and SET FEEDBACK OFF for each delete statement.
It creates two files and displays everything in script-output only when there are some records for deletion.
The script's call
#"C:\RM.sql"
The script
SET PAGES 0
SET LINESIZE 10000
SET TRIMS ON
SET ECHO OFF
SET HEADING ON
SET VERIFY OFF
SET FEEDBACK OFF
SET TERMOUT OFF
SET SERVEROUTPUT on size 1000000
SET TIMING OFF
SET COLSEP '|'
alter session set NLS_DATE_FORMAT = 'dd.mm.yyyy hh24:mi:ss';
whenever oserror exit -1
whenever sqlerror exit -2
-- The current timestamps into 'times' variable
column times new_value times noprint
select to_char(sysdate, 'YYYYMMDD_HH24MISS') times from DUAL;
-- variables definition
define output_file="C:\temp\filename_&times..log"
-- echo some text to the standard output
SET TERMOUT ON
PROMPT
PROMPT "The script counts and reports the records to be deleted..."
PROMPT
SET TERMOUT OFF
-- write the results to the 'output_file' file
spool &output_file
PROMPT
PROMPT "BEGIN------------------------------"
PROMPT "delete from the_table1"
select 'Total records BEFORE delete: ' || count (*) as count_records from the_table1;
SET FEEDBACK ON
PROMPT "Actual deletion of records..."
delete from the_table1;
commit;
SET FEEDBACK OFF
PROMPT "END------------------------------"
PROMPT
PROMPT "BEGIN------------------------------"
PROMPT "delete from the_table2"
select 'Total records BEFORE delete: ' || count (*) as count_records from the_table2;
SET FEEDBACK ON
PROMPT "Actual deletion of records..."
delete from the_table2;
commit;
SET FEEDBACK OFF
PROMPT "END------------------------------"
PROMPT
PROMPT "The script completed..."
SPOOL OFF
SET TERMOUT ON
PROMPT
PROMPT "&output_file has been successfully ended."
PROMPT
PROMPT
EXIT
;

I seem to recall TERMOUT and ECHO options depend on how sqlplus is being run and can give different results, similar to what you are seeing.
I'm using sqlplus as a example of how interactions with the run environment can affect output. This isn't really an answer, and I cannot reproduce the scenarios I used to see often, but I hope the following perhaps will offer some pointers as to what might be encountered.
Start with a simple test script test_off.sql:
set echo off
set termout off
prompt text1
spool f1.txt
prompt text2
spool off
prompt text 3
quit
Now let's run it a number of different ways:
1 Non-interactively Parameterised
$ sqlplus -S un/pw#idb #test_off.sql
$ cat f1.txt
text2
No output to screen, spool file created, with only the spooled contents.
2. Interactively
$ sqlplus -S un/pw/#db
#test_off.sql
$ cat f1.txt
text2
No output to screen, spool file created, with only the spooled contents.
3. Run as piped feed
$ cat test_off.sql | sqlplus -S un/pw#db
text1
text2
text 3
Here we see all the PROMPT command results on screen.
Similar effects may be seen if run within a HEREDOC block.
I've definitely seen (in older versions) some strange inconsistencies and perhaps your SQL Developer is similarly afflicted.

Related

not able to suppress sqlplus output on terminal

I am using following script to delimited file using spool in the unix server. I ssh into it using putty and execute the shell script.
Here is shell script:
/oracle/app/oracle/product/19.0.0/dbhome_1/bin/sqlplus -s /nolog<<-EOF
conn user/pass
SET PAGESIZE 0
SET LINESIZE 32000
SET NUMWIDTH 127
SET FEEDBACK OFF
set echo off
set heading off
set headsep off
SET MARKUP CSV ON DELIMITER | quote off
set termout off
spool mc_format.dat
select * from mytable;
spool off
EOF
but I am not able to suppress the rows printing out on the terminal, and eventually on log when I run using cron.
Is there any setting I am missing out?
Right from the documentation
SET TERMOUT OFF
Controls the display of output generated by commands in a script that is executed with #, ## or START. OFF suppresses the display so that you can spool output to a file without displaying the output on screen. ON displays the output on screen. TERMOUT OFF does not affect output from commands you enter interactively or redirect to SQL*Plus from the operating system.
So instead of the here document, call the script using one of the start methods mentioned.

How to use sqlplus and sqlldr in a script file?

I am using sqlplus to get data from a remote database table and then using sqlldr to insert that data into some other table. I have written a shell script to do this. The sqlplus option is working but the sqlldr command is not working, although I have been able to insert using it from command prompt but it seems not be working in file.
Here's my script.
#!/bin/bash
#script to get 5 minutes of data from FCT table and insert into LOCAL table
sqlplus -s user/passs#FCT_DB <<EOF
SET TERMOUT OFF
SET LINESIZE 300
SET HEAD OFF
SPOOL export.csv
SELECT X FROM Y
SPOOL OFF
EXIT
EOF
! SQLLDR usr/pass#LOCAL_DB CONTROL=loader.ctl ERRORS=5000
The export.csv is created correctly. loader.ctl is also correct.
Also, whenever the script runs it shows data fetched on shell. I have searched that SET TERMOUT OFF helps not to display it, but it also doesn't seem to work.

Spool Command: Do not output SQL statement to file

I am wanting to output a Query to a CSV file and am using the below as a small test;
spool c:\test.csv
select /*csv*/ username, user_id, created from all_users;
spool off;
but the output has the actual select statment as the first line
> select /*csv*/ username user_id created from all_users
USERNAME USER_ID CREATED
REPORT 52 11-Sep-13
WEBFOCUS 51 18-Sep-12
Is there a way to prevent this? I tried SET Heading Off thinking that might do it, but it did not change. I am using SQL Developer an running as script.
Thanks
Bruce
Unfortunately SQL Developer doesn't fully honour the set echo off command that would (appear to) solve this in SQL*Plus.
The only workaround I've found for this is to save what you're doing as a script, e.g. test.sql with:
set echo off
spool c:\test.csv
select /*csv*/ username, user_id, created from all_users;
spool off;
And then from SQL Developer, only have a call to that script:
#test.sql
And run that as a script (F5).
Saving as a script file shouldn't be much of a hardship anyway for anything other than an ad hoc query; and running that with # instead of opening the script and running it directly is only a bit of a pain.
A bit of searching found the same solution on the SQL Developer forum, and the development team suggest it's intentional behaviour to mimic what SQL*Plus does; you need to run a script with # there too in order to hide the query text.
My shell script calls the sql file and executes it. The spool output had the SQL query at the beginning followed by the query result.
This did not resolve my problem:
set echo off
This resolved my problem:
set verify off
Just for anyone who stumbles upon this (after 7+ years) ...
This works for me ... adapt it to your way of invoking sqlplus.
sqlplus -s / as sysdba 2>&1 > /dev/null <<EOF
whenever sqlerror exit sql.sqlcode;
set echo off
set verify off
set feedback off
set term off
set head off
set pages 1000
set lines 200
spool /tmp/whatever.output
### Your_SQL_statement_here ###
example: select sysdate from dual;
example: select * from V\$LOGFILE;
spool off
EOF
-s flag here is the key to not displaying the SQL statements when runing a script.
set echo off
spool c:\test.csv
select /*csv*/ username, user_id, created from all_users;
spool off;
You can directly export the query result with export option in the result grig.
This export has various options to export. I think this will work.
Exec the query in TOAD or SQL DEVELOPER
---select /*csv*/ username, user_id, created from all_users;
Save in .SQL format in "C" drive
--- x.sql
execute command
---- set serveroutput on
spool y.csv
#c:\x.sql
spool off;

pass sqlplus value to shell variable

the below picture shows what gets returned when I run sqlplus in shell
but when I run this from the "run" command:
powershell.exe -noexit c:\sqltriggers\voicetrigger2.ps1
with voicetrigger2.ps1 as this:
$(sqlplus user/pass#OMP1 '#C:\sqltriggers\VOICEBLOCKTRIG.SQL');
I get this:
I should expect a 3 back. The issue is, I try to set that as a variable, and if the integer is greater than zero, run a BAT file. But I don't think the SQLPlus is returning JUST an integer value. I think its actually returning this:
count(*)
3
How do I get it to just return the integer value from the SQLplus command?
SQL*Plus isn't returning anything, it's displaying the result of the query on standard output. To get the direct call to only show 3 you can set heading off in the SQL script, and also call SQL*Plus with the -s flag to suppress the banner. You probably also want an exit at the end of the SQL script so it doesn't stay sitting at the SQL> prompt.
The same applies to the powershell call, but there's something else going on there; the 17 is a line number which means it's waiting for more input and hasn't executed the commands in the SQL script, which suggests either a query without a terminating ; or /, or a PL/SQL block without a terminating /. But if it's exactly the same SQL you ran in the first example then that is a bit odd as they should behave the same. You should add the SQL script contents to the question to see what might be wrong.
The only thing I can think of that would change behaviour like that is if you had a login.sql that includes a set sqlterminator command, but you'd have to be picking up different login.sql files from the two calls... which is plausible if powershell has its own environment variables, perhaps.
It won't work this way. As Alex mentioned, sqlplus doesn't return anything as a function - it only writes whatever output you generate to standard output.
You can have variables in sqlplus, but there is no easy way to pass them to host environment. The only way I can think of is to use spool command to generate another batch file, which will actually set your host variables, and then process them the way you want in your host script.
Something like this:
16:30:20 SYSTEM#sandbox> get host.sql
1 SET VERIFY OFF TRIMSPOOL ON TERMOUT OFF HEADING OFF LINESIZE 4000 PAGES 0 FEEDBACK OFF timing off
2 spool s:\.tmp\host.ps1
3 select '$env:MY_VAR="'||dummy||'"' from dual;
4 spool off
5* exit
16:30:25 SYSTEM#sandbox> #host.sql
Disconnected from Oracle Database 11g Express Edition Release 11.2.0.2.0 - Production
PS S:\.tmp> cat host.ps1
$env:MY_VAR="X"
PS S:\.tmp> .\host.ps1
PS S:\.tmp> $env:my_var
X
PS S:\.tmp>
sqlplus -s /nolog <<EOF > query_result.txt
set heading off feedback off pagesize 0 linesize 30000 trimout on ;
select 5 from dual;
exit;
EOF
for i in `cat query_result.txt `
do
exit $i
done
try adding SET HEADING OFF in the beginning of your file. Check this answer (check the second best voted answer)

Oracle SqlPlus - saving output in a file but don't show on screen

Using SqlPlus for Oracle, how do I save the output of a query in a file but not show it on the terminal/prompt.
Right from the SQL*Plus manual
http://download.oracle.com/docs/cd/B19306_01/server.102/b14357/ch8.htm#sthref1597
SET TERMOUT
SET TERMOUT OFF suppresses the display so that you can spool output from a script without
seeing it on the screen.
If both spooling to file and writing to terminal are not required, use SET TERMOUT OFF in >SQL scripts to disable terminal output.
SET TERMOUT is not supported in iSQL*Plus
Try this:
SET TERMOUT OFF;
spool M:\Documents\test;
select * from employees;
/
spool off;
Try This:
sqlplus -s ${ORA_CONN_STR} <<EOF >/dev/null
set termout off doesn't work from the command line, so create a file e.g. termout_off.sql containing the line:
set termout off
and call this from the SQL prompt:
SQL> #termout_off

Resources