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 >