running ddl file through sh - linux

I am having issue when running a ddl script file through sh on one of the servers but executes fine on another. The script is as below
sqlplus mgr/$1#$2 #export_all_tables_mgr.ddl
if [ $? != 0 ];
then
echo 'ERROR exporting MGR data, Refer to .CSV and .CTL files for detail.' | tee -a MGR_ExtractionLog.log
fi
It uses sqlplus to run the ddl file but one the rogue server, it would just connect to sql plus and won't do anything.
oracle#dbsdev55z2 $ export_all_tables_mgr.sh password servicename
SQL*Plus: Release 10.2.0.4.0 - Production on Thu Jan 24 08:39:18 2013
Copyright (c) 1982, 2007, Oracle. All Rights Reserved.
Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bit Production With the Partitioning, Data Mining and Real Application Testing options
SQL>
To mention here, I am using Oracle 10g here. export_all_tables_mgr.ddl file is as below
alter session set nls_date_format = 'DDMMYYYYHH24MISS';
#drop_table_temp_extraction_counts.ddl
#create_table_temp_extraction_counts.ddl
WHENEVER SQLERROR EXIT -1
WHENEVER OSERROR EXIT -1
SET HEADING OFF
SET FEEDBACK OFF
SET VERIFY OFF
SPOOL MGR_ExtractionLog.log
SELECT TO_CHAR(SYSDATE, 'DD/MM/YYYY HH24:MI:SS'), '- Start extract process' FROM dual;
SPOOL OFF
define TableName=TABLE1
#ExportTable
define TableName=TABLE2
#ExportTable
SPOOL MGR_ExtractionLog.log append
SELECT TO_CHAR(SYSDATE, 'DD/MM/YYYY HH24:MI:SS'), '- End extract process' FROM dual;
SPOOL OFF
EXIT 0

I'm guessing that this is a shell problem, try adding the following as the first line of your shell script to tell it which interpreter to use:
#!/bin/sh

Related

Not to display SQLPLUS prompt

I am trying to connect with sqlplus using a bash script. When I execute the script below SQLPLUS banner displayed.
Below the script:
$ORACLE_HOME/bin/sqlplus "/ as sysdba" <<EOF
set echo off
set heading off
spool bind.txt
select * from DBMS_LOCK_ALLOCATED where name = '$uservar';
spool off
exit
EOF
Output of the script
oracle#DMOTA01:~/script> ./before_bind.sh
SQL*Plus: Release 11.2.0.3.0 Production on Wed Nov 27 11:54:01 2019
Copyright (c) 1982, 2011, Oracle. All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL> SQL> 2 3 4 Disconnected from Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
oracle#DMOTA01:~/script>
I don't want to display "SQL*Plus: Release 11............. Real Application Testing options" lines. How i can do it?
You need to add -S to sqlplus to switch it in silence mode:
$ORACLE_HOME/bin/sqlplus -S "/ as sysdba" <<EOF
set echo off
set heading off
spool bind.txt
select * from DBMS_LOCK_ALLOCATED where name = '$uservar';
spool off
exit
EOF

How to reliably return results from Oracle SQL*Plus to a variable in Korn shell?

Hello Unix/Linux geniae,
When an error occurs in the query, why does the shell variable (OPEN_MODE in this case) contain not only the expected SQL error message but also a listing of all the files in the directory?
I realise it has to do with the backticks and the fact that there is an asterisk in the error message but how can I get the error message back without the directory listing?
Run from command line:
$ OPEN_MODE=`sqlplus -s '/ as sysdba' <<'EOSQL' 2>/tmp/results.synchro.$$
> set headi off newpa none feedb off
> whenever sqlerror exit failure
> select open_mode from v$database;
> EOSQL
> `
$ echo $OPEN_MODE
select open_mode from v$database db_space_calculation.ksh get_emc_schedule_status.ksh set_emc_schedule_status.ksh synchro.ksh synchro_adsp_adso.cfg synchro_arp_arpt.cfg synchro_xbrl_xbrla.cfg synchro_xbrl_xbrlt.cfg test.sh ERROR at line 1: ORA-01034: ORACLE not available Process ID: 0 Session ID: 0 Serial number: 0
And run interactively from SQL*Plus to show how the error is normally presented...
$ sqlplus '/ as sysdba'
SQL*Plus: Release 12.1.0.2.0 Production on Mon Jan 15 20:31:04 2018
Copyright (c) 1982, 2014, Oracle. All rights reserved.
Connected to an idle instance.
SQL> set headi off newpa none feedb off
SQL> whenever sqlerror exit failure
SQL> select open_mode from v$database;
select open_mode from v$database
*
ERROR at line 1:
ORA-01034: ORACLE not available
Process ID: 0
Session ID: 0 Serial number: 0
Disconnected
I have also tried the "piping into read" method but doesn't work either.
sqlplus -s '/ as sysdba' <<'EOSQL' 2>/tmp/results.synchro.$$ | read OPEN_MODE
set headi off newpa none feedb off
whenever sqlerror exit failure
select open_mode from v$database;
EOSQL
Has to work in ksh. No bash please.
$() produces the same results as backticks. The only time I use backticks in ksh is when calling sqlplus! There are times when $() simply does not work. But that's for another day :-)

Passing the name of spool file to sqlplus from a shell script

I am trying to write a unix program, in which I need to connect to the SQL DB and fetch the data and store it into a file.
Currently I am using the following command:
output1=`sqlplus -s username#SID/password <<EOF
SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING ON ECHO OFF;
SPOOL EMP_NAMES.txt
select emp_name from employee order by emp_name;
Spool off;
This is working fine. But my requirement was that I want to pass the value of spool file such that everytime a new Spool file would be generated.
I basically want to append the date at the end of the file name like:
date=`date +'%d/%m/%Y_%H:%M:%S:%2N'`
output1=`sqlplus -s username#SID/password <<EOF
SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING ON ECHO OFF;
SPOOL EMP_NAMES_$date.txt
Kindly let me know as to how this can be done.
If you call your sqlplus with a heredoc, you can do this easily:
spool_file=: ... your date logic here ...
sql_ouput=: ... path for sqlplus output & errors ...
sqlplus -s username#SID/password << EOF &> "$sql_output"
SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING ON ECHO OFF;
spool $spool_file
# SQL statements
spool off
EOF
if [[ $? != 0 ]]; then
: ... error handling ...
fi
It's better to capture stdout/stderr of sqlplus into a file rather than a shell variable.
I think it is possible to hide the password by removing it from the command line and adding it as the first line of heredoc (this will prevent password from showing in ps)
Take a look at this related post: Connect to sqlplus in a shell script and run SQL scripts

Running Linux Functions inside Sqlplus

Can I call user-created shell functions from inside Oracle SQLPLUS using the HOST command? If not, what's the best way to approach the problem?
Essentially, I want to run a shell file:
Shell commands
sqlplus
#file.sql
HOST mylinuxfunction...
#file2.sql
HOST anotherlinuxfunction..
exit
Shell commands
Thank you!
You can surely invoke HOST commands from SQLPlus scripts, but I imagine you are really asking whether you can use the return values from your linux functions in the rest of your SQLPlus scripts. And you also might be wanting to use results from the SQL queries in your linux functions.
If you do not need to pass SQL information to your linux functions, and do not need to access the results from the linux functions in the remainder of your SQL, then what you have will almost work. This would
date
sqlplus / << xxENDxx \
#file.sql
HOST mylinuxfunction...
#file2.sql
HOST anotherlinuxfunction..
exit
xxENDxx
date
Now if you want to get information from your linux function into SQL, you will have to use external tables; a lot of setup, but look here: https://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:439619916584 and search for "but here is another interesting approach, available in 10.2.0.5 and up:"
If you want to pass information from Linux commands that are done before invoking SQLPlus into your SQL commands, that would be something like this, that inserts a row into the uptimes table with output from the uptime command that is stored in the BASH variable $UPTIMES:
#!/bin/bash
if [ "$1" = "" ]
then
echo Missing User ID parm
exit 1
else
USER_ID=$1
fi
read -p "Enter Your password for Oracle instance $ORACLE_SID for user $USER_ID: " PW
UPTIMES=`uptime | awk -F, '{print $3, $4, $5}' | awk '{printf "%2.2f,%2.2f,%2.2f\n", $3, $4, $5}'`
sqlplus /nolog << xxENDxx \
connect $USER_ID/$PW
insert into uptimes (date_stamp, one_min, five_min, fifteen_min) values (sysdate, $UPTIMES);
HOST ls -o uptimes.sh
--#file2.sql
select * from uptimes;
HOST du -sh .
exit
xxENDxx
date
Invoking the above gives this:
oracle. (/home/oracle/sql)
Linux> ./uptimes.sh mark.stewart
Enter Your password for Oracle instance ecs03 for user mark.stewart: xxxx
SQL*Plus: Release 12.1.0.2.0 Production on Thu Mar 17 20:09:36 2016
Dev:#> Connected.
Dev:MARK.STEWART#ecs03> Dev:MARK.STEWART#ecs03>
1 row created.
Dev:MARK.STEWART#ecs03> -rwxr-xr-x. 1 oracle 548 Mar 17 20:09 uptimes.sh
Dev:MARK.STEWART#ecs03> Dev:MARK.STEWART#ecs03>
DATE_STAM ONE_MIN FIVE_MIN FIFTEEN_MIN
--------- ---------- ---------- -----------
17-MAR-16 0 .01 .05
17-MAR-16 0 .01 .05
17-MAR-16 0 .01 .05
Dev:MARK.STEWART#ecs03> 146M .
Dev:MARK.STEWART#ecs03> Disconnected from Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options
Thu Mar 17 20:09:36 CET 2016
oracle. (/home/oracle/sql)
Linux>

RSnapshot reports errors using rsnapreport.pl: "NO STATS DATA"

I configured RSnapshot on a WD My Book Live (2TB) and its working (at least that's what the logs say). I used the reporting tool rsnapreport.pl from /usr/share/doc/rsnapshot/examples/utils/rsnapreport.pl.gz to get human readable mail reports about the crontab triggered backup jobs.
While the backup jobs seem to work, the reports are a obviously missing information as you can see in this snipplet:
SOURCE TOTAL FILES FILES TRANS TOTAL MB MB TRANS LIST GEN TIME FILE XFER TIME
--------------------------------------------------------------------------------------------------------------------
rsync://server:/vmail 13950 137 3687.81 20.31 0.052 seconds 0.000 seconds
ERRORS
/shares/rsnapshot/daily.0/ NO STATS DATA
The Question now is:
Beside the error at the bottom, which is my first and major problem and question, the FILE XFER TIME is also 0 for all backup jobs (I guess that the issues correlate).
I followed all instructions (see below) - what am I missing?
So what did I do so far:
*) The NAS runs Debian Squeeze (incl. squeeze-backports), Kernel Version is 2.6.32, PPC Architecture.
*) rsync version 3.0.3-2 (preinstalled), with /etc/rsyncd.conf:
pid file=/var/run/rsyncd.pid
lock file=/var/run/rsync.lock
log file=/var/log/rsync.log
[rsync]
path=/shares/rsync
uid=root
gid=share
read only=no
list=yes
auth users=root
*) Installed rsnapshot 1.3.1-1 with /etc/rsnapshot.conf:
config_version 1.2
snapshot_root /shares/rsnapshot/
cmd_rm /bin/rm
cmd_rsync /usr/bin/rsync
cmd_logger /usr/bin/logger
interval daily 7
interval weekly 4
interval monthly 3
verbose 3
loglevel 3
logfile /var/log/rsnapshot.log
lockfile /var/run/rsnapshot.pid
rsync_long_args --delete --numeric-ids --relative --delete-excluded --stats
backup rsync://server:/vmail/ backupOfServer/vmail/
backup ...
backup ...
backup ...
*) unpacked the report script and followed instructions in the script (most of which you can see in the config above):
# this script prints a pretty report from rsnapshot output
# in the rsnapshot.conf you must set
# verbose >= 3
# and add --stats to rsync_long_args
# then setup crontab 'rsnapshot daily 2>&1 | rsnapreport.pl | mail -s"SUBJECT" backupadm#adm.com
# don't forget the 2>&1 or your errors will be lost to stderr
*) and set up cron.d/rsnapshot:
MAILTO="user1#foo,user2#foo"
30 3 * * * root /usr/bin/rsnapshot daily 2>&1 | /root/rsnapreport.pl
0 3 * * 1 root /usr/bin/rsnapshot weekly 2>&1 | /root/rsnapreport.pl
30 2 1 * * root /usr/bin/rsnapshot monthly 2>&1 | /root/rsnapreport.pl
If you need any detailed or additional information, don't hesitate. We are happy to have daily reports of the backup at all, just the errors at the bottom are making us nervous.
Best Regards and thanks in advance,
Peter
The reason for this error was, that I did not uncomment the cmd_cp parameter. RSnapshot therefore used its build-in copy mechanism, which uses rsync.
This call of rsync was echoed to the output. The report script scans the output for calls to rsync and looks for transfer statistics, but the initial "copy" command does not produce such stats - therefore the error saying "NO STATS" for the source /daily.0
The solution is, to read the configuration file and follow the instructions:
# LINUX USERS: Be sure to uncomment "cmd_cp". This gives you extra features.
# EVERYONE ELSE: Leave "cmd_cp" commented out for compatibility.
#
# See the README file or the man page for more details.
#
#cmd_cp /bin/cp
Uncommenting the last line fixes the error... RTFM ;)
The "NO STATS DATA" error is also reported if you miss out on the:
rsync_long_args --stats
The "NO STATS DATA" error is also reported if you backing up something containing "rsync" in its path like /etc/default/rsync.
For example in this case the command rsnapshot daily 2>&1 | /bu/script/rsnapreport.pl | mail -s "[BU Report]date" me#example.com will return the following errors:
Use of uninitialized value $source in hash element at
/bu/script/rsnapreport.pl line 95, <> line 3991. Use of uninitialized
value $source in hash element at /bu/script/rsnapreport.pl line 96, <>
line 3991. ...
This is due to the rsnapreport.pl script which parse stats info from the rsync outpout and from the "rsync" string in it.
To simply resolve this problem add in your /etc/rsnapshot.conf the line corresponding to the problematic rsync string found in the rsync outpout:
For example and if you don't need to backup etc/default/rsync:
exclude etc/default/rsync
If you need to backup the files with path containing "rsync" you have to modify the rsnapreport.pl script.

Resources