下載connector
MySQL是微軟的死對頭, 所以C#當然不會那麼好心的直接支援MySQL. 所以為了能在C#中使用MySQL, 就必需到MySQL官網下載驅動程式, 下載完後直接安裝即可. 網址如下
https://dev.mysql.com/downloads/connector/net/
C# 設定
開啟C#專案後, 於專案/加入參考/瀏覽, 然後將下面的MySql.Data.dll加入
C:\Program Files (x86)\MySQL\MySQL Connector Net 6.10.5\Assemblies\v4.5.2\MySql.Data.dll
加入後, 在方案總管就會出現MySql.Data了
C# 程式撰寫
class Program { static void Main(string[] args) { string connStr = "server=localhost;uid=帳號;pwd=密碼;database=資料庫"; MySqlConnection conn = new MySqlConnection(connStr); conn.Open(); string cmdStr="select * from wp_terms"; MySqlCommand cmd = new MySqlCommand(cmdStr, conn); MySqlDataReader dr = cmd.ExecuteReader(); while (dr.Read()) { for (int i = 0; i < 4; i++) { Console.Write(dr.GetString(i)); } Console.WriteLine(); } dr.Close() } }
MySqlDataReader非常嚴僅, 產生物件後, 一定要Close(), 才可以再次產生新的 dr. 這在ComboBox時若有 SelectionChanged事件時要特別注意. 最好是ComboBox裏的值都設定好後, 才指定要觸發的事件, 不要把事件寫在xaml裏.
cmbCar.SelectionChanged += new SelectionChangedEventHandler(cmbCar_SelectionChanged);
使用 using
使用 using 建立物件,此類別必需是 IDisposable 介面。底下的 conn 物件使用 using 建立,還是需要 conn.Open(),但不用 conn.Close(),因為離開 using區塊後會自動執行 Dispose 方法,而在 Dispose 就會自動 Close 連線。
不過底下是使用 MySqlDataAdapter(),會自動Open, 所以看不到 Open()的指令。
要取得 conn的連線狀況,可以使用 conn.State,此變數為 ConnectionState.Open 或 ConnectionState.Closeed。
new Thread(() => { using (conn = new MySqlConnection(G.connStr)) { string strCmd = "select * from 員工資料"; DataTable dtShow = new DataTable(); try { new MySqlDataAdapter(strCmd, conn).Fill(dtShow); } catch (Exception ex) { MessageBox.Show(ex.Message, "資料庫查詢錯誤"); } } //底下不會執行 if (conn.State==ConnectionState.Open) { conn.Close(); Console.WriteLine("close database"); } }).Start();
取得新增資料後的 id
如果資料表有 id 欄位,且設定為 Auto Increment,則在新增資料錄時,id 會自動填入,那要如何得知新增的 id 呢?
可在新增一筆資料後,下達 “select last_insert_id()” SQL 語法即可取得。
new MySqlCommand("insert into table (.....) values (.....)").ExecuteNonQuery(); int id = 1; using (MySqlDataReader dr = new MySqlCommand("SELECT LAST_INSERT_ID()", conn).ExecuteReader()) { if (dr.Read()) id = dr.GetInt32(0); }
鎖表
將整個資料表鎖住,不讓其他人查詢新增修改,稱為鎖表。
為什麼要鎖表
填入資料時,若需先查詢資料表的狀況,再決定要填入什麼資料。此時在查詢後及填入前,資料表中途被其他人更新,而導致資料在短暫的時間中被變更。
舉個例子,比如 A 行程查詢資料表中最大的員工編號
select max(員工編號) from 員工資料
當取得最大編號 fl0009 時,下一筆則要填入 fl0010。但在填入之前,可能會被 B 行程捷足先登填入 “fl0010″,這時 A 行程再度填入 fl0010 就會重複。員工編號是一定要設為 Unique 的,所以重複的話就會造成新增失敗。
要解決這個問題,需在 A 行程查詢最大員工編號前進行鎖表,讓其他人 (B行程) 不能讀也不能寫,此時其他人會進入 Blocked 狀態,待 A 行程解鎖後,其他人才會自動開始運作。
鎖表的運作方式如下
new MySqlCommand("lock table 員工資料 write", conn).ExecuteNonQuery(); //開始查詢 //開始處理資料 //開始 insert into table new MySqlCommand("unlock tables", conn).ExecuteNonQuery();
上述在 lock 及 unlock 之間,其他人都無法使用員工資料表,會進入 Blocked。而 A 行程此時也只能使用 “員工資料表”,至於其他資料表都無法使用。
MySQL伺服器預設 30 秒若還沒解鎖,就會傳出timeout 例外錯誤。
MySQL 的鎖非常多,可說是世上最完備的鎖定機制。但本人所接觸的專案只需使用到鎖表,所以只簡單說明此法。其它鎖的使用方法,待日後再補充說明。
常見錯誤
fatal error encountered during command execution
連線字串需加
Allow User Variables=True;
完整字串如下
public static string connStr = string.Format("server={0};uid={1};pwd={2};database={3};convert zero datetime=True;Allow User Variables=True;", domain, dbAccount, dbPassword, dbName);