ADO.NET是一组类库,让我们通过程序的方式访问数据库。SYSTEM.DATA这个类提供了统一的接口访问Oracle MSSQL Access。像SYSTEM.IO类操作文件一样。
**connection 连接准备环境。
获取连接字符串
连接的属性(字符串)=实现准备一个连接字符串(服务器实例;数据库;用户名;密码)4个东西 数据源 数据库 用户名 密码
可以con.ConnectionString,也可以直接将次字符串放在在构造函数里。因为构造函数就是为字段赋值的
从配置文件中:
获取连接字符串,1,建一个txt,2改后缀名udl3双击配置测试4改回来 打开txt就有了
http://blog.csdn.net/chaoyuan899/article/details/8272021
连接打开 con.open 只能打开一次
连接关闭 con.close 可以关闭多次,关闭数据库,而不是关闭连接哦。
释放资源 con.dipose 数据库不在本机内存,是这种连接一种非托管资源,需要手动释放 用using把 connection括起来,非常占用数据资源。
数据库的关闭con.close为数据库的关闭,还以open再close,但是连接没有关闭。如果dispose一下,要重新连接才能操作。
1 using System; 2 using System.Collections.Generic; 3 using System.Data.SqlClient; 4 using System.Linq; 5 using System.Text; 6 namespace condb 7 { 8 class Program 9 { 10 static void Main(string[] args) 11 { 12 string str = @"server=.LK;database=master;uid=sa;pwd=123"; 13 //也可以conn.ConnectionString = str; 14 SqlConnection conn=new SqlConnection(str); 15 conn.Open(); 16 Console.WriteLine("打开master数据库了"); 17 conn.Close(); 18 conn.Dispose(); 19 Console.ReadKey(); 20 } 21 } 22 }
1 using System; 2 using System.Collections.Generic; 3 using System.Data.SqlClient; 4 using System.Linq; 5 using System.Text; 6 namespace condb 7 { 8 class Program 9 { 10 static void Main(string[] args) 11 { 12 //也可以conn.ConnectionString = str; 13 //@转义字符 14 // windows身份验证字符串1,server没有实例名2,用户名密码换成 intergrated security=true; 15 //连接字符串的获取1,建一个txt,2改后缀名udl3双击配置测试4改回来 打开txt就有了 16 string str = @"server=.LK;database=master;uid=sa;pwd=123"; 17 //using (){}代替了close和dispose 把连接放()内,{}内放其他操作 18 using(SqlConnection conn = new SqlConnection(str)) 19 { 20 //判断打开关闭状态 21 if (conn.State == System.Data.ConnectionState.Closed) 22 { 23 conn.Open(); 24 } 25 Console.WriteLine("打开master数据库了"); 26 } 27 //conn.Close(); 28 //conn.Dispose(); 29 Console.ReadKey(); 30 } 31 } 32 }
**Command 执行 sql 增删改
增加删除修改ExecuteNonquery
读取单个 Executescalar
读取一行 ExecuteRead
string sql_txt=""
using( SqlCommand cmd=newSqlComand(sql_txt,con)){int res=cmd.excuteNonQuery()} 参数为sql语句和连接环境con。
ExecuteNonQuery()
返回受影响行数,和信息一样。增删改 select返回-1
ExecuteScalar()
1,查
一行一列的值或者数据条目数
返回查询到的数据 不知道数据类型,可以用Object 接收。注意:只能显示查询到的结果的第一行第一列一个数据,而不是一行数据。常常用来查询select count(*) 检测行数,或者该字段是否已经存在。
1 using System; 2 using System.Collections.Generic; 3 using System.Data.SqlClient; 4 using System.Linq; 5 using System.Text; 6 namespace condb 7 { 8 class Program 9 { 10 static void Main(string[] args) 11 { 12 //也可以conn.ConnectionString = str; 13 //@转义字符 14 // windows身份验证字符串1,server没有实例名2,用户名密码换成 intergrated security=true; 15 //连接字符串的获取1,建一个txt,2改后缀名udl3双击配置测试4改回来 打开txt就有了 16 string str = @"server=.LK;database=lianxi;uid=sa;pwd=123"; 17 //using (){}代替了close和dispose 把连接放()内,{}内放其他操作 18 using(SqlConnection conn = new SqlConnection(str)) 19 { 20 //判断打开关闭状态 21 if (conn.State == System.Data.ConnectionState.Closed) 22 { 23 conn.Open(); 24 } 25 // string sq_txt = "insert into t_score values(3,'第三次')"; 26 string sq_txt = "select scoreName from t_score "; 27 using( SqlCommand cmd=new SqlCommand(sq_txt,conn)) 28 { 29 // int res=cmd.ExecuteNonQuery(); 30 object res = cmd.ExecuteScalar(); 31 Console.WriteLine(res); 32 } 33 34 35 } 36 //conn.Close(); 37 //conn.Dispose(); 38 Console.ReadKey(); 39 } 40 } 41 }
2,增(插入)能插入会报错
查当,为插入的时候,显示的只是受影响行数,此时用ExecuteScalar()并没有,为null。
但是还是会插入到数据库。
inserted临时表
常用:若想插入的时候同时显示并返回(在数据库结果中)这条插入的的某个字段,常常用到这行的自动增长的id。
数据库有一个语句在vlaues前面output inserted.返回的字段。inserted临时表中output。
INSERT into t_score output inserted.scoreName values(6,'第六次')
set nocount on 插入查看等语句消息中显示多少行 给去掉,同时执行。就不会显示多少行受影响。解决了好多行“1行受影响”消息。。。
读取数据:1,查询一行数据或者整个数据库的数据
ExecuteReader()
返回一个SqlDataReader对象,这个对象并没有返回所有的数据,而是提供了访问所有数据的属性HasRows,Read
Reader.FieldCount。一行数据的字段数
读取数据excuteScalar()返回的是某个数据,大部分是返回一张行数据 = sqldatareader对象[列名1 别名] 对象[列名2]
当然这个索引可以用列名,也可以用[0] [1] [2]对一些没有列名的列也能查得到。
Reader.GetInt32(列序号)直接获取第几列的元素.。和Reader[]功能一样。循环一下,也可以实现全部读取。
SqlDataReader数据连接方式: 数据库游标/查询结果放在数据库服务器而非本机上 一旦连接断开将无法再读取/这样做的好处是无论读取多少条数据 对程序所占用内存几乎没有影响
这类方法类型一致必须:数据库为bit GetBoolen 为int GetInt32 为varchar GetString 必须一致 先判断null reader.IsDbNull
数据库的类型和c#中的类型 System.Data.DbType(枚举)像对应转化。string--nchar varchar
using System; using System.Collections.Generic; using System.Data.SqlClient; using System.Linq; using System.Text; namespace condb { class Program { static void Main(string[] args) { string str = @"server=.LK;database=lianxi;uid=sa;pwd=123"; string sq_txt = "select * from t_score "; using(SqlConnection conn = new SqlConnection(str)) { if (conn.State == System.Data.ConnectionState.Closed) { conn.Open(); } using( SqlCommand cmd=new SqlCommand(sq_txt,conn)) { //SqlDataReader cmd对摸个数据库进行执ExecuteReader行命令的时候,返回一个sqldataReader对象。 //此对象对数据库进行判断bool(有HasRows和read()在数据库添加每行数据的指针),包含了一些非托管资源,需要dispose //这个对象还有和[] 来读取每个列对应的列值。reader 就是仿佛是一个一行数据的集合,索引为read数据库的时候创建的。 SqlDataReader reader=cmd.ExecuteReader(); if (reader.HasRows) { //当这个对象进行读Read的时候,会在数据库缓存表加上一个指针,每Read一次,指针就会往下移动一个。 //前提已经确定了数据库和表,不需要担心Read的哪个个表哪个个数据库 if (reader.Read()) //若为循环全部显示 取代if判断,换为while循环,因为不知多少数据,不能用for { //返回object 类型。索引为数据库中的列名 Console.WriteLine( reader["scoreid"].ToString()+ " " +reader["scoreName"].ToString()); } } } } Console.ReadKey(); } } }
结果
数据库 读取 备份 导出
1 using System; 2 using System.Collections.Generic; 3 using System.Data.SqlClient; 4 using System.IO; 5 using System.Linq; 6 using System.Text; 7 namespace condb 8 { 9 class Program 10 { 11 static void Main(string[] args) 12 { 13 string str = @"server=.LK;database=student;uid=sa;pwd=123"; 14 string sq_txt = "select * from stu_infor "; 15 //考虑写进去的格式 16 using (FileStream file = new FileStream("wenjian.dat", FileMode.Create, FileAccess.Write)) 17 { 18 using (StreamWriter writer = new StreamWriter(file, Encoding.UTF8)) 19 { 20 //List<string> list=new List<string>(); 21 //开始读取 22 writer.WriteLine("{0}点开始读取 ", DateTime.Now); 23 using (SqlConnection conn = new SqlConnection(str)) 24 { 25 if (conn.State == System.Data.ConnectionState.Closed) 26 { 27 conn.Open(); 28 } 29 using (SqlCommand cmd = new SqlCommand(sq_txt, conn)) 30 { 31 //SqlDataReader cmd对摸个数据库进行执ExecuteReader行命令的时候,返回一个sqldataReader对象。 32 //此对象对数据库进行判断bool(有HasRows和read()在数据库添加每行数据的指针),包含了一些非托管资源,需要dispose 33 //这个对象还有和[] 来读取每个列对应的列值。reader 就是仿佛是一个一行数据的集合,索引为read数据库的时候创建的。 34 SqlDataReader reader = cmd.ExecuteReader(); 35 if (reader.HasRows) 36 { 37 //当这个对象进行读Read的时候,会在数据库缓存表加上一个指针,每Read一次,指针就会往下移动一个。 38 //前提已经确定了数据库和表,不需要担心Read的哪个个表哪个个数据库 39 while (reader.Read()) 40 {//返回object 类型。索引为数据库中的列名,也可以[0] [1] [2] 41 //对一行数据进行遍历,添加 42 //此时不适合用静态类File.Append方法,开一次关一次资源损坏大。需要准备一个流写在开始。 43 for (int i = 0; i < reader.FieldCount - 1; i++) 44 { 45 writer.Write("{0}|", reader[i]); 46 // list.Add(reader[i].ToString()); 47 } 48 writer.WriteLine(reader[reader.FieldCount - 1]); 49 } 50 } 51 } 52 } 53 } 54 } 55 Console.ReadKey(); 56 } 57 } 58 }
用到list集合。
1 using System; 2 using System.Collections.Generic; 3 using System.Data.SqlClient; 4 using System.IO; 5 using System.Linq; 6 using System.Text; 7 namespace DB_Read_Write_XML 8 { 9 class Program 10 { 11 static void Main(string[] args) 12 { 13 string str = @"server=.LK;database=student;uid=sa;pwd=123"; 14 string sq_txt = "select * from stu_infor "; 15 using (FileStream file = new FileStream("wenjian.dat", FileMode.Create, FileAccess.Write)) 16 { 17 using (StreamWriter writer = new StreamWriter(file, Encoding.UTF8)) 18 { 19 writer.WriteLine("{0}点开始读取 ", DateTime.Now); 20 using (SqlConnection conn = new SqlConnection(str)) 21 { 22 if (conn.State == System.Data.ConnectionState.Closed) 23 { 24 conn.Open(); 25 } 26 using (SqlCommand cmd = new SqlCommand(sq_txt, conn)) 27 { 28 SqlDataReader reader = cmd.ExecuteReader(); 29 if (reader.HasRows) 30 { 31 while (reader.Read()) 32 { 33 List<string> list = new List<string>(); 34 for (int i = 0; i < reader.FieldCount; i++) 35 { 36 list.Add(reader[i].ToString()); 37 } 38 writer.WriteLine(string.Join("|", list.ToArray())); 39 } 40 } 41 } 42 } 43 } 44 } 45 Console.ReadKey(); 46 } 47 } 48 }
读取为XML格式,我用序列化,出错,尚未解决。
1 namespace DB_Read_Write_XML 2 { 3 [Serializable] 4 public class row 5 { 6 public int stu_id { get; set; } 7 public string name{ get; set; } 8 public int age { get; set; } 9 public string gender { get; set; } 10 public DateTime time { get; set; } 11 public int p_order { get; set; } 12 public int p_delete { get; set; } 13 } 14 class Program 15 { 16 static void Main(string[] args) 17 { 18 string str = @"server=.LK;database=student;uid=sa;pwd=123"; 19 string sq_txt = "select * from stu_infor "; 20 XmlSerializer serializer=new XmlSerializer(typeof(List<string>)); 21 using (FileStream file = new FileStream("wenjian.xml", FileMode.Create, FileAccess.Write)) 22 { 23 //using (StreamWriter writer =new StreamWriter(file,Encoding.Default)) 24 //{ 25 // writer.WriteLine("<ROOT>"); 26 27 using (SqlConnection conn = new SqlConnection(str)) 28 { 29 if (conn.State == System.Data.ConnectionState.Closed) 30 { 31 conn.Open(); 32 } 33 using (SqlCommand cmd = new SqlCommand(sq_txt, conn)) 34 { 35 SqlDataReader reader = cmd.ExecuteReader(); 36 if (reader.HasRows) 37 { 38 List<row> list = new List<row>(); 39 40 while (reader.Read()) 41 { 42 int i1= reader.GetInt32(0); 43 string st = reader.GetString(1); 44 int i2= reader.GetInt32(2); 45 string c1= reader.GetString(3); 46 DateTime d1= reader.GetDateTime(4); 47 int i3= reader.GetInt32(5); 48 int i4= reader.GetInt32(6); 49 row r = new row() 50 { 51 stu_id = i1, 52 name=st , 53 age =i2, 54 gender =c1, 55 time =d1 , 56 p_order=i3, 57 p_delete = i4 58 }; 59 list.Add(r); 60 } 61 serializer.Serialize(file, list); 62 } 63 } 64 } 65 //} 66 } 67 Console.ReadKey(); 68 } 69 } 70 }
用Xdoc,Xele来解决.此时我犯了错误,已经标示出来
对应程序
1 namespace DB_Read_Write_XML 2 { 3 internal class Program 4 { 5 private static void Main(string[] args) 6 { 7 string str = @"server=.LK;database=student;uid=sa;pwd=123"; 8 string sq_txt = "select * from stu_infor "; 9 XDocument xDoc = new XDocument(); 10 XElement xroot = new XElement("root"); 11 xDoc.Add(xroot); 12 13 //xrow.Value = 18; 14 //using (FileStream file = new FileStream("wenjian.xml", FileMode.Create, FileAccess.Write))//有了xdoc创建,就不用流创建了 15 //{ 16 using (SqlConnection conn = new SqlConnection(str)) 17 { 18 if (conn.State == System.Data.ConnectionState.Closed) 19 { 20 conn.Open(); 21 } 22 using (SqlCommand cmd = new SqlCommand(sq_txt, conn)) 23 { 24 using (SqlDataReader reader = cmd.ExecuteReader()) 25 { 26 if(reader.HasRows)//read.HasRows永远成立。此时不能用while,会造成死循环,只需要判断一下往下执行就好 27 { 28 while (reader.Read()) 29 { 30 XElement xrow = new XElement("row"); 31 // xrow.Value = 18;是错误的错误 1 无法将类型“int”隐式转换为“string” 32 //可用参数来解决这个麻烦,节点名和直接赋值,后面这个参数是object类型 33 int stuid = reader.GetInt32(0); 34 XElement x1 = new XElement("id", stuid); 35 string xingbie = reader.GetString(1); 36 XElement x2 = new XElement("ming", xingbie); 37 int nianling = reader.GetInt32(2); 38 XElement x3 = new XElement("nling", nianling); 39 string xb = reader.GetString(3); 40 XElement x4 = new XElement("xingbie",xb); 41 DateTime tm = reader.GetDateTime(4); 42 XElement x5 = new XElement("shijian", tm); 43 int order = reader.GetInt32(5); 44 XElement x6 = new XElement("paixu", order); 45 int delete = reader.GetInt32(6); 46 XElement x7 = new XElement("schu", delete); 47 48 xrow.Add(x1, x2, x3, x4, x5, x6, x7); 49 xroot.Add(xrow); 50 51 } 52 } 53 } 54 } 55 } 56 xDoc.Save("1.xml"); 57 } 58 } 59 }
结果:
.....
reader.HasRows是只判断这个表是否有数据,不会再判断。
而reader.read()一行一行的读,能读到数据就会返回true,读不到就返回faulse
注入漏洞攻击与参数化查询
注入漏洞,就是读者输入账号密码时,1‘or ’1=’1。作为c#的变量接受到数据库条件中。
select count(*) from biao where name='mianzi' and pwd='mima'
若mimi=1‘or ’1=’1
select count(*) from biao where name='mianzi' and pwd='1‘or ’1=’1',这句sql永远成立, and or是同一级别,先执行and两旁再or。
如果pwd=@pwd让密码当做数据库的一个变量,先执行这个变量。就不会出现问题。
select count(*) from biao where name='@name' and pwd='@pwd'
也就是讲c#的变量为数据库的@变量赋值就能解决了。
将c#变量赋值给数据库变量做为参数,需要SqlParameter类。专门处理sql命令中的参数(赋值给数据库变量)。
这个sqlparameter是cmd的一个属性。因为cmd有了con和sql语句,确定了连接和执行命令,所以对这条执行命令内的参数操作。这样记忆。
cmd.Parameters.add。
就像cmd.ExecuteNonQuery,cmd.ExecuteScalar一样也是cmd的一个元素。
internal class Program { private static void Main(string[] args) { string name = Console.ReadLine(); string mima = Console.ReadLine(); string str = @"server=.LK;database=student;uid=sa;pwd=123"; string sq_txt = "select count(*) from stu_infor where name=@uid and age=@pwd";//这里@uid和@pwd不带单引号,本身就是变量 int res; using (SqlConnection conn = new SqlConnection(str)) { if (conn.State == System.Data.ConnectionState.Closed) { conn.Open(); } using (SqlCommand cmd = new SqlCommand(sq_txt, conn)) { SqlParameter sqname=new SqlParameter("@uid",SqlDbType.NVarChar); sqname.Value = name; SqlParameter sqmima=new SqlParameter("@pwd",SqlDbType.Int); sqmima.Value = mima; cmd.Parameters.Add(sqname); cmd.Parameters.Add(sqmima); res= Convert.ToInt32(cmd.ExecuteScalar()); } if (res > 0) { Console.WriteLine("登录成功"); } else { Console.WriteLine("用户名或者密码不对"); } Console.ReadKey(); } } }
DataReader 只读只进 结果集,一条一条读取数据
DataAdapter 一个封装上面3个对象的一个对象
DataSet:临时数据库。断开数据库就操作这个DateSet
select * from sys.objects 查看系统视图
用命令行
一,登录:sqlcmd -S .实例
1> sql语句
2>sql语句
二,开启关闭某个实例的服务,
net start/stop mssql$实例名
连接服务器实例;数据库;用户名;密码四个东西,身份验证(sql验证,windows验证)
System.Data.Common.DbConnectin 是Data.SqlClient.Sqlconnection 和Data.OdbcConnection 和Data.OleConnection的父类,工厂模式,可以用这个父类变量接受不同的数据库,Oracle:08右键添加引用,10的时候需要装一个第三方的插件dll