sqlcmd return only count - suppress text - bash

I have a bash file which executes a SQLCMD query to check for the existence of a database:
sqlcmd -S localhost -U sa -P $SA_PASSWORD -d master -Q "SET NOCOUNT ON SELECT count(*) FROM master.sys.databases WHERE name = N'MyDatabaseHere'")
I tried adding the SET NOCOUNT ON but it still outputs like this:
------
1
I am assigning the result to a variable and I want to be able to check it like this
myvariable == 1
Is there a way to do this?

Took me a while but I found a solution only using sqlcmd.
You need to use -W -h-1 -k
-W removes trailing space
-h-1 removes headers
-k Removes all control characters, such as tabs and new line characters from the output.
TABLENAME=$(/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P $SA_PASSWORD -d master -W -h-1 -k -Q "SET NOCOUNT ON SELECT name FROM master.sys.databases WHERE name = N'MyDatabaseNameHere'")

Related

SET PGPASSWORD with asterisk character not working

I use a batch file to copy data from a database to other like this:
SET PGPASSWORD=passtest
"C:\Program Files\e-SUS\database\postgresql-9.6.13-4-windows-x64\bin\psql.exe" -h 10.10.10.10 -p 5433 -d esus -U postgres -c "\copy (SELECT * from mytable) to 'e:\data.csv' with csv header"
IF EXIST e:\data.csv ( "C:\Program Files\e-SUS\database\postgresql-9.6.13-4-windows-x64\bin\psql.exe" -h 11.11.11.11 -p 5433 -d esus -U postgres -c "\copy mytable from 'e:\data.csv' with csv header delimiter ','" )
this works correctly, but if my password have a asterisk character like SET PGPASSWORD=pass*test this not works... I try to use SET PGPASSWORD=pass%*test but this not works too.
Any idea?
You need to quote the asterisk:
SET PGPASSWORD="sec*ret"

Using a bash variables in sqlcmd

I have been tasked with replacing ISQL in a lot of our bash scripts with sqlcmd. ISQL allows piping a variable in it's execution.
An example would be:
SQL_STATEMENT="SELECT TOP 1 SYS_USER_NAME FROM SYS_USER"
echo $SQL_STATEMENT | isql -b -d, $DSN $DBUID $DBPWD >> setupdb_test.txt
From what I can tell this is not viable in sqlcmd. How can I do this? What flags does sqlcmd have to allow this to happen?
Here is what I have tried and have had a good result BUT I really do not want to create the file sql_command.sql every time a particular script runs:
echo "SELECT TOP 1 SYS_USER_NAME FROM SYS_USER" > sql_command.sql
sqlcmd -S $DB -U $DBUID -P $DBPWD -d $DSN -i sql_command.sql >> setupdb_test.txt
Programs originating on Windows can be picky about how they handle non-regular files and I don't have the opportunity to test, but you can try the typical Unix tricks for providing a "file" with data from an echo.
Either /dev/stdin:
echo "SELECT TOP 1 SYS_USER_NAME FROM SYS_USER" | sqlcmd -S "$DB" -U "$DBUID" -P "$DBPWD" -d "$DSN" -i /dev/stdin
or process substitution:
sqlcmd -S "$DB" -U "$DBUID" -P "$DBPWD" -d "$DSN" -i <(echo "SELECT TOP 1 SYS_USER_NAME FROM SYS_USER")

Copy output of sql-query to a file

I want to export a random entry of my database into a file with the command
SELECT * FROM my_table ORDER BY RANDOM() LIMIT 1 \g /path/file;
This query works if I enter it in my db terminal, but I want to us this query with a bash script but then I get the error: syntax error at or near "\g"
My bash script looks like this:
PGPASSWORD=*** psql -U user -d db_name -h localhost -p port -t -c "SELECT * FROM my_table ORDER BY RANDOM() LIMIT 1 \g /path/file"
Bash is interpreting the string and trying to interpolate it. Probably, escaping the backslash will solve your problem.
PGPASSWORD=*** psql -U user -d db_name -h localhost -p port -t -c "SELECT * FROM my_table ORDER BY RANDOM() LIMIT 1 \\g /path/file"
A SQL statement terminated by \g is not supported by the -c command switch. Per documentation of -c:
-c 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. Thus you cannot mix SQL
and psql meta-commands with this option
To redirect the results to a file, there are several options:
shell redirection: psql [other options] -Atc 'SELECT...' >/path/to/data.txt
-A is to switch to unaligned mode (no space fillers to align columns).
put the SQL part in a heredoc text instead of the command line:
psql [options] <<EOF
SELECT ... \g /path/to/file
EOF
This form has the advantage that multiline statements or multiple statements are supported directly.
\copy of the query. Be aware that COPY to a FILE is different: it creates the file on the server with the permissions of postgres and requires being a database superuser. COPY TO STDOUT works too but is not better than SELECT concerning the redirection.
I found a solution for my script, and now it works.
#!/bin/bash
RANDOM_NUMBER=0
while true
do
for i in `seq 1`
do
RANDOM_NUMBER=$(($RANDOM % 100000))
echo $RANDOM_NUMBER
PGPASSWORD=*** psql -U user_name -d db_name -h localhost -p PORT -c
"INSERT INTO numbers (number) VALUES ('$RANDOM_NUMBER');"
done
sleep 10
for i in `seq 1`
do
PGPASSWORD=*** psql -U user_name -d db_name -h localhost -p PORT -c
"DELETE FROM numbers WHERE id = (SELECT id FROM numbers ORDER BY RANDOM() LIMIT 1);"
done
done

Why does vagrant ssh -c ignore single quotes in command?

I want to update a column of my database running in a VW (using Vagrant) with the host's IP.
To do this I want to use a bash script:
LOCAL_IP=$(ipconfig getifaddr en0)
SQL="vagrant ssh -c 'psql -U user -d mydatabase -h localhost -c \"update mytable set mycolumn = '$LOCAL_IP';\"'"
eval $SQL
But I get this error:
ERROR: syntax error at or near ".123"
LINE 1: update mytable set mycolumn = 123.123.123.123;
The ouput of the SQL vriable:
echo $SQL
vagrant ssh -c 'psql -U user -d mydatabase -h localhost -c "update mytable set mycolumn = '123.123.123.123';"'
When I call the psql command from echo $SQL in the vm everything is fine, but I don't have the host ip.
vagrant ssh
psql -U user -d mydatabase -h localhost -c "update mytable set mycolumn = '123.123.123.123';"
It looks like the vagrant ssh -c command would remove the single quotes around the IP. Any ideas?
UPDATE
Easiest way to reproduce my problem:
$ vagrant ssh -c 'echo "update table set column = 'test';" > bla.sql'
$ vagrant ssh
$ cat bla.sql
update table set column = test;
I found the solution here:
https://stackoverflow.com/a/20498919/5902456
It looks now like this:
SQL="vagrant ssh -c 'psql -U user -d mydatabase -h localhost -c \"update mytable set mycolumn = '\''$LOCAL_IP'\'';\"'"

store postgresql result in bash variable

How to atore a scalar postgresql-value on a bash-variable like in script below?
dbname="testlauf"
username="postgres"
vartest='psql -c -d $dbname -U $username -h localhost -p 5432 "SELECT gid FROM testtable WHERE aid='1';"'
echo "$vartest"
I tried several different writings, but nothing seems to work. Thanks in advance.
Put the -c option just before its argument - the query. Mind also using the additional -t option to get just the tuple value. And of course, use the backticks (`) operator.
Using the -X option is also recommended, as sometimes a .psqlrc file might add some redundant output, as well as the -A option, which disables column aligning (whitespaces).
In order to skip NOTICE or other additional messages, include the -q flag.
vartest=`psql -d $db -U $user -AXqtc "SELECT gid FROM testtable WHERE aid='1'"`
Using -t option or --tuples-only will give you the rows only, so it will easier to store them in array variable (if the result from query more than one)
vartest =(`psql -t -d $dbname -U $username -c "SELECT gid FROM testtable WHERE aid='1';"`)
echo $vartest
example:
query result
ubuntu#ratnakri:~$ psql -h localhost -p 5432 -t -U postgres -d postgres -c "select slot_name from pg_replication_slots"
barman
barman2
make it into array variable
ubuntu#ratnakri:~$ RESULT=(`psql -h localhost -p 5432 -t -U postgres -d postgres -c "select slot_name from pg_replication_slots"`)
ubuntu#ratnakri:~$ echo ${RESULT[0]}
barman
ubuntu#ratnakri:~$ echo ${RESULT[1]}
barman2

Resources