MySQL驅動安裝及連線

下載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了

csharp_mysql1

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);

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *