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
Related
I want to make specific .sql file for each of my routines.
#!/bin/bash
routine_names=$(mysql mydb --execute="SELECT
*
FROM
information_schema.routines
WHERE
routine_type = 'PROCEDURE' OR routine_type ='FUNCTION'
AND routine_schema = 'mydb';"|cut -f1)
for routine in "$routine_names"
do
if [ -e "${routine}.sql" ]
then
echo "ok"
else
content_procedure=$(mysql mydb--execute="SHOW CREATE PROCEDURE $routine;")
echo "$content_procedure" >> masoud.txt
fi
done
my routine_names variable is a list of my procedures. like this:
SP_ONE
SP_TWO
SP_THREE
I want to loop of these result. but I think the result is not an array. because routine variable has all content.
wrap your mysql mydb ... command with ()
routine_names=($(mysql mydb --execute="SELECT
*
FROM
information_schema.routines
WHERE
routine_type = 'PROCEDURE' OR routine_type ='FUNCTION'
AND routine_schema = 'mydb';"|cut -f1))
I was curious and got the idea from here.
Just another case how I fix my problem
#!/bin/bash
mysql -u USER -p -h localhost -D database1 -e "SELECT ID FROM prodTable WHERE display=1 AND new=1 AND exDate<DATE_SUB(CURDATE(),INTERVAL 2 YEAR)" | while read ID;
do
echo "The following product has been moved: $ID"
done
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
My Bash script makes an array from MySQL:
info_tmp=$(mysql --batch --silent -u root -ppassword database -e "SELECT id,info1,info2 FROM table WHERE id=1")
info=($(for i in $info_tmp;do echo $i;done))
info1=${info[1]}
My problem is, that, if info1 is an empty string in the database, then $info1 became info2.
How can I put an empty string into $info array?
Mysql Database:
Id | info1 | info2
1 | | data2
2 | data3 | data4
$info_tmp
1 data2
2 data3 data4
Thank you for your answer
This is the final code that worked (#Barmar):
IFS="|"
info_tmp=$(mysql --batch --silent -u root -ppassword database -e "SELECT CONCAT_WS('|', id,info1,info2) FROM table WHERE id=1")
info=(${info_tmp// / })
info1=${info[1]}
If there's a character that shouldn't appear in any of the columns, use that as a delimiter.
IFS="|"
info_tmp=$(mysql --batch --silent -u root -ppassword database -e "SELECT CONCAT_WS('|', id,info1,info2) FROM table WHERE id=1")
This works because bash doesn't merge sequences of non-whitespace delimiters in IFS, only whitespace characters.
I'm not sure what the point of the for loop that copies $info_tmp to $info is, but you need to do the same thing there. If you use whitespace as your word delimiter, you'll never be able to get empty array values from command substitution.
What about temporarily adding a single character in your for-loop:
info_tmp=$(mysql --batch --silent -u root -ppassword database -e "SELECT id,info1,info2 FROM table WHERE id=1")
info=($(for i in $info_tmp;do echo " "$i;done))
info1=$(${info[1]} | cut -c 2-)
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`
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 :)