set escape on then issue host command in SQL*Plus - oracle

The command set escape on would enable the escape character.
SQL> select '\&' from dual;
'
-
&
SQL>
But when issue a host command, I can't understand the behavior.
SQL> host echo foobar aa
foobar aa
SQL> show escape
escape "\" (hex 5c)
SQL> host echo foobar \&
foobar
SQL> host echo foobar '\&'
foobar &
SQL>
Why does using '\&' instead of just \& change the output?

& is a substitution character
The & is translated as this and is just waiting for more (translated into nothing).
SQL> host echo &
SP2-0317: expected symbol name is missing
SQL> host echo 1
1
<- One line returns
SQL> host echo \&
<- two lines return
SQL> host echo 1 & 2
Enter value for 2: 3
1 3

Related

sqlplus removes extra whitespace

I have a below test ksh file
#!/bin/ksh
(
sqlplus -s << EOF
${DATABASE}
SET SERVEROUTPUT ON;
SET HEAD OFF
SET FEED OFF
SET DEFINE OFF
SET PAGES 0
SET COLSEP ";"
WHENEVER SQLERROR EXIT SQL.SQLCODE
SELECT 'aaaa vvvv cccc' FROM DUAL;
EXIT
EOF
) | while read sql_out
do
echo ${sql_out}
done
The expected output is
aaaa vvvv cccc
however the output observed is
aaaa vvvv cccc
Sqlplus is stripping out extra white spaces from my output and I want to preserve it.
It isn't SQL*Plus doing that, it's the shell. You need to enclose your variable in quotes:
To preserve whitespace within a string or in a variable, use quoting.
So instead of
echo ${sql_out}
do either of these:
echo "${sql_out}"
printf "%s\n" "${sql_out}"
and the output will then be:
aaaa vvvv cccc

delete rows from databse using a shell script

the below script gives me an error. Basically I am trying to delete the records that I got from the first query. I have put them in a text file, formatted them and used them in the delete operation.
After executing the script I am getting the below error:-
: line 5: syntax error at line 27: `<<' unmatched
Can't tell because the code you dumped is unformatted, but my first guess would be you have leading spaces in front of the EOF in your here document.
This should work (note that there are no leading spaces in front of the EOF.:
sqlplus -s $dbcreds << EOF > output.txt
SET SERVEROUTPUT OFF
select empname from emp where dept_no=123;
EOF
if [ -s "output.txt" ]
then
echo " Found the below employees....Deleting them from Database ..............!!!! \n"
cat output.txt
sed "s/(.*)/'\1'/" output.txt| tr '\n' ','|sed 's/.$//' >final_employees.txt
while read line
do
sqlplus -s $dbcreds <<EOF
SET SERVEROUTPUT OFF
Delete from emp where empname in ($line);
EOF
done < final_employees.txt
else
echo " No employees found....!!!"
fi

Bash ending the variable after first space?

I'm building a string in Bash in a loop. The data processed by the loop from the lines in two files which are looking like this:
FIRST part of the string is a line in file 1 looking like:
SOME_PACKAGE
SECOND PART is a line of a file 2 looking like:
someFunction('some',parameters,here)
The final output has a dot between the two strings:
1 SOME_PACKAGE.someFunction('some',parameters,here)
The 1 is important here. Explaination in a second.
The string is formed in a double while loop
while read line1 ; do
while read line2 ; do
stringArray=($line2)
string=$line1.${stringArray[1]}
sqlplus -s /nolog > /dev/null 2>&1 <<EOF
connect user/password#db_instance
variable rc refcursor;
SPOOL ${line1}_${stringArray[0]}.DATA
exec :rc := $string;
print rc;
spool off
exit
EOF
done < file2.txt
done < file1.txt
This string is then passed to SQLPlus, and SQLPlus should exit a command like this:
SQL> variable rc refcursor;
SQL> exec :rc := SOME_PACKAGE.someFunction('some',parameters,here);
SQL> print rc;
Until now, everything was working fine. But I got a more complicated parameters next to the someFunction. Now it looks like this:
SOME_PACKAGE.someFunction('some',parameters,here,'and 2 more',NULL)
It seems that the variable passed to SQL*Plus ends on the first space... So it looks like:
SOME_PACKAGE.someFunction('some',parameters,here,'and
From what I know I shouldnt pass spaces in variables, or if I want to do this, I should wrap them in quote signs: "" but where should I put those quote signs to pass the final vatiable to SQL*Plus WITHOUT those quote signs? Or what other solution do You guys propose?
The answer was simple thanks to #arco444.
The reason all this happened was the Internal field separator, which was set to default.
What I did was the following:
I've changed the look of file2 from
1 SOME_PACKAGE.someFunction('some',parameters,here,'and 2 more',NULL)
to
1§SOME_PACKAGE.someFunction('some',parameters,here,'and 2 more',NULL)
And I added some ILS changes before and after the loop, so the final code looks like this:
oldifs=$IFS
IFS="§"
while read line1 ; do
while read line2 ; do
stringArray=($line2)
string=$line1.${stringArray[1]}
sqlplus -s /nolog > /dev/null 2>&1 <<EOF
connect user/password#db_instance
variable rc refcursor;
SPOOL ${line1}_${stringArray[0]}.DATA
exec :rc := $string;
print rc;
spool off
exit
EOF
done < file2.txt
done < file1.txt
IFS=$oldifs
Everything is working like a charm now.

line 45: syntax error: unexpected end of file

When I try running the script, I am gettin the error line 45: syntax error: unexpected end of file. I am relatively new to scripting. Please help me resolve it.
#!/bin/ksh
set -xv
export HOME=/home/mine
. $HOME/.env.ksh
BIS_SPOOL=/tmp/bis_table_mine.spl
BIS_REPORT_MINE=/tmp/bis_table_report_mine.txt
touch $BIS_SPOOL
rm $BIS_SPOOL
touch $BIS_SPOOL
exec 5< $BIS_REPORT_MINE
while read -u5 REC_MINE
do
TBLENAME=`echo "$REC_MINE" | awk '{print $3}' | tr '[:upper:]' '[:lower:]'`
sqlplus -s ${USER_ID}/${USER_PASS}#${ORACLE_SID} <<- EOF
set feedback off
set hea ON
set pagesize 9999
set linesize 9999
set trimspool ON
set termout off
spool $BIS_SPOOL append
Column C1 Heading 'Job Name' Format a30
Column C2 Heading 'Table Name' Format a30
SELECT job_name C1,
table_name C2,
FROM table_usage
WHERE table_name like 'TBLENAME%'
/
exit;
EOF
done
exec 5<& -
The <<- EOS is interpreted literally. Make it
sqlplus -s ${USER_ID}/${USER_PASS}#${ORACLE_SID} <<-EOF
without the space char.
Also make sure there is no space char before or after your closing EOS , but leading tab chars are allowed.
IHTH

ORACLE: need to export table data without spaces between columns

Say i have Table A with columns
col1 col2 col3 col4
-------------------
sajal singh 28 IND
hello how are you
I want to export the data into a flat file without spaces or tabs between columns
So the output should be
cat dump
sajalsingh28IND
hellohowareyou
what i have tried. i have written a script
#!/usr/bin/bash
#the file where sql output will go
OUT=report.txt
>$OUT
DESC=desc.txt
>$DESC
sqlplus -s "xxx/xxx#xxx" << END_SQL > /dev/null
set pages 0
set feedback off
set heading off
set trimspool off
set termout off
set verify off
set wrap off
SPOOL $DESC
Select * from table_name;
SPOOL OFF
END_SQL
But i am getting outputs of one row in multiple lines and with tabs/spaces
So question is how can i fix that? and
I found some data pump utilities like expdp. Can i use that in Unix? if yes, how can i acheive the dump in that format?
Thank You
If you already have a CSV dump, then you can run the following command:
awk 'BEGIN{FS=",";OFS=""}{$1=$1}1' csv.dump > new.dump
Untested:
SET HEADING OFF
SET FEEDBACK OFF
SPOOL $DESC
SELECT col1 ||''|| col2 ||''|| col3 FROM table_name;
SPOOL OFF;
From a "simplified oracle view" to "plain" characters with sed:
sed -n '3,$ s/\s//gp' file
$cat file
col1 col2 col3 col4
-------------------
sajal singh 28 IND
hello how are you
$sed -n '3,$ s/\s//gp' file
sajalsingh28IND
hellohowareyou
Explanation: replace all white space (not line breaks) from line 3 to EOF with "nothing".
If you want the columns padded out but no additional spaces between the columns you can do:
set colsep ""
The default is to have a single space between the double-quotes, which puts a single space between the columns. You might also want to do:
set tab off
... to ensure that multiple spaces in the padding isn't converted to tabs, which looks fine for display but would be a pain parsing the file.
If you want no spaces at all, to do this within SQL*Plus you'd need to concatenate the columns:
select col1 || col2 || col3 || col4 from table_name;
This is useful if you're putting a delimiter between the columns (e.g. making it a CSV), but I don't know what you'd be able to do with the data in the file if you squashed everything together without delimiters.
So this is what i came up with: it will dump oracle data without any spaces etc between columns, while preserving the spaces within data. I thought i would share it with you.
#!/usr/bin/bash
#the file where sql output will go
OUT=report.txt
>$OUT
DESC=desc.txt
>$DESC
TABLE_NAME=$1
###GET DESCRIBE####
s=""
#######################
sqlplus -s "xxx/xxx#xxx" << END_SQL > /dev/null
set pages 0
set feedback off
set heading off
set trimspool off
set termout off
set verify off
set wrap off
SPOOL $DESC
desc $TABLE_NAME;
SPOOL OFF
END_SQL
#######################
for i in `cat $DESC|awk -F" " '{print $1}'|grep -v -i name|grep -v -`
do
s=$s"trim($i)||'|'||"
done
s=`echo $s|sed "s/||'|'||$//g"`
echo $s
#######################
#sqlplus - silent mode
#redirect /dev/null so that output is not shown on terminal
sqlplus -s "xxx/xxx#xxx" << END_SQL > /dev/null
set pages 0
set feedback off
set heading off
set trimspool off
set termout off
set verify off
set colsep ""
set tab off
set lines 1500
SPOOL $OUT
select $s from $TABLE_NAME;
SPOOL OFF
END_SQL
#######################
cat $OUT|sed "s/|//g"|sed "s/ *$//g" >$OUT.new
mv $OUT.new $OUT
echo Finished writing report $OUT

Resources