Store multiple values from sql select in bash - mysql

I am trying to store each value from the following sql select statement and store them in separate variables using bash.
#!/bin/bash
mysqlhost="thehost"
mysqldb="thedb"
mysqlun="theusername"
mysqlpw="thepassword"
mysqlconnection="--disable-column-names --host=$mysqlhost --user $mysqlun --password=$mysqlpw --database=$mysqldb"
declare -a pinIDs=$(mysql $mysqlconnection -e "SELECT pinID FROM somewhere WHERE something = something";)
I get the following result when I use code
echo $pinIDs
8 11 23 26
I need to store each of those values into their own variable.

Add brackets to put output in array pinIDs. Replace
declare -a pinIDs=$(mysql $mysqlconnection -e "SELECT pinID FROM somewhere WHERE something = something";)
by
declare -a pinIDs=( $(mysql $mysqlconnection -e "SELECT pinID FROM somewhere WHERE something = something";) )
Then see output of: declare -p pinIDs

For others that are using this to learn. What I did after fixing the brackets in order to put the result into an array such as (8 11 23 26) instead of 8 11 23 26, was this:
cnt=${#pinIDs[#]}
for (( i=0 ; i<cnt ; i++ ))
do
echo "pinId: ""${pinIDs[$i]}"
done

Related

Run mysql query inside bash script

I am trying to run MySQL query through bash script. But, when I run SELECT * FROM EXAMPLE_DB; inside bash scripting, it is translated to SELECT files1 files2 files3 where I run the script.
Example :
read -d '' SQL_QUERY << EOF
SET #var_name = NOW() - INTERVAL 30 DAY;
CREATE TABLE tassta.temp_vontista_messages AS SELECT * FROM tassta.vontista_messages WHERE date(sent_date) >= date(#var_name);
EOF
echo ${SQL_QUERY} | mysql
What I want to run the mysql query as it is. What happened now that this is translated to
read -d '' SQL_QUERY << EOF
SET #var_name = NOW() - INTERVAL 30 DAY;
CREATE TABLE tassta.temp_vontista_messages AS SELECT file1 file2 file3 [files from where I run the script.] FROM tassta.vontista_messages WHERE date(sent_date) >= date(#var_name);
EOF
echo ${SQL_QUERY} | mysql
SQL_QUERY="SET #var_name = NOW() - INTERVAL 30 DAY;
CREATE TABLE tassta.temp_vontista_messages AS SELECT * FROM tassta.vontista_messages WHERE date(sent_date) >= date(#var_name);"
mysql -Be "$SQL_QUERY"
or:
echo "$SQL_QUERY" | mysql
NOTE: Do not put spaces before, or after the =.
see: How do I escape the wildcard/asterisk character in bash?

How to save multiple columns to bash arrays with 1 select in mysql

I'm trying to save multiple columns in bash arrays with one query, but I can't figure it out.
Now I have 3 SELECTs like this:
read -d \t -ra data1<<< $(mysql -u root -p'password' -D'users_info' -se 'SELECT data1 FROM users_logs')
read -d \t -ra data2<<< $(mysql -u root -p'password' -D'users_info' -se 'SELECT data2 FROM users_logs')
read -d \t -ra data3<<< $(mysql -u root -p'password' -D'users_info' -se 'SELECT data3 FROM users_logs')
and it's working, but I wonder, if this is an optimal way. I think that I could achieve this with one query.
I was trying to do something with mysql --batch and mapfile, but couldn't make it.
and output of running:
mysql -u root -p'password' -D'users_info' -se 'SELECT data1, data2, data3 FROM users_logs'
is:
somemail1#gmail.com 2 2z7bhxb55d3
somemail2#gmail.com 2 we3cq3micu9cn
somemail3#gmail.com 1 we3cq1dicu9cn
All those data are varchar(30).
Assuming the objective is to read a grid of data into multiple arrays (with each column being loaded into a separate array) ...
For dynamically generating/populating arrays using bash namerefs take a look at this answer.
If the number of arrays (and their names) are predefined ...
First some data to simulate the OP's output:
$ cat mysql.out
somemail1#gmail.com 2 2z7bhxb55d3
somemail2#gmail.com 2 we3cq3micu9cn
somemail3#gmail.com 1 we3cq1dicu9cn
NOTE: The following code assumes the column data does not include white space, eg, the above file has 3 columns and not 1 column with embedded spaces; otherwise OP will need to insure the stream of input has a well-defined column delimiter that can be used by the while loop
One bash loop idea:
unset data1 data2 data3
typeset -a data1 data2 data3
i=0
while read -r col1 col2 col3
do
(( i++ ))
data1[${i}]="${col1}"
data2[${i}]="${col2}"
data3[${i}]="${col3}"
done < mysql.out # replace this with ...
# done < <(mysql ... SELECT data1,data2,data3 ...) # this to have mysql results fed directly into 'while' loop
This gives us:
$ typeset -p data1 data2 data3
declare -a data1=([1]="somemail1#gmail.com" [2]="somemail2#gmail.com" [3]="somemail3#gmail.com")
declare -a data2=([1]="2" [2]="2" [3]="1")
declare -a data3=([1]="2z7bhxb55d3" [2]="we3cq3micu9cn" [3]="we3cq1dicu9cn")
If you don't mind the indices starting # 0 ...
unset data1 data2 data3
typeset -a data1 data2 data3
while read -r col1 col2 col3
do
data1+=("${col1}")
data2+=("${col2}")
data3+=("${col3}")
done < mysql.out
This gives us:
$ typeset -p data1 data2 data3
declare -a data1=([0]="somemail1#gmail.com" [1]="somemail2#gmail.com" [2]="somemail3#gmail.com")
declare -a data2=([0]="2" [1]="2" [2]="1")
declare -a data3=([0]="2z7bhxb55d3" [1]="we3cq3micu9cn" [2]="we3cq1dicu9cn")

In ksh , pass parameters to mysql select query

I have a linux script that gets a variable and I store it to var JOB_EXEC_ID
I am trying to pass the value of this to a MySQL query
Here is MySQL query set-up
print "JOB EXEC ID value for DataMeer Job ${LOADJOB} is : ${JobExecId} " |
tee -a ${LOGDIR}/${LOGFILE}
#Log on to MySQL to get the DataId
#Remove first the output file that would house the dataid
rm -f ${SCRDIR}/list_dataid.csv
mysql -u root -pmonday1 ${DAPDBNAME} < ${SCRDIR}/dataid_query.nosql
SQLRTN=$?
if [[ ${SQLRTN} != 0 ]]
then
print "Return code from sqlcall - DAP : ${SQLRTN}" |
tee -a ${LOGDIR}/${LOGFILE}
print "Exiting $Script - 55 " |
tee -a ${LOGDIR}/${LOGFILE}
exit 55
fi
The file dataid_query.nosql looks like this:
set #job_exec_id=10151
select d.id DataId
from data d inner join dap_job_configuration djc on d.dap_job_configuration__id = djc.id
left outer join dap_job_execution dje on djc.id = dje.dap_job_configuration__id and dje.created_data__id = d.id
where dje.id=#job_exec_id
into OUTFILE "/home/app1ebb/cs/list_dataid.csv"
I want to pass the value of JOB_EXEC_ID to the set command that is currently hardcoded right now with a value of 10151
in place of
mysql -u root -pmonday1 ${DAPDBNAME} < ${SCRDIR}/dataid_query.nosql
SQLRTN=$?
this lines
sed "1 s/[0-9]*$/${JOB_EXEC_ID}/" > /tmp/dataid_query.nosql
mysql -u root -pmonday1 ${DAPDBNAME} < /tmp/dataid_query.nosql
SQLRTN=$?
rm /tmp/dataid_query.nosql

Pass MySQL variables to script from command line

I have a MySQL update script I'd like to run from the command line, but I want to be able to pass a stage domain variable to the script.
I know this won't work, but it's the best way I can describe what I'm trying to do:
$ -uroot -hlocalhost mydatabase --execute "SET #domain = 'mydomain.dev' " < ./sql/update_domain.sql
Inside the script, I'm using the #domain variable, to update some configuration variables in a config table, using commands like this:
UPDATE my_cfg SET value = #domain WHERE name = 'DOMAIN';
Basically I want to prefix the SET #domain on the update_domain.sql file.
Any ideas how I can rectify my approach?
In your BATCH File :
mysql -e "set #domain=PARAMVALUE;source ./sql/update_domain.sql"
And in you SQL file :
UPDATE my_cfg SET value = #domain WHERE name = 'DOMAIN';
you can do that with sed like this:
echo "UPDATE my_cfg SET value = '#domain#' WHERE name = 'DOMAIN'" | sed 's/#domain#/mydomain.dev/' | mysql -uusername -ppassword dbname
or update.sql has UPDATE:
cat update.sql | sed 's/#domain#/mydomain.dev/' | mysql -uusername -ppassword dbname
This works for me:
system("(echo \"SET #domain = 'newstore.personera.abc';\"; cat sql/set_domain.sql) > /tmp/_tmp.sql")
system("mysql -uroot -hlocalhost newstore.personera.dev < /tmp/_tmp.sql")
system("rm /tmp/_tmp.sql")
...calling with system() from Capistrano.
I've found a better solution.
--init-command=name SQL Command to execute when connecting to MariaDB server.
mysql --init-command="SET #foo = 1; SET #bar = 2" -e "SELECT #foo, #bar, VERSION()"
Output:
+------+------+-------------------------------------+
| #foo | #bar | VERSION() |
+------+------+-------------------------------------+
| 1 | 2 | 10.6.3-MariaDB-1:10.6.3+maria~focal |
+------+------+-------------------------------------+
It also works with file redirection.

bash - SQL Query Outputs to variable

Im new in bash scripting.
I want to save sql-query outputs in variable, but
actually I must connect for every query to mysql with:
mysql -u $MYUSER -p$MYPASS -D database
and want to save every output in seperatly variable
sample query is: SELECT domain FROM domains WHERE user='$USER'
to
$variable1 = FIRST_OUTPUT
$variable2 = 2ND_OUTPUT
thank you
Taken from bash script - select from database into variable, you can read the query result into a variable.
Example
mysql> SELECT * FROM domains;
+-------+---------+
| user | domain |
+-------+---------+
| user1 | domain1 |
| user2 | domain2 |
| user3 | domain3 |
+-------+---------+
Usage
$ myvar=$(mysql -D$MYDB -u$MYUSER -p$MYPASS -se "SELECT domain FROM domains")
$ echo $myvar
domain1 domain2 domain3
echo is the bash command for output. You can then split $myvar into separate variables:
$ read var1 var2 var3 <<< $myvar
$ echo $var1
domain1
$ echo $var2
domain2
You can combine these two commands into a single one:
read var1 var2 var3 <<< $(mysql -D$MYDB -u$MYUSER -p$MYPASS -se "SELECT domain FROM domains")
It is possible to store the results into arrays (useful if you don't know how many records there):
$ read -ra vars <<< $(mysql -D$MYDB -u$MYUSER -p$MYPASS -se "SELECT domain FROM domains")
$ for i in "${vars[#]}"; do
$ echo $i
$ done
domain1
domain2
domain3
Another way of doing is:
dbquery=`mysql -D$MYDB -u$MYUSER -p$MYPASS -se "SELECT domain FROM domains"`
dbquery_array=( $( for i in $dbquery ; do echo $i ; done ) )
The first line stores all the output from the query in a varriable dbquery in a array-like-way. The second line converts the dbquery into an array dbquery_array with a simple for loop.
I did this
variable=mysql -u root -ppassworrd database << EOF
select MAX(variable) AS a from table where variable2 = 'SOMETEXT' AND day(datevalue) >= 22;
EOF
I hope it helps