How can I drop all the views from a MYSQL Database? - mysql

My database had lots of views and it was impossible to drop them one by one.
I would like to just drop them all because the database doesn't refresh structure changes of the tables in the view that select from them.

If you want to do this in the MySQL client, you can dynamically generate the DDL statements using information_schema, dump them to a SQL script, and then execute that script.
Example:
select concat('drop view ',table_schema,'.',table_name,';') as ddl
into outfile '/tmp/drop_all_views.sql'
from information_schema.views
where table_schema = 'your_schema';
\. /tmp/drop_all_views.sql

After searching on the web, I found a shell script to drop all tables here: http://www.cyberciti.biz/faq/how-do-i-empty-mysql-database/
Then, I changed that script to drop all views of the database.
This is the final result:
#!/bin/bash
PREFIX=""
SUFFIX=""
HOST="localhost"
PORT="3306"
while getopts p:s:h:P: OPCAO; do
case "${OPCAO}" in
p) PREFIX="${OPTARG}" ;;
s) SUFFIX="${OPTARG}" ;;
h) HOST="${OPTARG}" ;;
P) PORT="${OPTARG}" ;;
esac
done
shift $((OPTIND-1))
MUSER="$1"
MPASS="$2"
MDB="$3"
# Detect paths
MYSQL=$(which mysql)
AWK=$(which awk)
GREP=$(which grep)
if [ $# -eq 0 ]
then
echo "Usage: $0 [-h Host] [-P Port] [-p Prefix-View-Name] [-s Suffix-View-Name] {MySQL-User-Name} {MySQL-User-Password} {MySQL-Database-Name}"
echo "Drops all views from a MySQL"
exit 1
fi
TABLES=$($MYSQL -h $HOST -P $PORT -u $MUSER -p$MPASS $MDB -e "SELECT table_name FROM information_schema.views WHERE table_schema = '$MDB' AND table_name LIKE '$PREFIX%$SUFFIX';" | $AWK '{ print $1}')
for t in $TABLES
do
echo "Deleting $t view from $MDB database..."
$MYSQL -h $HOST -P $PORT -u $MUSER -p$MPASS $MDB -e "drop view $t"
done
This solution will work just for who uses Unix-like systems.
To call the script, I used:
./script.sh [-h host] [-P port] [-p prefixViewName] [-s suffixViewName] username password databaseName
EDIT: I improved the script to accept option parameters, like the host, port and also a prefix and a suffix to filter what views will be dropped.

Related

How to take all database backup same as db name

I am using MySQL on centos7. I have 50 databases Like database1, database2...., database50.
How can I set a cronjob for take a dump every day of all database same as database name [ Like database1.sql, database2.sql .... database50.sql ] using single command or script.
Please provide some adequate solution that will be appreciated.
Thanks.
Convert the current date to an integer number of days since some starting date.
Take that modulo 50. This gives you 0 .. 49.
Add 1 and concatenate. Now you have database1 .. database50. Put that in the shell variable db
mysqldump ... $db >$db.sql
I am using this script
#! /bin/bash
# MySQL database backup (databases in separate files) with daily, weekly and monthly rotation
# Sebastian Flippence (http://seb.flippence.net) originally based on code from: Ameir Abdeldayem (http://www.ameir.net)
# You are free to modify and distribute this code,
# so long as you keep the authors name and URL in it.
# Modified by IVO GELOV
# How many backups do you want to keep?
MAX_DAYS=5
# Date format that is appended to filename
DATE=`date +'%Y-%m-%d'`
DATSTR=`date '+%Y%m%d' -d "-$MAX_DAYS days"`
# MySQL server's name
SERVER=""
# Directory to backup to
BACKDIR="/var/db_arhiv/mysql"
#----------------------MySQL Settings--------------------#
# MySQL server's hostname or IP address
HOST="localhost"
# MySQL username
USER="user"
# MySQL password
PASS="password"
# List all of the MySQL databases that you want to backup,
# each separated by a space. Or set the option below to backup all database
DBS="db1 db2"
# Set to 'y' if you want to backup all your databases. This will override
# the database selection above.
DUMPALL="y"
# Custom path to system commands (enable these if you want use a different
# location for PHP and MySQL or if you are having problems running this script)
MYSQL="/usr/local/mysql/bin/mysql"
MYSQLDUMP="/usr/local/mysql/bin/mysqldump"
function checkMysqlUp() {
$MYSQL -N -h $HOST --user=$USER --password=$PASS -e status > /dev/null
}
trap checkMysqlUp 0
function error() {
local PARENT_LINENO="$1"
local MESSAGE="$2"
local CODE="${3:-1}"
if [[ -n "$MESSAGE" ]] ; then
echo "Error on or near line ${PARENT_LINENO}: ${MESSAGE}; exiting with status ${CODE}"
else
echo "Error on or near line ${PARENT_LINENO}; exiting with status ${CODE}"
fi
exit "${CODE}"
}
trap 'error ${LINENO}' ERR
# Check backup directory exists
# if not, create it
if [ ! -e "$BACKDIR/$DATE" ]; then
mkdir -p "$BACKDIR/$DATE"
echo "Created backup directory (${BACKDIR}/${DATE})"
fi
if [ $DUMPALL = "y" ]; then
echo "Creating list of databases on: ${HOST}..."
$MYSQL -N -h $HOST --user=$USER --password=$PASS -e "show databases;" > ${BACKDIR}/dbs_on_${SERVER}.txt
# redefine list of databases to be backed up
DBS=`sed -e ':a;N;$!ba;s/\n/ /g' -e 's/Database //g' ${BACKDIR}/dbs_on_${SERVER}.txt`
fi
echo "Backing up MySQL databases..."
#cd ${LATEST}
for database in $DBS; do
if [ ${database} = "information_schema" ] || [ ${database} = "performance_schema" ] || [ ${database} = "pinba" ]
then
continue
fi
echo "${database}..."
$MYSQLDUMP --host=$HOST --user=$USER --password=$PASS --default-character-set=utf8 --routines --triggers --lock-tables --disable-keys --force --single-transaction --allow-keywords --dump-date $database > ${BACKDIR}/${DATE}/${SERVER}$database.sql
done
if [ $DUMPALL = "y" ]; then
rm -f ${BACKDIR}/dbs_on_${SERVER}.txt
fi
# dump privileges
$MYSQL -N -h $HOST --user=$USER --password=$PASS --skip-column-names -A -e "SELECT CONCAT('SHOW GRANTS FOR ''',user,'''#''',host,''';') FROM mysql.user" | $MYSQL -N -h $HOST --user=$USER --password=$PASS --skip-column-names -A > ${BACKDIR}/${DATE}/${SERVER}_grants.sql
# delete older files
for x in `find ${BACKDIR}/20* -type d`
do
xd=`basename "${x//-/}"`
if [[ $xd < $DATSTR ]]
then
rm -rf "$x"
fi
done
echo "MySQL backup is complete"

Updating mysql table columns using shell script

I need to update mysql table using shell script . It is failing . My script goes like below .
#!/bin/bash
set -x
HOST=$1
DB=$2
FNAME=$3
LNAME=$4
FULLNAME="$FNAME $LNAME"
#MYSQL="mysql -uroot -p'mypass' -h $HOST $DB"
MYSQL="mysql -uroot -p'root123' -h $HOST $DB"
echo $MYSQl
$MYSQL -e 'INSERT INTO 'user' ('name', 'description', 'created_date', 'created_by') VALUES ( '$FNAME', '$FULLNAME', current_date(), 'dbo');
It is failing while running with mysql host, db, firstname and last name info as parameter .

Catching exit code after executing mysql query

I'm working on a bash script that will query mysql. I would like to add some error checking. Let say if the following query for some reason fails I want to catch the exit error and exit the script. For example this is part of my script.
QUERY="SELECT DISTINCT `TABLE_SCHEMA`, `TABLE_NAME`
FROM `information_schema`.`TABLES`
WHERE table_schema NOT IN ( 'mysql', 'information_schema', 'performance_schema' )"
mysql -u user -pPASSWD --batch -N -e "$QUERY" | while read DATABASE TABLE;
do
...
...
...
done
How could i catch the exit code after the scripts run the "$QUERY". I was thinking something like this. But it doesn't seem to work.
mysql -u user -pPASSWD --batch -N -e "$QUERY" echo $? | while read DATABASE TABLE;
Any ideas
You are in the good way: $? is the flag to check:
$ mysql -h mydb <<< "SELECT * FROM MyDB.some_table_that_exists;"
$ echo $?
0
$ mysql -h mydb <<< "SELECT * FROM MyDB.asdfasdfasdf;"
ERROR 1146 (42S02) at line 1: Table 'MyDB.asdfasdfasdf;' doesn't exist
$ echo $?
1
So what you can do is to execute the query and then:
if [ $? ... ]; then ...

DATABASE autocreation bash script: What's wrong?

My bash script won't crate the Database. What am I doing wrong here?
Please have a look:
#!/bin/bash -x
set -x
function deebee() {
EXPECTED_ARGS=2
E_BADARGS=65
MYSQL=`which mysql`
Q1="CREATE DATABASE IF NOT EXISTS $1;"
Q2="GRANT USAGE ON *.* TO $2#localhost IDENTIFIED BY '$3';"
Q3="GRANT ALL PRIVILEGES ON $1.* TO $2#localhost;"
Q4="FLUSH PRIVILEGES;"
SQL="${Q1}${Q2}${Q3}${Q4}"
if [ $# -ne $EXPECTED_ARGS ]
then
echo "Usage: $0 dbname dbuser dbpass"
exit $E_BADARGS
fi
$MYSQL -uroot -p -e "$SQL"
}
deebee $1 $2 $3
I'm calling the script as I've put it in a function, but it just spits out the expected arguments telling me the syntax, i.e that I should type in the bashscrip name, dbname, dbuser dbpass, but obviously there' something wrong with the script of my login permissions or user so that I can't automate this... What's going on, I'd love to know!
Thanks!
What I would do :
creating a mysql config file with credentials (easier to automate now) :
cat ~/.my.cnf
[client]
host = localhost
user = root
password = xxx
And the script :
#!/bin/bash
set -x
deebee() {
EXPECTED_ARGS=3
E_BADARGS=65
MYSQL=$(type -p mysql)
if (($# != $EXPECTED_ARGS))
then
echo "Usage: $0 dbname dbuser dbpass"
exit $E_BADARGS
fi
$MYSQL <<EOF
CREATE DATABASE IF NOT EXISTS '$1';
GRANT USAGE ON *.* TO '$2'#'localhost' IDENTIFIED BY '$3';
GRANT ALL PRIVILEGES ON '$1'.* TO '$2'#'localhost';
FLUSH PRIVILEGES;
EOF
}
# TODO tests on input args
deebee "$1" "$2" "$3"
And like Denis said in comments, take care of what users can put as arguments to prevent sql injection.
You should add some tests on input args.

How to run MySQL command on bash?

The following code works on the command line
mysql --user='myusername' --password='mypassword' --database='mydatabase' --execute='DROP DATABASE myusername;
CREATE DATABASE mydatabase;'
However, it doesn't work on bash file on execution
#!/bin/bash
user=myusername
password=mypassword
database=mydatabase
mysql --user='$user' --password='$password' --database='$database' --execute='DROP DATABASE $user; CREATE DATABASE $database;'
I receive the following error:
ERROR 1045 (28000): Access denied for user '$user'#'localhost' (using password: YES)
How to make the bash file run as the command line?
Use double quotes while using BASH variables.
mysql --user="$user" --password="$password" --database="$database" --execute="DROP DATABASE $user; CREATE DATABASE $database;"
BASH doesn't expand variables in single quotes.
This one worked, double quotes when $user and $password are outside single quotes. Single quotes when inside a single quote statement.
mysql --user="$user" --password="$password" --database="$user" --execute='DROP DATABASE '$user'; CREATE DATABASE '$user';'
I have written a shell script which will read data from properties file and then run mysql script on shell script. sharing this may help to others.
#!/bin/bash
PROPERTY_FILE=filename.properties
function getProperty {
PROP_KEY=$1
PROP_VALUE=`cat $PROPERTY_FILE | grep "$PROP_KEY" | cut -d'=' -f2`
echo $PROP_VALUE
}
echo "# Reading property from $PROPERTY_FILE"
DB_USER=$(getProperty "db.username")
DB_PASS=$(getProperty "db.password")
ROOT_LOC=$(getProperty "root.location")
echo $DB_USER
echo $DB_PASS
echo $ROOT_LOC
echo "Writing on DB ... "
mysql -u$DB_USER -p$DB_PASS dbname<<EOFMYSQL
update tablename set tablename.value_ = "$ROOT_LOC" where tablename.name_="Root directory location";
EOFMYSQL
echo "Writing root location($ROOT_LOC) is done ... "
counter=`mysql -u${DB_USER} -p${DB_PASS} dbname -e "select count(*) from tablename where tablename.name_='Root directory location' and tablename.value_ = '$ROOT_LOC';" | grep -v "count"`;
if [ "$counter" = "1" ]
then
echo "ROOT location updated"
fi