C# 存取 Sybase 資料庫


要讓 dotNet 程式存取 Sybase 資料庫,首先,你必須取得 Sybase PC Client 的幾個DLL檔案:
Sybase.Data.AseClient.dll
sybdrvado11.dll
sybdrvssl.dll

如果是開發者,可能需要先安裝 PC Client<<這裡下載>>,安裝完後再到 Visual Studio的專案下,把 Sybase.Data.AseClient.dll 加入參考


當要執行時,記得把 sybdrvado11.dll、sybdrvssl.dll 一並複製到執行路徑下(Sybase.Data.AseClient.dll 會自動在編譯時加入到路徑下所以不用特別拷貝)
使用時要引用:

using Sybase.Data.AseClient;
程式流程部分
1、建立連線 → 2、建立SQL命令 → 3、建立傳遞參數(如果需要) → 4、傳遞參數值(如果有建立傳遞參數) → 5、執行命令 → 6、取得查詢資料


連線資料庫
//連線資料庫
AseConnection aseCon;
aseCon = new AseConnection("DataSource=ServerIPorName;Port=5000;Database=Windstone;UID=sa;PWD=adminPassw0rd");
aseCon.Open();

SQL指令準備有兩種處理方式
一次性執行或是重複執行。

//一次執行的方式
string employeeNo = "052419";
DateTime inDate = new DateTime(2016,5,1);
AseCommand GetEmplName = new AseCommand("SELECT empl_name FROM employee WHERE empl_no = '" + employeeNo + "' and job_date > '" + inDate.toString("yyyy/MM/dd") + "'", aseCon);
string emplName = (string)GetEmplName.ExecuteScalar();


//重覆執行的方式
DateTime inDate = new DateTime(2016,5,1);
AseCommand GetEmplName  = new AseCommand("SELECT empl_name FROM employee WHERE empl_no = @emplno and job_date > @indate", aseCon);
// 設定使用的變數
AseParameter parm = new AseParameter("@emplno", AseDbType.Char, 6); GetEmplName.Parameters.Add(parm);
parm = new AseParameter("@indate", AseDbType.DateTime);
GetEmplName.Parameters.Add(parm);
//每次讀取只需要改變參數就可以
for (int i = 1 ; i <= 100 ; i++)
{
    GetEmplName.Parameters[0].Value = i.toString().PadLeft(6 , '0');
    GetEmplName.Parameters[1].Value = inDate;
    string emplName = (string)GetEmplName.ExecuteScalar();
    Console.WriteLine("id=" + i.toString().PadLeft(6 , '0') + ",name=" + emplName);
}

從上面例子可以看出,產生SQL語句組成時,如果只會執行一次,就用一次性執行方式比較簡單,但如果同一個查詢會一直不斷改變變數,則使用第二種方式,可以減少一直產生 AseCommand 物件,只要變更 Parameters 內容即可。

如果,SQL指令有同時使用到相同的 Parameter 時可以使用相同的 Parameter 名稱:
下面範例為新增資料,SQL與法需要4個資料作為新增使用,其中msg_time和upload_time使用了相同的參數的資料來源

AseCommand SetMessage  = new AseCommand("INSERT Message (msg_id , msg_text , msg_time , upload_time) VALUES (@msgid , @msgtxt , @msgtime , @msgtime)", aseCon);
AseParameter parm = new AseParameter("@msgid", AseDbType.Integer);
SetMessage.Parameters.Add(parm);
parm = new AseParameter("@msgtxt", AseDbType.Char,200);
SetMessage.Parameters.Add(parm);
//由於3、4參數都是使用@msgtime,所以只要設定一個就好
parm = new AseParameter("@msgtime", AseDbType.DateTime);
SetMessage.Parameters.Add(parm);


接下來就是SQL執行方式
AseCommand 有 4 種執行方式:
  1. ExecuteNonQuery - 執行指令不需要返回資料,適用在 UPDATE/INSERT指令上
  2. ExecuteScalar - 執行指令,只需要返回一筆資料者
  3. ExecuteReader - 執行指令並於每次Read返回一筆資料,有類似 Fetch 指令
  4. ExecuteXmlReader - 執行指令並返回XML格式資料

ExecuteNonQuery

string employeeName = "裝可愛";
string employeeNo = "052419";
AseCommand SetEmplName  = new AseCommand("Update employee SET empl_name = '" + employeeName + "'WHERE empl_no = '" + employeeNo +"'", aseCon);
SetEmplName.ExecuteNonQuery();

ExecuteScalar
前面SQL指令準備方式就有範例,但是要注意的是:假如回傳資料為 string 的話,為什麼使用強型別轉換方式
string emplName = (string)GetEmplName.ExecuteScalar();
而不是使用下面函數轉換呢
string emplName = GetEmplName.ExecuteScalar().toString();
原因在於,當指令執行回傳為NULL(無資料)時,第二種方式會出現 exception 錯誤(Null object refrence),所以強型別轉換,可以確保不會出錯。

ExecuteReader
搭配 AseDataReader 的 Read 與 GetDataType(field_ID) 方式取得資料

AseDataReader reader = GetEmplName.ExecuteReader();
//逐行 fetch
while(reader.Read())
{
    //讀取第一欄位資料
    Console.Write("name=" + reader.GetString(0));
    //讀取第二欄位資料
    Console.Write("age=" + reader.GetInt32(1).toString());
    //.....依此類推.....
}
//關閉AseDataReader
reader.Close();


關閉 Sybase 連線

//關閉連線
aseCon.Close();


錯誤處理:
使用 Try...Catch 包覆 ExecuteNonQuery/ExecuteScalar/ExecuteReader/ExecuteXmlReader 來處理各種錯誤

注意:
由於 Sybase PC Client 提供的 DLL是32位元版本的,所以程式在編譯時要注意編譯成32位元形式,否則執行時可能會無法發生錯誤。


參考資料:





留言

這個網誌中的熱門文章

【研究】列印的條碼為什麼很難刷(掃描)

C# 使用 Process.Start 執行外部程式

統一發票列印小程式