when are newlines in psql command line strings significant? - postgresql

I was trying to break a long command line involving psql command string (i.e. psql -c),and this seems to cause errors. For example, with PostgreSQL 9.5 and Ubuntu 16.04:
$ psql -c "\\dt"
works fine, while
$ psql -c "
> \\dt
> "
generates:
ERROR: syntax error at or near "\"
LINE 2: \dt
Just out of curiosity, when is it OK to insert newlines (i.e. \n) into a psql command string?

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.
https://www.postgresql.org/docs/current/static/app-psql.html
It seems that psql does not understand a backslash command with the leading new line.
As an alternative you can use piped echo command, also described in the documentation. For example:
$ echo '
> \d
> select 1 as x;' | psql postgres
List of relations
Schema | Name | Type | Owner
--------+-------+------+----------
public | dummy | view | postgres
(1 row)
x
---
1
(1 row)

Related

How to split PSQL command lines over multiple lines?

I'm using a windows batch file to connect to postgres using psql. I'm issuing commands like this....
SET PGPASSWORD=postgres
psql -U postgres -d postgres -c "DROP USER IF EXISTS foo;"
This works fine for running one, short SQL command against the database. But I'm having trouble with two related issues
How to continue a single long SQL command over multiple lines, and
How to run multiple commands.
Example 1.....
psql -U postgres -d postgres -c "CREATE DATABASE foo
WITH OWNER = bar
ENCODING = 'UTF8'
TABLESPACE = mytabspace;"
Example 2.....
psql -U postgres -d postgres -c "
ALTER TABLE one ALTER COLUMN X TYPE INTEGER;
ALTER TABLE two ALTER COLUMN Y TYPE INTEGER;"
Neither of these will work as shown, I've done some googling and found some suggestions for doing this with linux, and have experimented with various carats, backslashes and underscores, but just don't seem to be able to split the commands across lines.
I'm aware of the -f option to run a file, but I'm trying to avoid that.
Any suggestions?
The line continuation character in batch is the ^. See this Q&A
So end the line with space+caret ^ and make sure the following line begins with a space.
You will also have to escape double quoted areas that span several lines with a caret for this to work.
Since the line is unquoted then for the batch parser you will also have to escape any special chararacters like <>|& also with a caret.
psql -U postgres -d postgres -c ^"CREATE DATABASE foo ^
WITH OWNER = bar ^
ENCODING = 'UTF8' ^
TABLESPACE = mytabspace;"
psql -U postgres -d postgres -c ^" ^
ALTER TABLE one ALTER COLUMN X TYPE INTEGER; ^
ALTER TABLE two ALTER COLUMN Y TYPE INTEGER;"

Pass command line args to sql (Postgres)

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

psql - write a query and the query's output to a file

In postgresql 9.3.1, when interactively developing a query using the psql command, the end result is sometimes to write the query results to a file:
boron.production=> \o /tmp/output
boron.production=> select 1;
boron.production=> \o
boron.production=> \q
$ cat /tmp/output
?column?
----------
1
(1 row)
This works fine. But how can I get the query itself to be written to the file along with the query results?
I've tried giving psql the --echo-queries switch:
-e, --echo-queries
Copy all SQL commands sent to the server to standard output as well.
This is equivalent to setting the variable ECHO to queries.
But this always echoes to stdout, not to the file I gave with the \o command.
I've tried the --echo-all switch as well, but it does not appear to echo interactive input.
Using command editing, I can repeat the query with \qecho in front of it. That works, but is tedious.
Is there any way to direct an interactive psql session to write both the query and the query output to a file?
You can try redirecting the stdout to a file directly from your shell (Win or Linux should work)
psql -U postgres -c "select 1 as result" -e nomedb >> hello.txt
This has the drawback of not letting you see the output interactively. If that's a problem, you can either tail the output file in a separate terminal, or, if in *nix, use the tee utility:
psql -U postgres -c "select 1 as result" -e nomedb | tee hello.txt
Hope this helps!
Luca
I know this is an old question, but at least in 9.3 and current versions this is possible using Query Buffer meta-commands shown in the documentation or \? from the psql console: https://www.postgresql.org/docs/9.3/static/app-psql.html
\w or \write filename
\w or \write |command
Outputs the current query buffer to the file filename or pipes it to the shell command command.
Please try this format as I got the output from the same:
psql -h $host -p $port -q -U $user -d $Dbname -c "SELECT \"Employee-id\",\"Employee-name\" FROM Employee_table" >> Employee_Date.csv
I need the output in a CSV file.

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 )

Making an empty output from psql

I am running a psql command that executes a complex query. There's nothing that query produces, as such, psql returns "(No rows)" in the output.
Is there a way to make psql to return an empty string?
I've tried using --pset=tuples-only=on and --pset=footer=off and -q in all variations, and it doesn't seem to work.
Footer option works while in psql shell prompt, but doesn't work from script.
Tried on 9.1.7, need this for 8.4, 9.1 and 9.2.
May be good enough:
$ psql -Axt -c 'select 1 where 1=0'
produces an empty string
EDIT following comments:
The command above produces an empty line, so that includes and end-of-line.
To produce nothing at all, remove the -x option.
Not that it would make any difference to the shell anyway, as shown below:
with -x:
r=`psql -Atx -d test -c "select 1 where 1=0"`
echo $r | od -c
0000000 \n
0000001
without -x:
r=`psql -At -d test -c "select 1 where 1=0"`
echo $r | od -c
0000000 \n
0000001
Is there a way to make psql to return an empty string?
You can simply append SELECT '' after the first query.
Ex.:
psql -Atp5432 mydb -c "SELECT 1 WHERE FALSE; SELECT ''"
Replace SELECT 1 WHERE FALSE with your complex query that doesn't return a row.