Declare variable in Bash? - mysql

I'm connected to my DB from the bash. I do a select count of an array and I want to stock the return in a variable. How can I do that?
I did:
var=`"select count(*) from shop_tab where catalog <> ''" | mysql -h abcdcef.com --port=3306 --user=root --password=hbbfe shop`
The request return a number but it doesn't stock into the variable.
Thanks!
EDIT: It works with this command line:
myvar = $(echo "select count(*) from shop_tab where catalog <> '';" | mysql -h abcdcef.com --port=3306 --user=root --password=hbbfe shop)

An easier way is :
var=$(mysql -h abcdcef.com --port=3306 --user=root --password=hbbfe --batch --skip-column-names -Dshop -e "select count(*) from shop_tab where catalog <> ''")
Moreover, I'll preconize the use of function in order to easily add options to the MySQL command without having to modifying all your script.
function MysqlQuery() {
mysql -h abcdcef.com --port=3306 --user=root --password=hbbfe --batch --skip-column-names -D "$1" -e "$2";
}
va=$(MysqlQuery Shop "SELECT COUNT(*) FROM shop_tab WHERE catalog <> ''")
vaABC=$(MysqlQuery Shop "SELECT COUNT(*) FROM shop_tab WHERE catalog <> 'abc'")
vadef=$(MysqlQuery Shop "SELECT COUNT(*) FROM shop_tab WHERE catalog <> 'def'")
# ...
I find this more readable too...

I think you are forgetting an echo in the pipe? Like this:
var=`echo "select count(*) from shop_tab where catalog <> ''" | mysql -h abcdcef.com --port=3306 --user=root --password=hbbfe shop`

Related

mysqldump avoid file creation if no results

I try to make a differential backup from last backup like this:
mysqldump --no-create-info --replace --skip-comments --skip-triggers --hex-blob
testdb mytable --where="last_backup > '$last_backup'" | gzip -c > backup_file.gz
All ok but if no changes from the last backup mysqldump get one empty file (only header and footer lines specific to mysql)
Is there a way to avoid the creation of backup_file.gz if no changes?
SOME LIKE:
IF ((SELECT COUNT(*) FROM my_table WHERE last_backup > '$last_backup') > 0) THEN
mysqldump --no-create-info --replace --skip-comments --skip-triggers --hex-blob
testdb mytable --where="last_backup > '$last_backup'" | gzip -c > backup_file.gz
Finally I have solved with this:
if [[ "$(mysql -sse 'USE my_bd; SELECT COUNT(*) FROM my_table WHERE last_backup > '$last_backup'" -gt "0" ]]; then
mysqldump --no-create-info --replace --skip-comments --skip-triggers --hex-blob
testdb mytable --where="last_backup > '$last_backup'" | gzip -c > backup_file.gz
fi
The mysqldump command must be in one line. I have splited to be more readable
But the If condition can be in multiple lines

Loop through result set of mysql in Bash

I have a simple bash script. I wish to get an exact count of the number of rows in each table of the database.
#!/bin/bash
TABLES_OLD=$( mysql -u user -ppassword MySchema --batch --skip-column-names -e"SHOW TABLES FROM MySchema" )
for table in "${TABLES_OLD[#]}"
do
QUERY="SELECT COUNT(*) FROM ${table}"
echo "${QUERY}"
done
The script prints:
SELECT COUNT(*) FROM Table 1
Table2
Table3
Table4
etc...
Clearly this is not what I want, and I don't even understand how what is happening is possible. What am I doing wrong?
Try this, put the tables into an array then loop thru the results
db_host='host'
db_user='user'
db_pass='password'
db='your_db'
read -ra var_id <<< $(mysql -h $db_host -u $db_user -p$db_pass $db -sse "show tables from $db")
for i in "${var_id[#]}";
do
results=$(mysql -h $db_host -u $db_user -p$db_pass $db -sse "select count(*)from $i")
echo "$i $results"
done
This should do it :
#/bin/bash
mysql -u user-ppassword -e "SELECT table_name, table_rows
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'your_data_base_name';"
Replace echo with eval
The code will be
#!/bin/bash
TABLES_OLD=$( mysql -u user -ppassword MySchema --batch --skip-column-names -e"SHOW TABLES FROM MySchema" )
for table in "${TABLES_OLD[#]}"
do
QUERY="SELECT COUNT(*) FROM ${table}"
eval "${QUERY}"
done

Trying to check if a Mysql user exists in a bash script

I am trying to check if a MYSQL user exists. This is as far as I have got. I fall down on capturing the answer from the output.
#!/bin/bash
echo -e "What is the MYSQL username called"
read DBUSER
if [ -z "$DBUSER" ]
then
exit
mysql -uUSER -pPASS -e "SELECT EXISTS(SELECT 1 FROM mysql.user WHERE user = '$DBUSER')";
if
yes
do this
else
do this
this is the output I am getting
+-----------------------------------------------------+
| EXISTS(SELECT 1 FROM mysql.user WHERE user = 'bob') |
+-----------------------------------------------------+
| 1 |
+-----------------------------------------------------+
Can any one help please
Thanks very much for your help. Here is the final result working.
It needs the -sse
RESULT_VARIABLE="$(mysql -uUSER -pPASS -sse "SELECT EXISTS(SELECT 1 FROM mysql.user WHERE user = '$DBUSER')")"
if [ "$RESULT_VARIABLE" = 1 ]; then
echo "TRUE"
else
echo "FALSE"
fi
Assigning the result to a variable can be done like this:
RESULT_VARIABLE="$(mysql -uUSER -pPASS -se "SELECT EXISTS(SELECT 1 FROM mysql.user WHERE user = '$DBUSER')")"
And you can also alias a column in MySQL, btw.
SELECT EXISTS(SELECT 1 FROM mysql.user WHERE user = '$DBUSER') AS does_it_exist

How to get a value without characters like "- , + "?

This is the normal output:
mysql> select module_id from Modules where Module_name = 'STP_XENA';
+-----------+
| module_id |
+-----------+
| 3 |
+-----------+
1 row in set (0.00 sec)
Can I get answer for the query as only "3"
I need something like,
mysql> select module_id from Modules where Module_name = 'STP_XENA';
3
mysql>
But not from bash or console. Is there any option to do this ?
You cannot do it inside MySQL editor, AFAIK. If you execute the script from console, then adding -B switch can get you desired result.
> mysql -B -u username -p password -e "select module_id from Modules where Module_name = 'STP_XENA';" DBNAME
will yield value with column name:
module_id
3
Also, if you add --skip-column-names
> mysql -B --skip-column-names -u username -p password -e "select module_id from Modules where Module_name = 'STP_XENA';" DBNAME
will yield only value (minus column name):
3
HTH
EDIT: You may start mysql with --skip-column-names switch. I am not sure about -B though. If you are able to start with -B, then great.
You want to use the query result in something like a bash script?
If so, you could do with:
mysql -u{user} -p{password} -s -N -e "select module_id from Modules where Module_name = 'STP_XENA'" database_name
Example:
module_id = `mysql -u{user} -p{password} -s -N -e "select module_id from Modules where Module_name = 'STP_XENA'" database_name`
echo $module_id

Easiest way to get count val from mysql in bash

Maybe i should use python or perl but i dont know any.
I have 4 statements and i would like to check if there are any errors longer then an hour. My user is setup so i dont need to enter a mysql user/pass. This statement is in mysql_webapp_error_check.sh
#!/bin/bash
mysql testdb -e "select count(*) from tbl where last_error_date < DATE_SUB(NOW(), INTERVAL 1 HOUR);"
How do i make it give me the return value (count(*)) instead of printing to screen?
Then i'll write an if statement and output to stdout/err for cron to use to email me (otherwise i want the script to be silent so nothing is emailed unless theres a problem)
Searched the same, -s for silent works exactly for me.
#!/bin/bash
result=`mysql testdb -s -e "select count(*) from tbl where last_error_date < DATE_SUB(NOW(), INTERVAL 1 HOUR);"`
echo result = .$result.
PS.: There is also a --batch parameter in my mysql Ver 14.14 Distrib 5.1.49 which "Write fields without conversion. Used with --batch" so its a little off-topic here, but should be mentioned here.
in bash, you use $() syntax.
#!/bin/bash
ret=$(mysql testdb -e "select count(*) from tbl where last_error_date < DATE_SUB(NOW(), INTERVAL 1 HOUR);")
if [[ "$ret" > 0 ]];then
echo "there is count"
else
echo "no count"
fi
I usually do this:
var=`mysql -e "SELECT COUNT(*) FROM ...\G" | awk '/COUNT/{print $2}/'`
For my part I simply use grep -v to exclude the line printing count(*) from the return of MySQL.
So I get the counter like that:
db_name="NAME_DB";
db_user="USER_DB";
db_pwd="PWD_DB";
counter=`mysql -u${db_user} -p${db_pwd} ${db_name} -e "SELECT count(*) FROM my_table WHERE something = '1';" | grep -v "count"`;
echo "Count for request: $counter";
I use it for some Wordpress stuff this way, reading databases infos from the wp-config.php file:
wp_db_infos="wp-config.php";
wp_db=`cat ${wp_db_infos} | grep "DB_NAME" | awk -F ', ' '{print $2}' | awk -F "'" '{print $2}'`;
wp_user=`cat ${wp_db_infos} | grep "DB_USER" | awk -F ', ' '{print $2}' | awk -F "'" '{print $2}'`;
wp_pwd=`cat ${wp_db_infos} | grep "DB_PASSWORD" | awk -F ', ' '{print $2}' | awk -F "'" '{print $2}'`;
img_to_update=`mysql -u${wp_user} -p${wp_pwd} ${wp_db} -e "SELECT count(*) FROM wp_offres WHERE maj_img = '1';" | grep -v "count"`;
#!/bin/bash
echo show databases\; | mysql -u root | (while read x; do
echo "$x"
y="$x"
done
echo "$y"
)
local count=$(mysql -u root --disable-column-names --batch --execute "SELECT COUNT(*) FROM mysql.user WHERE user = '$DstDbName'")
if [[ "$count" > 0 ]]
then
fi
--batch - do clear output w/o borders
--disable-column-names - prints only row with value
no creasy AWK used :)