bash script stuck in single line - sql-server

I have below command for bash script:
#!/bin/sh
sqlserver=("localhost" "testserver")
db="master"
user="sa"
pass="test#12345"
for item in "${sqlserver[#]}"
do
sqlcmd -S "$item" -d $db -U $user -P $pass -I -h-1 -Q "set nocount on;SELECT name as username FROM SYSUSERS WHERE NAME LIKE '%test%'" >> "$item".txt
while IFS= read -r line; do
if [ -n "$line" ]
then
#echo "Text read from file: $line"
sqlcmd -S "$item" -d $db -U $user -P $pass -I -b -h-1 -Q "set nocount on;drop user $line"
fi
done < "$item".txt
done
script is stuck at sqlcmd -S $item -d $DATABASE -U $USERNAME -P $PASSWORD -I -b -h-1 -Q "set nocount on;drop user $line". and this is going to in loop , it's goes infinity. how to get out from this if command.
I got the error as below:
Msg 15151, Level 16, State 1, Server 66752ccaf826, Line 1
Cannot drop the user 'test2', because it does not exist or you do not have permission.
Msg 15151, Level 16, State 1, Server 66752ccaf826, Line 1
Cannot drop the user 'test2', because it does not exist or you do not have permission.
Msg 15151, Level 16, State 1, Server 66752ccaf826, Line 1
Cannot drop the user 'test2', because it does not exist or you do not have permission.
Msg 15151, Level 16, State 1, Server 66752ccaf826, Line 1
Cannot drop the user 'test2', because it does not exist or you do not have permission.
Issue: How to break or exit loop once end of file? and after complete file it will go with 2nd sql server with continue for loop.
For create User:
CREATE USER test1 WITHOUT LOGIN;
CREATE USER test2 WITHOUT LOGIN;
Update1:
If I use echo "Text read from file: $line" then if condition running properly but when I use sqlcmd -S "$item" -d $db -U $user -P $pass -I -b -h-1 -Q "set nocount on;drop user $line" then it goes to infinite loop.

Assuming you want the while loop to end with the end-of-file of "$item.txt", then you need to change
if [[ ! -z $line ]]
to (for bash)
if [[ -z $line ]] ; then break ; fi
or (for sh)
if [ -z $line ] ; then break ; fi
and remove the other "fi".
As for the command
sqlcmd -S $item -d $DATABASE -U $USERNAME -P $PASSWORD -I -b -h-1 -Q "set nocount on;drop user $line"
you need to resolve the issue reported, from the shell command line, before attempting to do that within the script.

Related

Is it possible to have a persistent psql connection in bash?

I have a very large bash script and I make thousands of psql queries throughout it which I suspect is slowing it down. I have created this MWE which proves my theory. I am assuming this slow down is because of having to connect to the db repeatedly. Is there a way to remain connected to psql in bash?
#!/bin/bash
DB_NAME=testdb
DB_USER=user1 #UPDATE THIS
#DROP DB
SQL_QUERY="DROP DATABASE IF EXISTS $DB_NAME;"
echo $SQL_QUERY | sudo -u $DB_USER psql >/dev/null
#CREATE DB
SQL_QUERY="CREATE DATABASE $DB_NAME;"
echo $SQL_QUERY | sudo -u $DB_USER psql >/dev/null
#CREATE TABLE
SQL_QUERY="CREATE TABLE foo
(
id BIGSERIAL PRIMARY KEY,
problems INTEGER
);"
echo $SQL_QUERY | sudo -u $DB_USER psql -d $DB_NAME >/dev/null
TARGET_ITERATIONS=1000
#MULTIPLE DB CALLS
SQL_QUERY="INSERT INTO foo
(
problems
)
VALUES
(
99
);"
START_TIME=$(date +%s)
for ITERATION in $(seq $TARGET_ITERATIONS)
do
echo $SQL_QUERY | sudo -u $DB_USER psql -d $DB_NAME >/dev/null
done
STOP_TIME=$(date +%s)
echo "Multiple Call Duration (s): $((STOP_TIME-START_TIME))"
#Single db call
SQL_QUERY=""
for ITERATION in $(seq $TARGET_ITERATIONS)
do
SQL_QUERY+="INSERT INTO foo
(
problems
)
VALUES
(
99
);"
done
START_TIME=$(date +%s)
echo $SQL_QUERY | sudo -u postgres psql -d $DB_NAME >/dev/null
STOP_TIME=$(date +%s)
echo "Single Call Duration (s): $((STOP_TIME-START_TIME))"
Output:
$ ./test_psql.sh
Multiple Call Duration (s): 64
Single Call Duration (s): 12
Per your comment, try running this:
#/bin/bash
mkfifo /tmp/mypipe
chmod a+r /tmp/mypipe
sleep 10000 > /tmp/mypipe &
psql -f /tmp/mypipe &
echo "\pset pager off" > /tmp/mypipe
echo "select count(*) from information_schema.columns;" > /tmp/mypipe
echo "select count(*) from information_schema.columns;" > /tmp/mypipe
sleep 3
echo "select count(*) from information_schema.columns;" > /tmp/mypipe
echo "\q" > /tmp/mypipe
rm /tmp/mypipe

sqlcmd does not close the connection in bash script while running multiple sqlcmd

While running following query, I was able to get first query result but it does not continue to 2nd query. It seems that the connection doesn't stop once it's completed.
I was able to run similar query with the query in a .sql file and run them 1 by 1. I encounter an issue running all 7 in 1 bash script.
QUERY1 = SELECT * FROM SOMETABLE
QUERY2 = SELECT * FROM SOMETABLE
QUERY3 = SELECT * FROM SOMETABLE
QUERY4 = SELECT * FROM SOMETABLE
QUERY5 = SELECT * FROM SOMETABLE
QUERY6 = SELECT * FROM SOMETABLE
QUERY7 = SELECT * FROM SOMETABLE
sqlcmd -S $HOST -U $USER -P $PASSWORD -d $DATABASENAME -s $QUERY1 >
QueryRun1.csv
sqlcmd -S $HOST -U $USER -P $PASSWORD -d $DATABASENAME -s $QUERY2 > QueryRun2.csv
sqlcmd -S $HOST -U $USER -P $PASSWORD -d $DATABASENAME -s $QUERY3 > QueryRun3.csv
sqlcmd -S $HOST -U $USER -P $PASSWORD -d $DATABASENAME -s $QUERY4 > QueryRun4.csv
sqlcmd -S $HOST -U $USER -P $PASSWORD -d $DATABASENAME -s $QUERY5 > QueryRun5.csv
sqlcmd -S $HOST -U $USER -P $PASSWORD -d $DATABASENAME -s $QUERY6 > QueryRun6.csv
sqlcmd -S $HOST -U $USER -P $PASSWORD -d $DATABASENAME -s $QUERY7 > QueryRun7.csv
This bash script does not fetch the 2nd query result and so.
I can't remember why, I wrote this a little bit ago, but I remember having problems with > with sqlcmd. I had better luck with the syntax below:
output=$(/opt/mssql-tools/bin/sqlcmd -U $Login -P $Password -i "$file")
echo "$output" > $log
In your case, that would mean something like this:
QUERY1="SELECT * FROM SOMETABLE"
QUERY2="SELECT * FROM SOMETABLE"
QUERY3="SELECT * FROM SOMETABLE"
QUERY4="SELECT * FROM SOMETABLE"
QUERY5="SELECT * FROM SOMETABLE"
QUERY6="SELECT * FROM SOMETABLE"
QUERY7="SELECT * FROM SOMETABLE"
output=$(sqlcmd -S $HOST -U $USER -P $PASSWORD -d $DATABASENAME -Q "$QUERY1")
echo "$output" > QueryRun1.csv
output=$(sqlcmd -S $HOST -U $USER -P $PASSWORD -d $DATABASENAME -Q "$QUERY2")
echo "$output" > QueryRun2.csv
output=$(sqlcmd -S $HOST -U $USER -P $PASSWORD -d $DATABASENAME -Q "$QUERY3")
echo "$output" > QueryRun3.csv
output=$(sqlcmd -S $HOST -U $USER -P $PASSWORD -d $DATABASENAME -Q "$QUERY4")
echo "$output" > QueryRun4.csv
output=$(sqlcmd -S $HOST -U $USER -P $PASSWORD -d $DATABASENAME -Q "$QUERY5")
echo "$output" > QueryRun5.csv
output=$(sqlcmd -S $HOST -U $USER -P $PASSWORD -d $DATABASENAME -Q "$QUERY6")
echo "$output" > QueryRun6.csv
output=$(sqlcmd -S $HOST -U $USER -P $PASSWORD -d $DATABASENAME -Q "$QUERY7")
echo "$output" > QueryRun7.csv

How can I get this script to loop X amount of times?

I am trying to loop everything under groupadd coffee for 5 times for creating 5 new users at a time. Taking those variables and filling in the other commands. After all that is finished start again for a new user. I've searched up and down and can't seem to figure it out. Here is the script:
#!/bin/bash
#Script for adding users and groups
if [ $(getent group Coffee) ]; then
echo
else
sudo groupadd Coffee
fi
read -p "What is the new user's login ID? " username
read -s -p "What is the user's password? " password
echo
read -p "What is the new user's full name? " fullname
read -p "What is the new user's initial group? " intgroup
read -p "What is the new user's additional group? " addgroup
if [ $(getent group $intgroup) ]; then
echo
else
sudo groupadd $intgroup
fi
if [ $(getent group $addgroup) ]; then
echo
else
sudo groupadd $addgroup
fi
sudo useradd -m -G Coffee,$intgroup,$addgroup $username
if [ -z $password ]
then
echo -e "newpass\nnewpass" | sudo passwd $username
else
echo -e "$password\n$password" | sudo passwd $username
fi
I know I may have to restructure this but I am hoping it is something simple I can add to fix it.
Here is the solution that I got helped with.
<pre>
#!/bin/bash
sudo groupadd Coffee
# adds group Coffee to system
COUNTER=0
while [ $COUNTER -lt 5 ]; do
echo The counter is $COUNTER
echo
read -p "What is the new user's login ID? " username
read -s -p "What is the user's password? " password
echo
read -p "What is the new user's full name? " fullname
read -p "What is the new user's initial group? " intgroup
read -p "What is the new user's additional group? " addgroup
#prompts for variables
if [ $(getent group $intgroup) ]; then
echo
else
sudo groupadd $intgroup
fi
#checks to see if specified group is on the system
if [ $(getent group $addgroup) ]; then
echo
else
sudo groupadd $addgroup
fi
#checks to see if specified group is on the system
sudo useradd -m -G Coffee,$intgroup,$addgroup $username
#creates home directory and adds user into groups
if [ -z $password ]
then
echo -e "newpass\nnewpass" | sudo passwd $username
else
echo -e "$password\n$password" | sudo passwd $username
fi
#changes password or gives default one
let COUNTER=COUNTER+1
done
echo
<code>

BATCH FILE : not able to display variable value by accessing by %variable%

I am using widows XP OS and have batch file where I set few variable values.
when i echo those varibales i can see the values, but when i use it in some commands i get empty sting as its value.
Sample Batch file
#ECHO OFF
SET "output=select * from employee where empid='160'"
CALL SET output=%%output:'=''%%
ECHO "%output%"
sqlcmd -b -h-1 -m-1 -V1 -S testsvr -E -Q "%output%' " -d tesdb
o/p select * from employee where empid=''160''
and value of variable in sqlcmd command is empty space.
I'm not sure, what you want to do.
#ECHO OFF
SET output=select * from employee where empid="160"
ECHO %output%
ECHO sqlcmd -b -h-1 -m-1 -V1 -S testsvr -E -Q '%output%' -d tesdb
..output is:
select * from employee where empid="160"
sqlcmd -b -h-1 -m-1 -V1 -S testsvr -E -Q 'select * from employee where empid="160"' -d tesdb
Try to place the quotes as follows:
SET output="select * from employee where empid='160'"
sqlcmd -b -h-1 -m-1 -V1 -S testsvr -E -Q %output% -d tesdb

How to use a shrinkDBs.bat file to truncate all log.ldf files in nested folders?

I would like to be able to shrink all log files in nested folders. I have used this same script to modify databases but I am having problems with the shrink command.
When I run this script, I get an error stating it can not find the database in the sys.database_files. So I'm guessing my database is going by a different name in sys.database_files or simply is not added. Can you help?
for /r /d %%i in (*) do (
ECHO %%i\MY_DB.mdf
osql -S LOCALHOST\SQLEXPRESS -U johan -P johan_j-d master -Q "EXEC sp_attach_db 'MY_DB', '%%i\MY_DB.mdf', '%%i\MY_DB_log.ldf';"
osql -S LOCALHOST\SQLEXPRESS -U johan -P johan_j -d MY_DB -Q "DBCC SHRINKFILE (N'MY_DB_log',0,TRUNCATEONLY);"
osql -S LOCALHOST\SQLEXPRESS -U johan -P johan_j -d master -Q "EXEC sp_detach_db 'MY_DB';"
)
Problem solved. I should have been using the logical file name not the physical file name.

Resources