1.1 概述 c#程式開發中,資料庫操作無疑是舉足輕重的,資料庫部分的技術點可能占整個c#技術點的1/4。這幾天我一直在研究System.Data.OracleClient.dll反編譯之後的.CS,放棄c#的心都有了,底層代碼不僅全是英文註釋,而且有很多東西看都看不懂,讓我深刻體會封裝的重要性!此 ...
1.1 概述
c#程式開發中,資料庫操作無疑是舉足輕重的,資料庫部分的技術點可能占整個c#技術點的1/4。這幾天我一直在研究System.Data.OracleClient.dll反編譯之後的.CS,放棄c#的心都有了,底層代碼不僅全是英文註釋,而且有很多東西看都看不懂,讓我深刻體會封裝的重要性!此外在做sql語句參數化拼接時,我想在c#中效仿java中的PreparedStatement,但是實現起來困難重重,花了很多時間,最後效果也不理想!放棄繼續深入!這就說明用語言開發和開發語言是兩個不同層次的!
fhbds!
1.2 操作oracle資料庫
任何操作都是建立在先連接上資料庫,連接資料庫需要第三方類庫System.Data.OracleClient.dll,(我已經上傳至文件),添加引用即可使用其中的類和方法。可惜沒有找到關於這個類庫的API,要不然學習這個類庫的阻力就會小很多,雖然微軟官網有一個c#的幫助文檔,但是我看後感覺幫助不大,就像我之前說的不要糾結別人提供給我們的類庫底層到底如何實現的,只要會用就ok了!java中連接資料庫也要導包,連接資料庫的語句在java中叫註冊資料庫驅動!
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Linq; 7 using System.Text; 8 using System.Threading.Tasks; 9 using System.Windows.Forms; 10 using System.Configuration; 11 using Oracle.ManagedDataAccess.Client; 12 using System.Collections; 13 14 15 public static bool ConnectOracle() 16 { 17 bool linkFlag = false; 18 try 19 { 20 //註冊驅動 21 string dataSource = "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=2013-20130829TH)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=oracle)));"; 22 string persistSecurityInfo = "Persist Security Info=True;"; 23 string userID = "User ID=SYSTEM;"; 24 string password = "Password=admin;"; 25 OracleConnection con = new OracleConnection(dataSource + persistSecurityInfo + userID + password); 26 con.Open(); 27 linkFlag = true; 28 return linkFlag; 29 } 30 catch (Exception ex) 31 { 32 ex.ToString(); 33 return linkFlag; 34 35 } 36 }
dataSource中一般只需要根據oracle安裝目錄下的tnsnames.ora文件修改HOST名和SERVICE_NAME就可以了,這個因人而異。第二個連接字元串不需要修改,usrid和password也是根據實際要
連接哪個資料庫來寫,以後可以寫到配置文檔中。
c#中操作資料庫主要用到以下三個類及其其中的方法,分別是:OracleConnection、 OracleDataAdapter、OracleCommand。此外還有一個OracleDataReader,基本上這四個對象就能完成我們
最基本的資料庫操作。
OracleConnection是用來連接資料庫的對象,最重要的2個方法就是open()和close()了。 OracleDataAdapter主要使用是用來執行select查詢語句的,返回時一個查詢的結果集。
下麵這個方法就是通過返回結果集,來獲取資料庫中的數據,c#中獲取數據的方式有點特殊,它是使用了二維數組的方式來存取的,很有一種坐標的感覺!
1 public static string dataSource = "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=2013-20130829TH)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=oracle)));"; 2 public static string persistSecurityInfo = "Persist Security Info=True;"; 3 public static string userID = "User ID=SYSTEM;"; 4 public static string password = "Password=admin;"; 5 public static string connectionString = dataSource + persistSecurityInfo + userID + password; 6 public static DataSet Query(string connectionString, string SQLString) 7 { 8 using (OracleConnection connection = new OracleConnection(connectionString)) 9 { 10 DataSet ds = new DataSet(); 11 try 12 { 13 connection.Open(); 14 OracleDataAdapter command = new OracleDataAdapter(SQLString, connection); 15 command.Fill(ds, "ds"); 16 } 17 catch (OracleException ex) 18 { 19 throw new Exception(ex.Message); 20 } 21 finally 22 { 23 if (connection.State != ConnectionState.Closed) 24 { 25 connection.Close(); 26 } 27 } 28 return ds; 29 } 30 }
測試腳本:
1 SET DEFINE OFF; 2 Insert into STUDENT 3 (SID, SNAME, SAGE, SPASS) 4 Values 5 ('100', '李四', '18', '123456'); 6 Insert into STUDENT 7 (SID, SNAME, SAGE, SPASS) 8 Values 9 ('003', '王五', '18', '123456'); 10 Insert into STUDENT 11 (SID, SNAME, SAGE, SPASS) 12 Values 13 ('004', '趙六', '18', '123456'); 14 Insert into STUDENT 15 (SID, SNAME, SAGE, SPASS) 16 Values 17 ('005', '張光烈', '18', '123456'); 18 Insert into STUDENT 19 (SID, SNAME, SAGE, SPASS) 20 Values 21 ('006', '魏大勇', '18', '123456'); 22 Insert into STUDENT 23 (SID, SNAME, SAGE, SPASS) 24 Values 25 ('007', '朱永博', '18', '123456'); 26 Insert into STUDENT 27 (SID, SNAME, SAGE, SPASS) 28 Values 29 ('001', '張三', '18', '123456'); 30 Insert into STUDENT 31 (SID, SNAME, SAGE, SPASS) 32 Values 33 ('520', '李雲龍', '100', '1314'); 34 COMMIT;
測試代碼:
1 private void button2_Click(object sender, EventArgs e) 2 { 3 string sql1 = "select * from student where sid='520'"; 4 DataSet ds1 = new DataSet(); 5 ds1 = Query(connectionString, sql1); 6 textBox1.Text += "此查詢語句一共查到["+ds1.Tables[0].Rows.Count.ToString()+"]條記錄!"; 7 textBox1.Text += "此查詢語句一共查到[" + ds1.Tables[0].Columns.Count.ToString() + "]個欄位!"; 8 textBox1.Text += "此查詢語句查到第一張表,第一條記錄的欄位“SNAME”的值是[" + ds1.Tables[0].Rows[0]["SNAME"].ToString().Trim()+"]!"; 9 textBox1.Text += "此查詢語句查到的第二個欄位是[" + ds1.Tables[0].Columns[1].ToString() + "]!"; 10 11 12 }
輸出:
其中ds1.Tables[0].Rows.Count就能實現查詢語句返回的記錄數,不需要另外想什麼方式!
OracleCommand是用來執行insert 、update、delete語句的,返回值是影響的行數!主要發揮作用的是OracleCommand的ExecuteNonQuery()方法。
1 //執行update insert delete語句,失敗了返回-1,成功了返回影響的行數,註意:自動commit 2 public static int ExecuteNonQuery(string connectionString, string SQLString) 3 { 4 5 using (OracleConnection connection = new OracleConnection(connectionString)) 6 { 7 int val = -1; 8 try 9 { 10 connection.Open(); 11 OracleCommand cmd = new OracleCommand(SQLString, connection); 12 val = cmd.ExecuteNonQuery(); 13 cmd.Parameters.Clear(); 14 } 15 catch (OracleException ex) { 16 throw new Exception(ex.Message); 17 } 18 finally 19 { 20 if (connection.State != ConnectionState.Closed) 21 { 22 connection.Close(); 23 } 24 } 25 return val; 26 } 27 }
測試代碼:
1 private void button3_Click(object sender, EventArgs e) 2 { 3 4 string sid = "520"; 5 string sname = "李雲龍"; 6 int age = 100; 7 string password = "1314"; 8 9 try 10 { 11 string sql = @"Insert into STUDENT(SID, SNAME, SAGE, SPASS)Values('001', '張三', '18', '123456')"; 12 //string sql = @"update student set sname='韓信' where sid='001'"; 13 //string sql = @"delete student where sid='001'"; 14 // string sql = "insert into student(SID,SNAME,SAGE,SPASS) values('" + sid + "','" + sname + "','" + age + "','" +password+ "')"; 15 int count = ExecuteNonQuery(connectionString, sql); 16 textBox1.Text = count.ToString(); 17 } catch(Exception ex){ 18 textBox1.Text= ex.Message; 19 } 20 }
此外OracleCommand還有一個ExecuteScalar()方法,返回的是object對象,返回的是查詢到的第一條記錄的第一個欄位的值,這個作用主要是用來精確查找的,也就是不會出現select *,
否則意義何在?
1 //返回查詢到第一個對象 2 public static object GetCount(string connectionString, string SQLString) 3 { 4 using (OracleConnection connection = new OracleConnection(connectionString)) 5 { 6 using (OracleCommand cmd = new OracleCommand(SQLString, connection)) 7 { 8 try 9 { 10 connection.Open(); 11 object obj = cmd.ExecuteScalar(); 12 if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value))) 13 { 14 return null; 15 } 16 else 17 { 18 return obj; 19 } 20 } 21 catch (OracleException ex) 22 { 23 throw new Exception(ex.Message); 24 } 25 finally 26 { 27 if (connection.State != ConnectionState.Closed) 28 { 29 connection.Close(); 30 } 31 } 32 } 33 } 34 }
測試代碼:
1 string sql1 = "select spass from student"; 2 object count = GetCount(connectionString,sql1); 3 textBox1.Text = count.ToString();
有時候我們並不在意查到的值是什麼,在意查不查的到只要稍微修改就可以了!
1 //判斷某個對象是否存在 2 public static bool Exists(string connectionString, string strSql) 3 { 4 object obj =GetCount(connectionString, strSql); 5 int cmdresult; 6 if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value))) 7 { 8 cmdresult = 0; 9 } 10 else 11 { 12 cmdresult = int.Parse(obj.ToString()); 13 } 14 if (cmdresult == 0) 15 { 16 return false; 17 } 18 else 19 { 20 return true; 21 } 22 }
測試代碼:
1 string sql1 =@"select spass from student where sname='劉邦'"; 2 bool flag = Exists(connectionString, sql1); 3 textBox1.Text = flag.ToString();
1.3 參數化拼接SQL語句
< not end >