batch file to store the psql query output into a variable - windows

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)

Related

Check if a role exists in PostgreSQL using psql

I need in a bash script a IF condition on the existence of a role in a PostgreSQL database. I have found solutions in SQL code [1, 2], but I need something I can use directly in bash, I assume with the help of psql. In [2] there are also psql solutions, but I don't manage to adapt it in a IF statement.
I have tried this unsuccessfully (I am a PostgreSQL and bash newbie):
psql_USER=my
if [ "$( psql -h db -U postgres --no-psqlrc --single-transaction --pset=pager=off --tuples-only --set=ON_ERROR_STOP=1 -tc "SELECT 1 FROM pg_user WHERE usename = $psql_USER" | grep -q 1 )" == '1' ] > /dev/null 2> /dev/null; then
echo "HOURRA !"
fi;
Result is:
Password for user postgres:
ERROR: column « my » does not exist
LINE 1: SELECT 1 FROM pg_user WHERE usename = my
^
I would avoid the quoting problem like this:
if psql -Atq -c "SELECT '#' || usename || '#' FROM pg_user" | grep -q '#'"$psql_USER"'#'
then
echo yes
fi
The psql invocation selects a list of all usernames, prefixed and suffixed with #. The grep has return code 0 if psql_USER contains one of these user names, else 1. The then branch of if is only taken if the return code of the pipeline is 0, that is, if the user exists in the database.

Sqlplus script part showing "Badly placed ()'s." error

I'm writing a script and have a problem when trying to get a date from the table. I'm having problem storing it into a variable. I always get the error:
Badly placed ()'s.
The variable TIMEFRAME is "D" and the shell actually gets into the IF, also the password is also not the problem as I use it to connect manually and check the query (no problems here).
This is the part of the script where I'm having problems.
#!/bin/csh -f
if ( $TIMEFRAME == "D" ) then
set TIMEBEG = `sqlplus -s $PASSWORD << EOF \
set head off; \
set feed off; \
select to_char(trunc(sysdate) - 1,'YYYYMMDD') from dual; \
exit; \
EOF`
set TIMEEND = $TIMEBEG"235959"
set TIMEBEG = $TIMEBEG"000000"
endif
I also tried to store it on a file, same problem
#!/bin/csh -f
set tmp_file=/tmp/tmp.$$
if ( $TIMEFRAME == "D" ) then
sqlplus -s $PASSWORD > $tmp_file << EOF \
set head off \
set feed off \
select to_char(trunc(sysdate) - 1,'YYYYMMDD') from dual; \
exit; \
EOF
set TIMEBEG=`cat $tmp_file`
set TIMEEND = $TIMEBEG"235959"
set TIMEBEG = $TIMEBEG"000000"
endif
I tried different solutions but with the same problem, tried without semi-colons, without the SETs, to put it on a single line, I'm out of Ideas.
When trying with -xvf this is what I get when I get into the part:
if ( $TIMEFRAME == "D" ) then
if ( D == D ) then
sqlplus -s $PASSWORD > $tmp_file << EOF set head off set feed off select to_char ( trunc ( sysdate ) - 1,'YYYYMMDD' ) from dual ; exit ; EOF
Badly placed ()'s.
Any ideas? This is running on Amazon Linux
I'm not sure you can use a here-doc inside backticks in C shell.
Write the sqlplus input to a file, rather than writing the whole sqlplus command.
#!/bin/csh -f
set tmp_file=/tmp/tmp.$$
if ( $TIMEFRAME == "D" ) then
cat > $tmp_file <<EOF
set head off
set feed off
select to_char(trunc(sysdate) - 1, 'YYYYMMDD') from dual;
exit;
EOF
set TIMEBEG = `sqlplus -s $PASSWORD < $tmp_file`
set TIMEEND = $TIMEBEG"235959"
set TIMEBEG = $TIMEBEG"000000"
endif

Check if a PostgresSQL DB Exists with Batch File and Output Custom Values to a Text File

Basically I am trying to check if a certain PostgreSQL DB exists with a batch file from the CMD in Windows. Then output custom results onto a text file within the same location, the text file will contain custom values. But the batch I created keeps giving me this (below), does not create the file and instead outputs this on the cmd:
SET _chk_DB=server
was unexpected at this time.
And I would like to know where I went wrong.
I am a beginner with batch so please do take that into consideration.
SET _chk_DB=server
FOR /F "usebackq" %%S IN (psql.exe -h %_svr% -d %_db% -U %_usr%
-P %_psw%
-Q "set nocount on; select count(*) from dbo.sysdatabases where
[name]='%_dtb%'") DO ( SET _chk_DB=%%S )
IF [%_chk_DB%]==[server]
"1" >> Info.text
else
echo "0" >> Info.txt
IF [%_chk_DB%]==[login]
"1" >> Info.text
else
echo "0" >> Info.txt
IF [%_chk_DB%]==[0]
"1" >> Info.text
else
echo "0" >> Info.txt

How to fetch more than one column value from oracle select query to shell variable

I am trying to fetch a row with more than one column value to different shell variables. Infact I found that at a time all the column values can be stored to single shell variable. But how can I put those column values to seperate shell variables. Below is an example I am trying for time being
function sqlQuery {
sqlplus -S shiyas/********* <<'EOF'
set heading OFF termout ON trimout ON feedback OFF
set pagesize 0
SELECT name,open_mode from v$database;
EOF
}
OUTPUT="$( sqlQuery )"
echo $OUTPUT
Here I am getting the output as
ORCL READ WRITE
But my requirement is column values ORCL, READ WRITE should get assigned to different shell variable.
I tried the below of parsing.
echo "$OUTPUT" | while read name open_mode
but it was throwing unexpected end of file error.
-bash-3.2$ sh call_sql_col_val_1.sh
ORCL READ WRITE
call_sql_col_val_1.sh: line 18: syntax error: unexpected end of file
Please let me know what concept I can use to fetch a single row column values to different shell variables.
I do this via eval myself:
oracle#******:/*****> cat test.sh
#!/bin/bash
function sqlQuery {
sqlplus -S / as sysdba <<'EOF'
set heading OFF termout ON trimout ON feedback OFF
set pagesize 0
SELECT name,open_mode from v$database;
EOF
}
eval x=(`sqlQuery`)
NAME=${x[0]}
OPEN_MODE="${x[1]} ${x[2]}"
echo NAME IS $NAME
echo OPEN_MODE IS $OPEN_MODE
So we are running the same function you have above, passing it into x and running it through eval to handle the delimitation. Then you have an array and call call is as such: x[0] for the first item, for example.
Output is:
oracle#******:/******> sh test.sh
NAME IS ******
OPEN_MODE IS READ WRITE

Including pipe running Oracle sql from DOS batch script

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

Resources