本文介紹了如何在shell中讀寫mysql數據庫。主要介紹了如何在shell 中連接mysql數據庫,如何在shell中創建數據庫,創建表,插入csv文件,讀取mysql數據庫,導出mysql數據庫為xml或html文件, 並分析了核心語句。本文介紹的方法適用於PostgreSQL ,相對mysql而言,shell 中讀寫PostgreSQL會更簡單些。
1. 連接mysql 數據庫
shell中連接數據庫的方法很簡單,只需要指定用戶名,密碼,連接的數據庫名稱,然后通過重定向,輸入mysql的語句,如下所示:
mysql -u USERNAME -p PASSWORD DATABASENAME <<EOF 2>/dev/null show databases; EOF
但這並不是一個好辦法,任何使用該腳本的用戶都能看到該數據庫用戶的賬號和密碼,要解決這個問題,可以用mysql 數據庫的一個特殊配置文件。mysql 數據庫使用$HOME/.my.cnf 文件來讀取特殊的啟動命令和設置。其中一項設置是由該用戶賬戶發起的mysql 會話的默認密碼。要在這個文件中設置默認密碼,可以加入下面的內容:
[client] password = 123456
然后,別忘了修改權限:
chmod 400 .my.cnf
這樣就可以通過腳本訪問mysql數據庫了,如下所示:
#!/bin/bash MYSQL=`which mysql` $MYSQL test -u root << EOF show databases; show tables; select * from employees where salary > 4000; EOF
2. 創建數據庫
通過上面的方法連接數據庫,再通過重定向輸入mysql語句,shell中讀寫mysql基本就介紹完了。只要把sql語句寫對了,通過重定向執行即可,下面來看一個實例:
#!/bin/bash ############################## # @file create_db_mysql.sh # @brief create database and tables in mysql # @author Mingxing LAI # @version 0.1 # @date 2013-01-20 ############################## USER="root" DATABASE="students" TABLE="students" ###################### #crate database mysql -u $USER << EOF 2>/dev/null CREATE DATABASE $DATABASE EOF [ $? -eq 0 ] && echo "created DB" || echo DB already exists ###################### #create table mysql -u $USER $DATABASE << EOF 2>/dev/null CREATE TABLE $TABLE( id int, name varchar(100), mark int, dept varchar(4) ); EOF [ $? -eq 0 ] && echo "Created table students" || echo "Table students already exist" ###################### #delete data mysql -u $USER $DATABASE << EOF 2>/dev/null DELETE FROM $TABLE; EOF
這個腳本比較簡單,就是幾條SQL語句,沒什么好解釋的,下面來看一下,如何讀入csv 文件,然后插入到mysql數據庫中。
3. 插入csv 文件
上面創建了一個學生表,表中有學生的學號,姓名,成績,系別,假設有一個csv文件,內容如下:
$cat data 1,Navin M,98,CS 2,Kavya N,70,CS 3,Nawaz O,80,CS 4,Hari S,80,EC 5,Alex M,50,EC 6,Neenu J,70,EC 7,Bob A,30,EC 8,Anu M,90,AE 9,Sruthi,89,AE 10,Andrew,89,AE
為了將csv 文件插入到數據庫,我們需要逐行讀入,然后給字符串加上雙引號,最后生成語句如下:
insert into students VALUES(1, "Navin M", 98, "CS");
要解析csv 文件,最好的工具莫過於awk了,將域的分隔符指定為逗號-F,,awk就自動將各個域拆分出來了,然后在需要雙引號的地方打印輸出一個雙引號,就能夠輕松得到下面這樣的數據:
1, "Navin M", 98, "CS" awk 代碼如下:
query=`echo $line | awk -F, '{ printf("%s,\"%s\",%s,\"%s\"", $1, $2, $3, $4)}'` statement=`echo "INSERT INTO $TABLE VALUES($query);"` echo $statement
當然了,你也可以用其他辦法,不過,幾乎沒有比awk更簡單的了,第2種方法如下:
oldIFS=$IFS IFS=, values=($line) values[1]="\"`echo ${values[1]} | tr ' ' '#' `\"" values[3]="\"`echo ${values[3]}`\"" query=`echo ${values[@]} | tr ' #' ', '` IFS=$oldIFS statement=`echo "INSERT INTO $TABLE VALUES($query);"` echo "$statement"
首先通過指定域分隔符,將csv文件解析成一個數組,然后將空格替換成一個特殊的符號"#"(因為后面的替換中,會一次性輸出數組,而數組是用空格分隔各字段,我們要將分隔數組的空格替換成逗號,所以這里將數據中的空格替換成"#") ,給字符串加上雙引號,最后再把空格替換成逗號,把"#"替換為空格。這種方法真是讓人抓狂,我第一次就沒有看明白,尤其是為什么要將空格替換成"#"。
完整的插入數據的程序如下:
#!/bin/bash # # @file write_to_db_mysql.sh # @brief wirte data to database in mysql # @author Mingxing LAI # @version 0.1 # @date 2013-01-20 # USER="root" DATABASE="students" TABLE="students" if [ $# -ne 1 ]; then echo $0 DATAFILE echo exit 2 fi data=$1 while read line; do # query=`echo $line | awk -F, '{ printf("%s,\"%s\",%s,\"%s\"", $1, $2, $3, $4)}'` oldIFS=$IFS IFS=, values=($line) values[1]="\"`echo ${values[1]} | tr ' ' '#' `\"" values[3]="\"`echo ${values[3]}`\"" query=`echo ${values[@]} | tr ' #' ', '` IFS=$oldIFS statement=`echo "INSERT INTO $TABLE VALUES($query);"` # echo $statement mysql -u $USER $DATABASE << EOF INSERT INTO $TABLE VALUES($query); EOF done < $data if [[ $? -eq 0 ]]; then echo "Wrote data into DB" fi
4. 讀取數據
知道怎么在shell 中連接mysql ,也知道了怎么在shell中批量執行sql 語句,讀取數據,就沒有任何難度了。
#!/bin/bash # # @file read_db_mysql.sh # @brief read data from mysql # @author Mingxing LAI # @version 0.1 # @date 2013-01-20 # USER="root" DATABASE="students" TABLE="students" #用tail 去掉表頭 depts=`mysql -u $USER $DATABASE <<EOF | tail -n +2 SELECT DISTINCT dept FROM $TABLE; EOF` for d in $depts; do echo Department: $d result="`mysql -u $USER $DATABASE << EOF set @i:=0; SELECT @i:=@i+1 as rank, name, mark FROM students WHERE dept="$d" ORDER BY mark DESC; EOF`" echo "$result" echo done
我們還可以在mysql語句中,使用選項來控制數據的輸出格式
-H 輸出為html
-X 輸出為xml
如下所示:
#!/bin/bash USER="root" DATABASE="students" TABLE="students" mysql -u $USER $DATABASE -H << EOF select * from $TABLE EOF
html 格式的可讀性比較差,輸出效果如下:
<TABLE BORDER=1><TR><TH>id</TH><TH>name</TH><TH>mark</TH><TH>dept</TH></TR><TR><TD>1</TD><TD>Navin M</TD><TD>98</TD><TD>CS</TD></TR><TR><TD>2</TD><TD> Kavya N</TD><TD>70</TD><TD>CS</TD></TR><TR><TD>3</TD><TD> Nawaz O</TD><TD>80</TD><TD>CS</TD></TR><TR><TD>4</TD><TD>Hari S</TD><TD>80</TD><TD>EC</TD></TR><TR><TD>5</TD><TD>Alex M</TD><TD>50</TD><TD>EC</TD></TR><TR><TD>6</TD><TD>Neenu J</TD><TD>70</TD><TD>EC</TD></TR><TR><TD>7</TD><TD>Bob A</TD><TD>30</TD><TD>EC</TD></TR><TR><TD>8</TD><TD>Anu M</TD><TD>90</TD><TD>AE</TD></TR><TR><TD>9</TD><TD>Sruthi</TD><TD>89</TD><TD>AE</TD></TR><TR><TD>10</TD><TD>Andrew</TD><TD>89</TD><TD>AE</TD></TR></TABLE>
可讀性差也可以理解,因為人家覺得,你沒必要修改么,直接以html形式展示數據就可以了。
id name mark dept 1 Navin M 98 CS 2 Kavya N 70 CS 3 Nawaz O 80 CS 4 Hari S 80 EC 5 Alex M 50 EC 6 Neenu J 70 EC 7 Bob A 30 EC 8 Anu M 90 AE 9 Sruthi 89 AE 10 Andrew 89 AE
xml形式的數據顯示就比較正常了,直接將上面的-H 換成-X,輸出如下:
<?xml version="1.0"?> <resultset statement="select * from students" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <row> <field name="id">1</field> <field name="name">Navin M</field> <field name="mark">98</field> <field name="dept">CS</field> </row> <row> <field name="id">2</field> <field name="name"> Kavya N</field> <field name="mark">70</field> <field name="dept">CS</field> </row> </resultset>
轉自:http://www.lvtao.net/tool/mysql-shell.html