Pass command line args to sql (Postgres) - postgresql

How can I pass command line args to sql files ran with psql (Postgres)?
i.e.
psql mydatabase < mysqlfile.sql arg1 arg2 arg3...
Is this possible?

Use variable interpolation feature in psql.
If you specify -v variable1=value1 or --set variable1=value1 parameter on command line, then :variable1 in the sql file will be replaced with corresponding text value.
Note: use standard-SQL quoted strings if you need quotes, spaces and so on.
Example:
echo "SELECT :arg1 FROM :arg2 LIMIT 10;" > script.sql
psql mydatabase -v arg1=relname -v arg2=pg_class < script.sql
psql mydatabase -v arg1="'some string' as label" -v arg2=pg_namespace < script.sql

Related

How to format result when query is executed from bash instead of PSQL shell?

I am familiar with \x auto mode of PSQL and it works great when I make query from inside PSQL shell.
But I'm executing query from bash shell and psql is running inside a docker container.
How can I combine \x auto with SELECT query in such case ?
What I have already tried:
$ docker exec -it my_database psql -U iamuser -c "\x auto; SELECT * FROM mytable;"
Expanded display is used automatically.
\x: extra argument "select" ignored
\x: extra argument "*" ignored
\x: extra argument "from" ignored
\x: extra argument "mytable;" ignored
I also tried doing this, but no query results are not shown.
$ docker exec -it my_database psql -U iamuser -c "\x auto \n SELECT * FROM mytable;"
Expanded display is used automatically.
Is it possible to achieve this ? If yes, how ?

syntax error at or near ":" when running parametrized query from shell

I'm trying to run a parameterized query from shell.
But when I run:
p='some stuff'
psql -d "dbname" -v v1="$p" -c "SELECT * FROM table WHERE name=:'v1'"
I'm getting the following error:
ERROR: syntax error at or near ":"
Meanwhile:
psql -d "dbname" -v v1="$p" -c "\echo :'v1'"
works normally. (returns as expected: 'some stuff')
You cannot use the variable defined in -v in -c command (see below). Try passing the command into the standard input:
psql -d "dbname" -v v1="$p" <<< "SELECT * FROM table WHERE name=:'v1'"
From the document:
-c command
--command command
...
command must be either a command string that is completely parsable by
the server (i.e., it contains no psql-specific features), or a single
backslash command.
...
-v does set the psql's internal variable, which is psql-specific features. That's why you got the syntax error.

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 )

Postgres dump specific table with a capital letter

I am trying to perform a postgres dump of a specific table using -t. However, the table has a capital letter in it and I get a "No matching tables were found." I tried using quotations and double quotations around the table name but they did not work. How can I get pg to recognize the capitals? Thanks!
pg_dump -h hostname dbname -t tableName > pgdump.sql
Here is the complete command to dump your table in plain mode:
pg_dump --host localhost --port 5432 --username "postgres" --role "postgres" --format plain --file "complete_path_file" --table "schema_name.\"table_name\"" "database_name"
OR you can just do:
pg_dump -t '"tablename"' database_name > data_base.sql
Look to the last page here: Documentation
The above solutions do not work for me under Windows 7 x64. PostgreSQL 9.4.5. But this does, at last (sigh):
-t "cms.\"FooContents\""
either...
pg_dump.exe -p 8888 --username=user -t "cms.\"FooContents\"" basdb
...or...
pg_dump.exe -p 8888 --username=user -table="cms.\"FooContents\"" basdb
Inside a cmd window, I had to put three (!) double quotes around the table name if it countains upper case letters.
Example
pg_dump -t """Colors""" database > database.colors.psql
This worked for me:
pg_dump -f file.sql -U user -t 'schema.\"Table\"' database
As part of a node script I had to surround with single and double quotes, e.g.
` ... --table 'public."IndexedData"'`
The accepted solution worked in a bash console, but not as part of a node script, only the single quote approach.
Thanks to #Dirk Zabel suggestion, the following worked for me:
Windows 10 CMD
pg_dump -d "MyDatabase" -h localhost -p 5432 -U postgres --schema=public -t """TableName""" > TableName.sql
Bash
pg_dump -d "MyDatabase" -h localhost -p 5432 -U postgres --schema=public -t "\"TableName\"" > TableName.sql
Powershell
the good (shortest)
& 'C:\Program Files\PostgreSQL\12\bin\pg_dump.exe' -d db_name -t '\"CasedTableName\"'
the bad (requires --%)
& 'C:\Program Files\PostgreSQL\12\bin\pg_dump.exe' --% -d db_name -t "\"CasedTableName\""
the ugly (requires `")
& 'C:\Program Files\PostgreSQL\12\bin\pg_dump.exe' -d db_name -t "\`"CasedTableName\`""
The main point of confusion for me was the absolute necessity of having \" in there. I assumed that maybe there was a weird bug in the way powershell or psql was parsing the arguments, but it turns out it's explained in the docs:
Some native commands expect arguments that contain quote characters. Normally, PowerShell's command line parsing removes the quote character you provided. The parsed arguments are then joined into a single string with each parameter separated by a space. This string is then assigned to the Arguments property of a ProcessStartInfo object. Quotes within the string must be escaped using extra quotes or backslash (\) characters.
And of course ProcessStartInfo.Arguments Remarks tells us:
To include quotation marks in the final parsed argument, triple-escape each mark.