Including pipe running Oracle sql from DOS batch script - oracle

We use the approach below to run SQL from a DOS batch script.
The model works fine but this specific code doesn't work. I believe because of the || characters. I tried using ^|^| but this didn't work.
Any ideas?
(
echo update mytable set file_path = 'C' || substr(file_path, 2);
echo commit;
echo exit
) | sqlplus x/x#orcl

Store the SQL as file and redirect SQL Plus's input:
sqlplus x/x#orcl <sql.txt

You can use CONCAT instead of the || operator

Escaping the || with ^|^| leaves you with yet another problem: cmd.exe thinks that the closing parenthesis of substr(file_path, 2); belongs to the opening parenthesis in the first line. It is therefore not printed to SQL*Plus, thus rendering the update statement to something like update mytable set file_path = 'C' || substr(file_path, 2 which obviously cannot be interpreted by Oracle.
You can solve this if you put the entire update statement into double quotes and feed this to (yet another) cmd.exe, like so:
(
#echo select * from mytable;
#cmd /c "echo update mytable set file_path = 'C' ^|^| substr (file_path, 2);"
#echo commit;
#echo exit
) | sqlplus x/x#orcl

Related

How to print only the output of dbms_out from a sqlplus script launched from powershell

myscript.sql:
set serveroutput on
set feedback off
set heading off
set echo off
DECLARE
CURSOR c1 IS
select 2 from dual
BEGIN
FOR i IN c1
LOOP
DBMS_OUTPUT.put_line (i.object_text );
END LOOP;
END;
/
exit;
I call my script with that:
sqlplus user/pass#database #Dpath\myscript.sql -S | Out-String | echo
SQL*Plus Version..........is always printed in the beginning. I don't want it.
the lines of my query are printed. that is OK.
Disconnected .... from Oracle Database is always printeed in the end. I don't want it
This code is just a reproductible example.I know that for the particular case, there is other way to do that. But what I want is to print just the dbms_out
You can just use SPOOL to create a separate file, where you will have full control of what is printed. You can also use a combination of the options SET FEEDBACK OFF, SET HEAD OFF and SET VERIFY OFF to remove the number of rows received, column names etc. so that your file looks more like an actual report instead of redirected output.
set serveroutput on
set feedback off
set heading off
set echo off
DECLARE
CURSOR c1 IS
select 2 as object_text from dual;
BEGIN
FOR i IN c1
LOOP
DBMS_OUTPUT.put_line (i.object_text );
END LOOP;
END;
/
EXIT;
PS C:\otr> sqlplus -s user/password#dev19 #c:\otr\file1.sql -S | Out-String | echo
2

How to get plain formatted output in csv with shell script for oracle sql query

This is my shell script.
echo "Start";echo #/opt/apps/Tests/SQLDir/Test1.sql | sqlplus Db1/Db1#//maydomain:port/abc;echo "Finish";
echo "Start";echo #/opt/apps/Tests/SQLDir/Test2.sql | sqlplus Db1/Db1#//maydomain:port/abc;echo "Finish";
I have 30 .sql files like this, added in one .sh file which results 30 .csv files
Test1.sql has
SPOOL /opt/apps/Tests/OF/output1.csv REPLACE;
select name from username where id = 10 and Sname is not NULL and ROWNUM < = 50000;
Test2.sql has
SPOOL /opt/apps/Tests/OF/output2.csv REPLACE;
select strname,ctyname from addr where city = 'NYC' and ROWNUM < = 50000;
My expected OP in output1.csv is
name
Abc
xyz
pqr
My expected OP in output2.csv is
strname | ctyname
10-AP NYC
11-KP MCH
90-ZP SDK
right now I am getting weird o/p in csv
name
-------------------------------
Abc
xyz
pqr
name
-------------------------------
TYU
KLH
50000 rows selected.
SQL>
So is there any way to remove those additional lines [--------- and 50000 rows selected.] with shell script/sql code?
And while executing shell script all sql result rows are getting printed on screen. how to avoid that?
Thanks in advance.
Following SQL*Plus command should do the job:
set markup csv on delimiter ' ' quote off
set feedback off
I must say, your method of passing the name of a script to sqlplus is the strangest I've ever seen. The usual practice (given your names) would be:
sqlplus Db1/Db1#//maydomain:port/abc #/opt/apps/Tests/SQLDir/Test1.sql
I don't see where your 'echo Start' and 'echo finished' accomplish anything, since there is no clarifying info coming along with it.
It looks to me like what you want in your scripts would be
set echo off trimsp on head off pagesize 0
spool /opt/apps/Tests/OF/output2.csv replace
select strname,ctyname from addr where city = 'NYC' and ROWNUM < = 50000;
spool off
BTW, 'spool' is a sqlplus command - a directive to sqlplus itself, not a sql statement. As such, it does not need a semi-colon at the end.
-- edit
Example of using environment variables on sqlplus command line:
username=scott
userpw=tiger
server=myserver
port=1521
dbname=mydb
sqlplus $username/$userpw#//$server:$port/$dbname
Though I would question why you need to set them as variables.
And I prefer to use tnsnames rather than ezconnect.

batch file to store the psql query output into a variable

Hi I am creating a batch file to execute a query and write a log file for the output. So based on some condition the there two queries to be executed.
So I was trying to store a output value of a query in to a variable and use that variable value to check the condition.
But here I am facing a problem that how should I suppose to declare and store output value into a variable using psql command.
Please help!!
Here what I tried:
SET /A a = psql -t -U postgres -d rpd -c "select count(*) from rpd.rpm_rpd_count"
SET /A b = 1
if %a% == 3 goto is_stat
else goto is_start
REM to copy the log
:is_start
psql -U postgres -d rpd -c "SELECT
a.table_name , 'MATCH' status FROM rpd.rpm_rpd_count A WHERE
a.rpd_count = a.rpm_count UNION ALL SELECT a.table_name, 'NOT MATCH'
AS status FROM rpd.rpm_rpd_count A WHERE a.rpd_count <> a.rpm_count;" >> C:\Users\admin\Desktop\err.log
goto END
:is_stat
psql -U postgres -d rpd -c "SELECT a.table_name , 'MATCH'
status FROM rpd.rpm_rpd_count A WHERE a.rpd_count = a.rpm_count;" >>
C:\Users\admin\Desktop\err.log
goto END
:END
echo %b% >> C:\Users\admin\Desktop\err.log
Problem here is that nothing is getting saved in the variable a
You can use a for loop to parse the output
for /f %%i in ('psql -t -U postgres -d rpd -c "select count(*) from rpd.rpm_rpd_count"') do set A=%%i
(use a single % if you try it in the command line console, and double %% in a batch file)

How to capture the output of a PL SQL function in a powershell variable?

I am able to connecting to remote oracle database using powershell and sqlplus. Also I am able to capture the output of the command/query executed in the database into a powershell variable.
PFB example.
$username ="hr"
$password ="hr"
$tnsalias ="orcl"
$outputfilepath="C:\Users\Desktop"
$sqlquery=#"
set serveroutput off
set feedback off
set heading off
set echo off
select sysdate from dual;
"#
Running the above query in oracle database as below
$xval=$sqlquery | sqlplus -silent $username/$password#$tnsalias
echo $xval
The output will be
23-APR-18
The problem is when I am running a PL SQL function as below.
$sqlquery=#"
set serveroutput off
set feedback off
set heading off
set echo off
declare
x varchar2:=null;
exec x:=MYTEST_FUN('a','b');
"#
There is no value captured in the $xval variable and also the function is not running.
How to execute the function such that the return value of the function is captured in a powershell variable.
One way is to make it set serveroutput on and use DBMS_OUTPUT.PUT_LINE() within BEGIN..END
Another option is to use the sqlplus' PRINT command.
set serveroutput off
set feedback off
set heading off
set echo off
variable x VARCHAR2 --declare bind variable x
exec :x := MYTEST_FUN('a','b'); --a colon before x needed.
PRINT x;
Worked for me:
$sqlQuery = #"
set serveroutput off
set feedback off
set heading off
set echo off
variable x NUMBER;
select count(*) into :x from TABLE;
PRINT x;
exit
"#
($sqlQuery | sqlplus -S user/pass | Write-Output | Out-String).Trim()
Late entry, most concisely:
$dateVar = ("set heading off
select sysdate from dual;" | sqlplus -s $yourConnectionString | Out-String).Trim()

Variable won't resolve inside PL-SQL statement

I am trying to pass a SQL command to the SQL*Plus command-line program (Oracle) in my KornShell (ksh) script, but my $MY_VAR variable seems to be failing to resolve. $MY_VAR is a string value.
sqlplus -s << EOF >> $LOG_FILE
$MY_SCHEMA
UPDATE my_table SET run_flag = 'I', start_time = to_char(sysdate, 'DD-Mon-YYYY HH24:MI:SS') WHERE (process_id = '$MY_VAR' AND run_flag != 'F');
COMMIT;
EOF
I can successfully echo out the $MY_VAR variable, and so I can see that the variable is populated, but it does not seem to be resolving when inserting the variable into the SQL command which I am providing as an argument to the SQL*Plus program. The log file for the script simply outputs:
0 rows updated. Commit complete.
The SQL seems to be valid as we can successfully execute the command in SQL Developer (albeit with a hardcoded value for $MY_VAR).
Any ideas on what I am missing here?
Thank you
Try this:
sql="$MY_SCHEMA
UPDATE my_table SET run_flag = 'I', start_time = to_char(sysdate, 'DD-Mon-YYYY HH24:MI:SS') WHERE (process_id = '$MY_VAR' AND run_flag != 'F');
COMMIT;"
print "$sql"
sqlplus -s <<<"$sql" >> $LOG_FILE
Does the sql look correct? If it does and zero rows are updated, your where clause must be selecting zero rows.
Your version of ksh may not have the <<< here-string syntax. In that case:
print "$sql" | sqlplus -s >> $LOG_FILE

Resources