話說這Access數據庫確實是有點年代了,前面在深圳的一家放射醫療公司,數據庫用的Access,后面在我的建議下,換成了SQLite。用SQLite多舒服,不用裝Runtime,還可以用EF。Access得裝Runtime,也用不了EF。
回到長沙后,找了一家工業儀器的公司,發現也是用的Access數據庫。
結果模糊查詢 的時候,發現不對勁,這里總結幾點C#在使用Access數據庫時可能會遇到的問題
1、連接字符串
Access 2007 (文件后綴為.accdb)
沒有密碼的情況
1 Provider = Microsoft.Ace.OleDb.12.0;Data Source={0};Persist Security Info=False;
有密碼的情況
1 Provider = Microsoft.Ace.OleDb.12.0;Data Source={0};Jet OleDb:DataBase Password='{1}';
說明:實際使用時,用string.Format()函數將{0}替換成數據庫路徑,{1}替換成密碼即可
實際如下:
1 Provider = Microsoft.Ace.OleDb.12.0;Data Source=D:\test.accdb;Jet OleDb:DataBase Password='123';
Access 2003 (文件后綴為.mdb)
將Provider替換為Microsoft.Jet.OleDb.4.0即可,如下
1 Provider=Microsoft.Jet.OleDb.4.0;Data Source=D:\test.accdb;Jet OleDb:DataBase Password='123';
2、不使用OleDbParameter時,日期需要使用##包起來
有時候可能查詢的語句比較簡單,就不想使用參數的形式的,直接去拼SQL語句,如果判斷的條件是日期,就要用##將日期包起來,不然會報錯,如下
1 var sql = "Select * From Test Where Date BETWEEN #2021/03/13# AND #2021/03/14#";
使用了參數,就可以不用帶#。如下
1 var sql = "Select * From Test Where Date BETWEEN #@StartDate# AND #@EndDate#"; 2 3 System.Data.OleDb.OleDbParameter[] parameters = new System.Data.OleDb.OleDbParameter[] 4 { 5 new System.Data.OleDb.OleDbParameter("@StartDate","2021/03/13"), 6 new System.Data.OleDb.OleDbParameter("@EndDate","2021/03/14") 7 };
3、使用OleDbParameter時,日期需要傳字符串
上面已經使用過參數了,這里需要注意的時,不能直接傳DateTime類型,而是需要傳入字符串,不然會報錯。這次就是在公司遇到這個問題,調試了好久,因為太久沒用Access,不記得了。
4、在Access里執行查詢時,通配符使用* ,在C#中,使用%
例如在Access中直接執行模糊查詢語句,查詢包含z的姓名
1 Select * from Test Where Name Like '*z*';
在C#中需要將*替換成%,如下:
1 var sql = Select * from Test Where Name Like '%z%';
5、使用Where false可以查詢表結構
1 var sql = "Select * from Test Where false";
這操作我以前還不知道,試了下SQL Server是不支持這操作的。
6、查詢語句包含單引號' 時,需要用兩個單引號 ''
如:
1 Select * from xx where Des = 'what's'
要寫成
Select * from xx where Des = 'what''s'
7、判斷表是否存在
調用OleDbConnection的GetOleDbSchemaTable函數,如下:
tableName就是要查詢的表名
1 OleDbConnection con = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=a.mdb"); 2 con.Open(); 3 var dt = con.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, tableName, "TABLE" });
GetOleDbSchemaTable會返回一個數據源架構信息的DataTable,再判斷DataTable的行數是否大於0即可判斷指定的表是否存在
1 if(dt.Rows.Count > 0) 2 { 3 Console.WriteLine("Exist") 4 } 5 else 6 { 7 Console.WriteLine("Not exist") 8 }
通過這種方式也可以查詢某個表是否存在某一列
tableName是要查詢的表名,columnName是要查詢的列名
1 con.GetOleDbSchemaTable(OleDbSchemaGuid.Columns, new object[] { null, null, tableName, columnName });
到新公司也沒寫啥項目,目前就遇到這幾個問題吧,做個總結。