Insert into mysql from linux terminal - mysql

I have a question. i can insert into mysql database from linux terminal a record with this command:
mysql dbTest insert into tablename values(1,"b","c")
Now i have a file in Linux with some records
for example:
$cat file
2, "c", "e"
3, "r", "q"
4, "t", "w"
5, "y", "e"
6, "u", "r"
7, "g", "u"
8, "f", "j"
9, "v", "k"
i don't know how can i insert all records to the file to mysql database from linux terminal.
I intent with a bash file but i don't know =(

Doing a series of inserts is not the best choice performance-wise. Since your input data exist as CSV you'd be better off doing a bulk load as #Kevin suggested:
mysql dbTest -e "LOAD DATA INFILE './file' INTO TABLE tablename FIELDS TERMINATED BY ','"

You can create a custom sql file using sed.
From a terminal execute the following code:
sed 's/\(^[0-9"]*, [a-z"]*, [a-z]*$\)/INSERT INTO tablename VALUES(\1);/g' source_file > sql_script.sql
After you can easily use the source command to insert the records.
$ mysql -u mysqlusername -p -h host
Enter password: your_secret_password
Mysql > use yourdatabasename
Mysql > source sql_script.sql

Using awk you could use the existing file and insert values from bash itself:
awk 'BEGIN {print "mysql -u root -p dbTest << EOF"} {print "insert into tablename values (" $0 ");"} END {print "EOF"}' file |bash -v

mysql -e "use databasename;insert into TABLENAME values ('POST',........);"

Install Mysql :
sudo apt-get install mysql-server
Goto Mysql shell:
mysql -u root -p
password:******
Show Database( if already exist):
show databases;
Create a databases:
create database employees;
Access the created database:
use employees;</code>
Create a table (Be careful on "``" and " " : use acutesign in each field):
create table `employees`( `id` int(11) NOT NULL AUTO_INCREMENT, `first_name` varchar(64) DEFAULT NULL,`last_name` varchar(64) DEFAULT NULL, `email` varchar(64) DEFAULT NULL, `department` varchar(64) DEFAULT NULL, `salary` DECIMAL(10,2) DEFAULT NULL, PRIMARY KEY(`id`))
ENGINE = InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET = latin1;
Add Information to a table:
INSERT INTO `employees` (`id`,`first_name`,`last_name`,`email`,`department`,`salary`)
VALUES (1, 'Sumanta','Silwal','sumantasilwal10#gmail.com','Computer Design', '5000.00');
Look the created tale:
select * from employees;
Note: use "`" sign in each field like employees, id, first_name, last_name, email, department and salary.
**Enjoy coding.

Related

trying to get Mysql command line back to bash after entering mysql from command line within code?

trying to get the code back into bash from mysql but having to manule type exit at
else
echo "Continuting process"
fi **this is the end of the if else stament nested above**
sudo apt-get install mysql-server
mysql -u root -p;
mysql> grant all privileges on KF4005"aaon#localhost";
mysql> CREATE DATABASE F4005;
mysql> use KF4005;
mysql> CREATE TABLE filedata File name VARCHAR , File permissions VARCHAR, UserID INT, GroupID
INT, Last accessed VARCHAR , Last Changed VARCHAR, Size INT, Last Modified VARCHAR , Birth
VARCHAR;
mysql> SHOW TABLES;
mysql> LOAD DATA LOCAL INFILE 'Bashoutput.txt' INTO TABLE filedata;
mysql> SELECT * FROM filedata;
mysql> exit;
trying to return back to normal bash here but have to manule typepe exit
exit;
exit;
You can press CTRL + D to exit MySQL.

Run Query to MySQL from a Bash Script

please help, whats wrong?
sudo -u root /etc/scripts/mysql.sh root 111111
#!/bin/bash
mysql --host=localhost --user=root --password=111111
mysql 1<< EOF
INSERT INTO
table1(id)
SELECT MAX(id) + 1 FROM table1;
EOF
You should just invoke MySQL once and specify the default database:
#!/bin/bash
mysql --host=localhost --user=root --password=111111 1 << EOF
INSERT INTO
table1(id)
SELECT MAX(id) + 1 FROM table1;
EOF
Use below script:
#!/bin/bash
USER='root'
PASS='root123'
mysql -u$USER -p$PASS mydb -e"insert into table1 (id) select (max(id) + 1) from table1;"
Note: As you are executing sql from same server so no need of localhost.
Now use as from directory where your script exists-
sh myscript.sh

How to convert all tables in database to one collation?

I'm getting error:
Illegal mix of collations (utf8_general_ci,IMPLICIT) and (utf8_unicode_ci,IMPLICIT) for operation '='"
I tried changing both tables manually to utf8_general_ci,IMPLICIT but I'm still getting the error.
Is there a way to convert all tables to utf8_general_ci,IMPLICIT and be done with it?
You need to execute a alter table statement for each table. The statement would follow this form:
ALTER TABLE tbl_name
[[DEFAULT] CHARACTER SET charset_name]
[COLLATE collation_name]
Now to get all the tables in the database you would need to execute the following query:
SELECT *
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA="YourDataBaseName"
AND TABLE_TYPE="BASE TABLE";
So now let MySQL write the code for you:
SELECT CONCAT("ALTER TABLE ", TABLE_SCHEMA, '.', TABLE_NAME," COLLATE your_collation_name_here;") AS ExecuteTheString
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA="YourDatabaseName"
AND TABLE_TYPE="BASE TABLE";
You can copy the results and execute them. I have not tested the syntax but you should be able to figure out the rest. Think of it as a little exercise.
Better option to change also collation of varchar columns inside table also
SELECT CONCAT('ALTER TABLE `', TABLE_NAME,'` CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;') AS mySQL
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA= "myschema"
AND TABLE_TYPE="BASE TABLE"
Additionnaly if you have data with forein key on non utf8 column before launch the bunch script use
SET foreign_key_checks = 0;
It means global SQL will be for mySQL :
SET foreign_key_checks = 0;
ALTER TABLE `table1` CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE `table2` CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE `tableXXX` CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
SET foreign_key_checks = 1;
But take care if according mysql documentation http://dev.mysql.com/doc/refman/5.1/en/charset-column.html,
If you use ALTER TABLE to convert a column from one character set to another, MySQL attempts to map the data values, but if the character sets are incompatible, there may be data loss. "
EDIT: Specially with column type enum, it just crash completly enums set (even if there is no special caracters)
https://bugs.mysql.com/bug.php?id=26731
#Namphibian's suggestion helped me a lot...
went a little further though and added columns and views to the script
just enter your schema's name below and it will do the rest
-- set your table name here
SET #MY_SCHEMA = "";
-- tables
SELECT DISTINCT
CONCAT("ALTER TABLE ", TABLE_NAME," CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;") as queries
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA=#MY_SCHEMA
AND TABLE_TYPE="BASE TABLE"
UNION
-- table columns
SELECT DISTINCT
CONCAT("ALTER TABLE ", C.TABLE_NAME, " CHANGE ", C.COLUMN_NAME, " ", C.COLUMN_NAME, " ", C.COLUMN_TYPE, " CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;") as queries
FROM INFORMATION_SCHEMA.COLUMNS as C
LEFT JOIN INFORMATION_SCHEMA.TABLES as T
ON C.TABLE_NAME = T.TABLE_NAME
WHERE C.COLLATION_NAME is not null
AND C.TABLE_SCHEMA=#MY_SCHEMA
AND T.TABLE_TYPE="BASE TABLE"
UNION
-- views
SELECT DISTINCT
CONCAT("CREATE OR REPLACE VIEW ", V.TABLE_NAME, " AS ", V.VIEW_DEFINITION, ";") as queries
FROM INFORMATION_SCHEMA.VIEWS as V
LEFT JOIN INFORMATION_SCHEMA.TABLES as T
ON V.TABLE_NAME = T.TABLE_NAME
WHERE V.TABLE_SCHEMA=#MY_SCHEMA
AND T.TABLE_TYPE="VIEW";
Below is the more accurate query.
I am giving example how to convert it to utf8
SELECT CONCAT("ALTER TABLE `", TABLE_NAME,"` DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;") AS mySQL
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA="myschema"
AND TABLE_TYPE="BASE TABLE"
If you're using PhpMyAdmin, you can now:
Select the database.
Click the "Operations" tab.
Under "Collation" section, select the desired collation.
Click the "Change all tables collations" checkbox.
A new "Change all tables columns collations" checkbox will appear.
Click the "Change all tables columns collations" checkbox.
Click the "Go" button.
I had over 250 tables to convert. It took a little over 5 minutes.
You can use this BASH script:
#!/bin/bash
USER="YOUR_DATABASE_USER"
PASSWORD="YOUR_USER_PASSWORD"
DB_NAME="DATABASE_NAME"
CHARACTER_SET="utf8" # your default character set
COLLATE="utf8_general_ci" # your default collation
tables=`mysql -u $USER -p$PASSWORD -e "SELECT tbl.TABLE_NAME FROM information_schema.TABLES tbl WHERE tbl.TABLE_SCHEMA = '$DB_NAME' AND tbl.TABLE_TYPE='BASE TABLE'"`
for tableName in $tables; do
if [[ "$tableName" != "TABLE_NAME" ]] ; then
mysql -u $USER -p$PASSWORD -e "ALTER TABLE $DB_NAME.$tableName DEFAULT CHARACTER SET $CHARACTER_SET COLLATE $COLLATE;"
echo "$tableName - done"
fi
done
For phpMyAdmin I figured this out:
SELECT GROUP_CONCAT("ALTER TABLE ", TABLE_SCHEMA, '.', TABLE_NAME," CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" SEPARATOR ' ') AS OneSQLString
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA="yourtableschemaname"
AND TABLE_TYPE="BASE TABLE"
Just change yourtableschemaname and you're fine.
Taking the answer from #Petr Stastny a step further by adding a password variable. I'd prefer if it actually took it in like a regular password rather than as an argument, but it's working for what I needed.
#!/bin/bash
# mycollate.sh <database> <password> [<charset> <collation>]
# changes MySQL/MariaDB charset and collation for one database - all tables and
# all columns in all tables
DB="$1"
PW="$2"
CHARSET="$3"
COLL="$4"
[ -n "$DB" ] || exit 1
[ -n "$PW" ]
[ -n "$CHARSET" ] || CHARSET="utf8mb4"
[ -n "$COLL" ] || COLL="utf8mb4_bin"
PW="--password=""$PW"
echo $DB
echo "ALTER DATABASE $DB CHARACTER SET $CHARSET COLLATE $COLL;" | mysql -u root "$PW"
echo "USE $DB; SHOW TABLES;" | mysql -s "$PW" | (
while read TABLE; do
echo $DB.$TABLE
echo "ALTER TABLE $TABLE CONVERT TO CHARACTER SET $CHARSET COLLATE $COLL;" | mysql "$PW" $DB
done
)
PW="pleaseEmptyMeNow"
This is my version of a bash script. It takes database name as a parameter and converts all tables to another charset and collation (given by another parameters or default value defined in the script).
#!/bin/bash
# mycollate.sh <database> [<charset> <collation>]
# changes MySQL/MariaDB charset and collation for one database - all tables and
# all columns in all tables
DB="$1"
CHARSET="$2"
COLL="$3"
[ -n "$DB" ] || exit 1
[ -n "$CHARSET" ] || CHARSET="utf8mb4"
[ -n "$COLL" ] || COLL="utf8mb4_general_ci"
echo $DB
echo "ALTER DATABASE $DB CHARACTER SET $CHARSET COLLATE $COLL;" | mysql
echo "USE $DB; SHOW TABLES;" | mysql -s | (
while read TABLE; do
echo $DB.$TABLE
echo "ALTER TABLE $TABLE CONVERT TO CHARACTER SET $CHARSET COLLATE $COLL;" | mysql $DB
done
)
Following on from G H I've added the user and host parameters incase you need to do this on a remote server
#!/bin/bash
# mycollate.sh <database> <user> <password> [<host> <charset> <collation>]
# changes MySQL/MariaDB charset and collation for one database - all tables and
# all columns in all tables
DB="$1"
USER="$2"
PW="$3"
HOST="$4"
CHARSET="$5"
COLL="$6"
[ -n "$DB" ] || exit 1
[ -n "$USER" ] || exit 1
[ -n "$PW" ] || exit 1
[ -n "$HOST" ] || HOST="localhost"
[ -n "$CHARSET" ] || CHARSET="utf8mb4"
[ -n "$COLL" ] || COLL="utf8mb4_general_ci"
PW="--password=""$PW"
HOST="--host=""$HOST"
USER="--user=""$USER"
echo $DB
echo "ALTER DATABASE $DB CHARACTER SET $CHARSET COLLATE $COLL;" | mysql "$HOST" "$USER" "$PW"
echo "USE $DB; SHOW TABLES;" | mysql "$HOST" "$USER" "$PW" | (
while read TABLE; do
echo $DB.$TABLE
echo "ALTER TABLE $TABLE CONVERT TO CHARACTER SET $CHARSET COLLATE $COLL;" | mysql "$HOST" "$USER" "$PW" $DB
done
)
PW="pleaseEmptyMeNow"
If you want a copy-paste bash script:
var=$(mysql -e 'SELECT CONCAT("ALTER TABLE ", TABLE_NAME," CONVERT TO CHARACTER SET utf8 COLLATE utf8_czech_ci;") AS execTabs FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA="zabbix" AND TABLE_TYPE="BASE TABLE"' -uroot -p )
var+='ALTER DATABASE zabbix CHARACTER SET utf8 COLLATE utf8_general_ci;'
echo $var | cut -d " " -f2- | mysql -uroot -p zabbix
Change zabbix to your database name.
I will share my answer using MySQL procedure.
You need to run 3 sql command.
1.
DROP PROCEDURE IF EXISTS UpdateTable;
2.
DELIMITER $$
CREATE PROCEDURE UpdateTable()
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE _table_name CHAR(255);
DECLARE cur CURSOR FOR
SELECT table_name FROM information_schema.tables
WHERE table_schema = 'my_db_name' AND table_type = "BASE TABLE";
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN cur;
My_loop: LOOP
FETCH cur INTO _table_name;
SET #my_table_name = _table_name;
IF done THEN
LEAVE My_loop;
END IF;
SET FOREIGN_KEY_CHECKS = 0;
SET #stmt = CONCAT('ALTER TABLE ', #my_table_name, ' CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;');
PREPARE stmt1 FROM #stmt;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
SET FOREIGN_KEY_CHECKS = 1;
END LOOP;
CLOSE cur;
END$$
DELIMITER ;
3.
CALL UpdateTable();
Then run first one again. If you don't want to store the procedure.

How to echo print statements while executing a sql script

We have a simple sql script which needs to be executed against a MySQL database and we would like print log statements on the progress of the script (e.g. Inserted 10 records into foo or Deleted 5 records from bar). How do we do this?
I would like to know the syntax to be used for insert/update/delete statements.
How do I know about the number of rows affected by my statement(s).
I would also like to control printing them using a ECHO off or on command at the top of the script.
The script should be portable across Windows / Linux OS.
This will give you are simple print within a sql script:
select 'This is a comment' AS '';
Alternatively, this will add some dynamic data to your status update if used directly after an update, delete, or insert command:
select concat ("Updated ", row_count(), " rows") as '';
I don't know if this helps:
suppose you want to run a sql script (test.sql) from the command line:
mysql < test.sql
and the contents of test.sql is something like:
SELECT * FROM information_schema.SCHEMATA;
\! echo "I like to party...";
The console will show something like:
CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME
def information_schema utf8
def mysql utf8
def performance_schema utf8
def sys utf8
I like to party...
So you can execute terminal commands inside an sql statement by just using \!, provided the script is run via a command line.
\! #terminal_commands
Just to make your script more readable, maybe use this proc:
DELIMITER ;;
DROP PROCEDURE IF EXISTS printf;
CREATE PROCEDURE printf(thetext TEXT)
BEGIN
select thetext as ``;
END;
;;
DELIMITER ;
Now you can just do:
call printf('Counting products that have missing short description');
What about using mysql -v to put mysql client in verbose mode ?
For mysql you can add \p to the commands to have them print out while they run in the script:
SELECT COUNT(*) FROM `mysql`.`user`
\p;
Run it in the MySQL client:
mysql> source example.sql
--------------
SELECT COUNT(*) FROM `mysql`.`user`
--------------
+----------+
| COUNT(*) |
+----------+
| 24 |
+----------+
1 row in set (0.00 sec)
You can use print -p -- in the script to do this example :
#!/bin/ksh
mysql -u username -ppassword -D dbname -ss -n -q |&
print -p -- "select count(*) from some_table;"
read -p get_row_count1
print -p -- "select count(*) from some_other_table;"
read -p get_row_count2
print -p exit ;
#
echo $get_row_count1
echo $get_row_count2
#
exit

How to feed mysql queries from bash

I'm trying to make a bash script that creates a mysql user and database but I can't find a way to feed the sql into mysql, I'm trying with this format:
mysql < echo "query"
But that is not working, see the example below:
mysql --host=localhost --user=user --password=password < echo "CREATE USER 'testuser'#'localhost' IDENTIFIED BY 'jakdJxct8W';
CREATE DATABASE IF NOT EXISTS 'testuser_dev' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
GRANT ALL PRIVILEGES ON 'testuser_dev' . * TO 'testuser'#'localhost';
CREATE DATABASE IF NOT EXISTS 'testuser_qa' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
GRANT ALL PRIVILEGES ON 'testuser_qa' . * TO 'testuser'#'localhost';"
How to feed mysql with the queries?
Try like this:
echo "select 1" | mysql
Try using a here document like this:
mysql --host=localhost --user=user --password=password << END
CREATE USER 'testuser'#'localhost' IDENTIFIED BY 'jakdJxct8W';
CREATE DATABASE IF NOT EXISTS 'testuser_dev' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
GRANT ALL PRIVILEGES ON 'testuser_dev' . * TO 'testuser'#'localhost';
CREATE DATABASE IF NOT EXISTS 'testuser_qa' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
GRANT ALL PRIVILEGES ON 'testuser_qa' . * TO 'testuser'#'localhost';
END
Alternatively place all you commands in text file and run it:
mysql --host=localhost --user=user --password=password < commands.sql
mysql --batch --silent -e 'SHOW TABLES';
Batch and silent are handy if you are planning to pipe the output
The reason your attempt did not work was because the < expects a file name and you fed it a string. You would have to do something like
echo "YOURQUERYSTRINGHERE">tmpfile
mysql --host=localhost --user=user --password=password dbname <tmpfile
ken's suggestion of
mysql --host=localhost --user=user --password=password -e "QUERY" dbname
can work, but if you try to use bash variables in your query you can fall foul of parameter expansion. eg
QUERY="select * from $MYTABLE WHERE name=\"silly#place.com\";"
mysql --host=localhost --user=user --password=password -e "$QUERY" mydbname
may not do what you expect.
One option is use
echo "$QUERY"|mysql --host=localhost --user=user --password=password mydbname
which works if the query string contains appropriate quoting. Another option is the "here" document as suggested by dogbane.
Have you tried mysql -e query?
cat <<EOD | mysql [-u user] [-ppassword] [database]
select 1;
select 2;
select 3;
EOD
in your case
cat <<EOD | mysql -u root -p
CREATE DATABASE IF NOT EXISTS testuser_dev DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
GRANT ALL PRIVILEGES ON testuser_dev.* TO "testuser"#"localhost";
CREATE DATABASE IF NOT EXISTS testuser_qa DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
GRANT ALL PRIVILEGES ON testuser_qa.* TO "testuser"#"localhost";
FLUSH PRIVILEGES;
EOD
For big queries in a bash script, you can try:
read -d '' SQL_QUERY_1 << EOF
SELECT prod.id as id, prod.title as title, comp.name as company, pho.id as photo_id, pho.image as photo_name
FROM products as prod
JOIN accounts as comp
ON comp.id = prod.account_id
JOIN photos as pho
ON pho.id = prod.featured_photo_id;
EOF
echo ${SQL_QUERY_1} | mysql