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

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

Related

create db if not exists in postgres .sh file

I want to execute these lines in the below .sh file:
#!/bin/sh +x
sudo su postgres
psql -U postgres -tc "SELECT 1 FROM pg_database WHERE datname = 'test_db'" | grep -q 1 || psql -U postgres -c "CREATE DATABASE test_db"
But only 'sudo su postgres' is executing and the 2nd line is not executing. Can someone help me execute those 2 lines
Just pass your psql command to su:
sudo su postgres -c "psql -U postgres -tc \"SELECT 1 FROM pg_database WHERE datname = 'test_db'\" | \
grep -q 1 || psql -U postgres -c \"CREATE DATABASE test_db\""
If you want to pass the datname value as a parameter, replace it by $1 in the script ($1, $2, etc. expand as the first, second, etc. parameters you pass to your script):
sudo su postgres -c "psql -U postgres -tc \"SELECT 1 FROM pg_database WHERE datname = '$1'\" | \
grep -q 1 || psql -U postgres -c \"CREATE DATABASE $1\""
and call your script like this:
./script.sh test_db
You can even have optional parameters. For instance, if you want an optional parameter for the table name (pg_database in your example):
db=pg_database
if [ -n "$2" ]; then db="$2"; fi
sudo su postgres -c "psql -U postgres -tc \"SELECT 1 FROM $db WHERE datname = '$1'\" | \
grep -q 1 || psql -U postgres -c \"CREATE DATABASE $1\""
and call your script like this:
./script.sh test_db
to use the default, else:
./script.sh test_db other_pg_database
I suggest you update your sudo configuration so you can directly express that you only need to as postgres and not root:
sudo -u postgres ...
For example:
user host = (postgres) command
where user is your user, host is the host name you want this apply (ALL?), and command is the name of your command (ALL?) possible prefixed with "NOPASSWD: " if you don't want to require a password.
Then do the action and deal with the error if needed instead of guarding against it:
sudo -u postgres bash -c "psql -U postgres -c "CREATE DATABASE $1"
Possible single quoting the $1 and if you want that to be robust, escape any single quotes in the database name. I showed you a shell (bash) in the above, so can easily tag on error handling.

How to create and call a variable for PostgresSQL/psql connections within batch file?

I have a single batch file that runs various psql and ogr2ogr (spatial/GIS) commands within PostgreSQL databases. I run identical commands across two identical databases (dev & test). I'd like to store my PostreSQL connection info in a single variable and call it to run my psql commands. That way I can simply comment out the connection (dev or test) which I'm not currently using.
The reason I'm using this workflow is because I also run ogr2ogr commands in the same script, which successfully uses a simply batch variable.
Scenario 1: Manually update connections. This works but is tedious to update
::Run commands in DEV Server/DB
psql U UserName -h 99.99.999.999 -d MyDB -c "some sql command1"
ogr2ogr command 1
psql U UserName -h 99.99.999.999 -d MyDB -c "some sql command2"
psql U UserName -h 99.99.999.999 -d MyDB -c "some sql command3"
::Run commands in TEST Server/DB
psql U UserName -h 88.88.888.888 -d MyDB -c "some sql command1"
ogr2ogr command 1
psql U UserName -h 88.88.888.888 -d MyDB -c "some sql command2"
psql U UserName -h 88.88.888.888 -d MyDB -c "some sql command3"
Scenarios 2: I would like to set DB connections in 1 one place. Then I can run all commands and switch between DBs by simply commenting out 1 line and re-running the batch.
\SET dbConnect "-U UserName -h 99.99.999.999 -d MyDevDB"
::\SET dbConnect "-U UserName -h 88.88.888.888 -d MyTestDB"
psql dbConnect -c "some sql command1"
ogr2ogr command 1
psql dbConnect -c "some sql command2"
psql dbConnect -c "some sql command3"
I've tried several options include the -v, set, and /set to no avail. I've researched these cases below, but am still struggling. Ideally I'd like to store and call the variables in one location, in one file.
psql passed variable
How do I specify a password to psql non-interactively?
PostgreSQL Connection URL

How to in insert into a specific schema in postgres using psql pipe command

I have using psql pipe command to copy a table from one database to another in Postgres. It is working fine. But I need to copy the table to a specific schema in the new database. I have gone through the documentation (used -n option for specifying schema name) but it is not working.
Command:
pg_dump -U postgres -h localhost -p 1212 -d dbname -t tablename -Ft | pg_restore -U postgres -h localhost -p 1213 -d dbname -n schemaname
you can't do it with pg_dump|pg_restore sequence. you need to alter table t set schema s; in restored db
I do it that this way:
pg_dump -U postgres -h localhost -p 1212 -d dbname -t tablename | sed "sed/oldschemaname/newschemaname/" | psql -U postgres -h localhost -p 1213 -d dbname -n schemaname
With the corresponding regular expression

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 --------------------^-------------------------------------------------------^

error syntax ( execute psql query from shell script )

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)