error syntax ( execute psql query from shell script ) - postgresql

i got this query want to to be executed remotely on my 2nd server and
#!/bin/bash
QUERY=`psql -h my2ndserverip -d testdb -U testuser 'select count(*) as result
from testdb.user where last_logged_date > (clock_timestamp() -interval '90 minutes)
echo "users = $QUERY" > tmp.txt
any tips to fix syntax ?

Use a here document (heredocuments preserve quotes AND allow shell-variable subtitution, as illustrated by the parameter 90 which is used inside single quotes):
#!/bin/bash
limit=${1:-90}
psql -h my2ndserverip -d testdb -U testuser -t -A <<EOFEOF > tmp.txt
SELECT count(*) AS result
FROM "user"
WHERE last_logged_date > clock_timestamp()-interval '${limit} minutes'
;
EOFEOF
exitcode=$?
result=`cat tmp.txt`
echo "Limit=${limit} Exitcode=${exitcode} Result=${result}"
#Eof
I suppose you want psql to omit the column headers etc, so I added the -t -A flags to the psql commandline.
BTW I changed from testdb.user, to FROM user, I don't think you have a schema named 'testdb'.

there are more than one issue
instead quotes in SQL query, you can use $$
postgres=# select interval $$90 min$$;
interval
──────────
01:30:00
(1 row)

Related

How to add double quotes in table names using postgresql query?

i have migrated the table and schema from oracle to postgresql. schema name and table name both contains double quotes. How to select the table name in the specific schema using psql command i.e
psql -U enterprisedb -d test -c "select count(*) from "HISTORY"."EMP";"
I have tried the following methods:-
psql -U enterprisedb -d test -c "select count(*) from "HISTORY"."EMP";"
psql -U enterprisedb -d test -c "select count(*) from "||HISTORY||"."||EMP||";"
psql -U enterprisedb -d test -c "select count(*) from ""HISTORY"".""EMP"";"
Below are the codes which i have tried:-
psql -U enterprisedb -d test -c "select count(*) from "HISTORY"."EMP";"
psql -U enterprisedb -d test -c "select count(*) from "||HISTORY||"."||EMP||";"
psql -U enterprisedb -d test -c "select count(*) from ""HISTORY"".""EMP"";"
i want psql command to fetch the data .when i am using double quotes its coudln't find the table . How to use the double quotes in the psql command.
I can fetch the data while login to the server the select queries works. but i want to use psql command to work and fetch details.
You could use a here document, which preserves all quotes:
#!/bin/sh
psql -U enterprisedb -d test <<ZZZZ
select count(*) from "HISTORY"."EMP"
;
ZZZZ

How to escape single quote in postgres query via ansible

I am able to execute simple select/delete queries of postgres via ansible playbook. But if my query contains some single quote, it fails. How can I escape a single quote?
Example
This runs fine:
command: psql -U dbuser dbname -c 'SELECT count(*) from table;'
I want to run this:
command: psql -U dbuser dbname -c 'SELECT count(*) from table where time <= '01-sep-2016';'
But this is giving me errors.
Not sure how it would work out in ansible playbook, but there is usually 3 ways to deal with this:
use doublequotes around the query
command: psql -U dbuser dbname -c "SELECT count(*) from table where time <= '01-sep-2016';"
use backslash:
command: psql -U dbuser dbname -c 'SELECT count(*) from table where time <= \'01-sep-2016\';'
use quotes twice in a row:
command: psql -U dbuser dbname -c 'SELECT count(*) from table where time <= ''01-sep-2016'';'
You could just use double quotes in the shell and single quotes inside the SQL:
$ psql -U dbuser dbname -c "SELECT count(*) from table where time <= '01-sep-2016';"
# Here --------------------^-------------------------------------------------------^

How to return a value from psql to bash and use it?

Suppose I created a sequence in postgresql:
CREATE SEQUENCE my_seq;
I store the below line in an sql file get_seq.sql
SELECT last_value FROM my_seq;
$SUDO psql -q -d database_bame -f get_seq.sql
How do I get the int number returned by SELECT into bash and use it?
You can capture the result of a command using the VAR=$(command) syntax:
VALUE=$(psql -qtAX -d database_name -f get_seq.sql)
echo $VALUE
The required psql options mean:
-t only tuple
-A output not unaligned
-q quiet
-X Don't run .psqlrc file
Try:
LAST_VALUE=`echo "SELECT last_value FROM my_seq;" | psql -qAt -d database_name`

Using shell script store PostgreSQL query on a variable

I want to store following postgreSQL query result in a variable. I am writing command on the shell script.
psql -p $port -c "select pg_relation_size ('tableName')" postgres
I need variable to save the result on a file. I have tried following but it is not working
var= 'psql -p $port -c "select pg_relation_size ('tableName')" '
Use a shell HERE document like:
#!/bin/sh
COUNT=`psql -A -t -q -U username mydb << THE_END
SELECT count (DISTINCT topic_id) AS the_count
FROM react
THE_END`
echo COUNT=${COUNT}
The whole psql <<the_end ... stuff here ... the_end statement is packed into backticks
the output of the execution of the statement inside the backticks is used as a value for the COUNT shell variable
The -A -t -q are needed to suppress column headers and error output
inside a here document, shell variable substitution works, even in single quotes!
So, you could even do:
#!/bin/sh
DB_NAME="my_db"
USR_NAME="my_name"
TBL_NAME="my_table"
COL_NAME="my_column"
COUNT=`psql -A -t -q -U ${USR_NAME} ${DB_NAME} << THE_END
SELECT COUNT(DISTINCT ${COL_NAME} ) AS the_count
FROM ${TBL_NAME}
THE_END`
echo COUNT=${COUNT}
to run a query inline you have to wrap it in grave accents, not single quotes:
$ vim `which fancyexecfileinpath`
psql lets you run queries from command line, but I guess you should be inputting complete information. you might be missing the database name.
postgres#slovenia:~$ psql -d mydbname -c "select * from applications_application;"
postgres#slovenia:~$ specialvar=`psql -d flango -c "select * from applications_application;"`
postgres#slovenia:~$ echo $specialvar
id | name | entities | folder | def_lang_id | ... | 2013-07-09 15:16:57.33656+02 | /img/app3.png (1 row)
postgres#slovenia:~$
notice the grave accents when assigning it to specialvar
otherwise you'll be setting it to a string.
There shouldn't be any space between the variable and the equals sign ("=") and the value ( http://genepath.med.harvard.edu/mw/Bash:HOW_TO:_Set_an_environment_variable_in_the_bash_shell )

Store PostgreSQL query result to Shell or PostgreSQL variable

For instance, I have a table stores value:
select * from myvalue;
val
-------
12345
(1 row)
How can I save this 12345 into a variable in postgresql or shell script?
Here's what I tried in my shell script:
var=$(psql -h host -U user -d db <<SQLSTMT
SELECT * FROM myvalue;
SQLSTMT)
but echo $var gives me:
val ------- 12345 (1 row)
I've also tried
\set var (select * from myvalue)
in psql and when I type \set it lists:
var = '(select*frommyvalue)'
No, no, no! Use "raw data" switch from psql, like "-t" or "\t" and pipe the query to psql instead of parsing ascii-table, come on :-)
echo 'select * from myvalue;' | psql -t -h host -U user -d db
If you really need parse psql output, you could also use -H switch ( turns on HTML output ), and parse it with some perl module for parsing html tables, I used that once or twice.. Also, you may want to use a pgpass file and ~/.psqlrc for some defaults, like default DB to connect, when not specified.
psql has a -c/--command= option to accept SQL from the command line, and -t/--tuples-only option to control output formatting.
$ psql -c 'select 1+1'
?column?
----------
2
(1 row)
$ psql -t -c 'select 1+1'
2
$ VALUE=`psql -t -c 'select 1+1'`
$ echo $VALUE
2
var=`psql -Atc "select 1;"`
echo $var
1
In this answer I explain one way to do it, using a co-process to communicate back-and-forth with psql. That's overkill if all you need is to run a query and get a single result, but might be good to know if you're shell scripting with psql.
You can filter the result you get with your psql command:
var=$(psql -h host -U user -d db <<SQLSTMT
SELECT * FROM myvalue;
SQLSTMT)
var=$(cut -d' ' -f3 <<<$var)
None of these worked for me, but this did:
median_avm=psql "host=${dps1000} port=#### dbname=### user=${reduser} password=${redpass}" -c "SELECT AVG(column) FROM db.table;" -t
using a source file with ${dps1000}, ${reduser}, ${redpass} defined and manually entering port and dbname