學(xué)習(xí)目的:通過程序訪問數(shù)據(jù)庫(kù) ,ADO.NET就是一組類庫(kù),
--》connection 用來連接數(shù)據(jù)庫(kù)的類
語法:首先需要一個(gè)連接字符串
-->以SQL server身份驗(yàn)證連接
string sqlconnection=@"Data Source=實(shí)例名服務(wù)名;Initial Catalog=數(shù)據(jù)庫(kù)名;User Id=用戶名;PassWord=密碼";
--》以windows身份驗(yàn)證連接
string sqlconnection=@"Data Source=實(shí)例名服務(wù)名;Initial Catalog=數(shù)據(jù)庫(kù)名;Integrated security=true";
然后需要一個(gè)連接對(duì)象
SqlConnection con=new SqlConnection(連接字符串) --connection是對(duì)硬盤的數(shù)據(jù)進(jìn)行處理所以要釋放資源,調(diào)用close(),dispose()方法或using()
打開連接用Open()
連接都需要Dispose()
查看連接狀態(tài)用 State 連接打開會(huì)返回true,否則返回false
-->Command 用來執(zhí)行SQL語句
首先需要一句SQL語句
string sql="insert 。。。。。";
然后需要一個(gè)執(zhí)行對(duì)象 (也需要釋放資源)
SqlCommand cmd=new SqlCommand(Sql語句)
SqlCommand需要提高SQL語句和一個(gè)連接通道(就是連接對(duì)象)
常用的三個(gè)方法
--》ExecuteNonQuery() 處理增(insert)、 刪(delete/drop)、 改(update/alter),返回受影響行數(shù),不可以處理查詢
--》ExecuteScalar() 處理查詢,返回首行首列的值,值返回一個(gè)值,增、刪、改也可以執(zhí)行但是返回的值永遠(yuǎn)是-1
--》ExcuteReader() 處理查詢,返回DataReader對(duì)象
一、ADO.NET其實(shí)就是一個(gè)類庫(kù)
專門用來處理數(shù)據(jù)庫(kù)的類庫(kù)
System.Data下還有很多命名空間
odbc
oledb
sqlClient
注:推薦《ADO.Net 2.0 技術(shù)內(nèi)幕》
2、數(shù)據(jù)庫(kù)(數(shù)據(jù)庫(kù)管理軟件)
->SQL Server 2008
->架構(gòu)(dbo.Table)
->數(shù)據(jù)庫(kù)
-》表
--》使用時(shí)先要連接到SQL Server
首先要連接字符串
SQL Server身份驗(yàn)證
server=機(jī)器名/實(shí)例名;database=數(shù)據(jù)庫(kù);uid=sa;pwd=密碼
windows身份驗(yàn)證
Data Source=機(jī)器名/實(shí)例名;Initial Catalog=數(shù)據(jù)庫(kù)名;Integrated security=true=true
3、使用ADO.Net連接的時(shí)候,需要使用一個(gè)SqlConnection的對(duì)象只起到連接數(shù)據(jù)庫(kù)
-》第一步準(zhǔn)備連接字符串
string strcon=@"Data Source=./sqlexPRess;Initial Catalog=MyName;User Id=sa;Password=1234";
->準(zhǔn)備連接通道
引用命名空間 system.Data.sqlclient;
SqlConnection con=new SqlConnection(strcon);
->Open進(jìn)行打開連接 (盡可能晚的打開,盡可能早的關(guān)閉)
-》關(guān)閉連接
Close()
釋放資源
Dispose()
4、執(zhí)行SQL語句
SqlCommand對(duì)象
-》首先需要一個(gè)SQL語句
-》需要一個(gè)連接對(duì)象
SqlCommand cmd=new SqlCommand(Sql語句,連接通道)
1、SqlCommand有三個(gè)常用的執(zhí)行SQL語句的方法
-》ExecuteNonQuery
一般執(zhí)行得到返回受影響行數(shù)的方法
-》一般處理增、刪、改等操作
-》返回一個(gè)值,受影響行數(shù),如果執(zhí)行查詢的SQL語句返回-1
2、 ExecuteSalar
執(zhí)行查詢,會(huì)返回查詢結(jié)果集的第一行第一列對(duì)應(yīng)的值,其他行其他列會(huì)忽略掉,一般使用聚合查詢時(shí)只要得到一個(gè)結(jié)果用到
返回值是一個(gè)Object類型,需要轉(zhuǎn)換(拆箱),轉(zhuǎn)換時(shí)用convert,不要強(qiáng)轉(zhuǎn),有時(shí)候會(huì)返回字符串形式的數(shù)字,強(qiáng)轉(zhuǎn)的話會(huì)出錯(cuò),得不到結(jié)果
--》得到自動(dòng)增長(zhǎng)ID
在添加數(shù)據(jù)的時(shí)候,在values前使用 output inserted.主鍵字段
insert into 表名 (字段1,字段2..) output inserted.主鍵名 values(值1,值2....)
2、 SqlDataReader
當(dāng)ExecuteReader執(zhí)行的時(shí)候會(huì)通過SqlConnection連接通道連接數(shù)據(jù)庫(kù)然后把SQL語句傳過去,數(shù)據(jù)庫(kù)里有一個(gè)SQL server執(zhí)行引擎,這個(gè)引擎會(huì)解析傳進(jìn)來的SQL語句然后執(zhí)行,
到數(shù)據(jù)庫(kù)里查找數(shù)據(jù),查找到數(shù)據(jù)之后不是一次性全都拿出來倒到內(nèi)存里,這個(gè)引擎有個(gè)臨時(shí)緩存,它會(huì)先拿一部分的數(shù)據(jù)到這個(gè)臨時(shí)緩存里,然后等待應(yīng)用程序(客戶端)執(zhí)行read()進(jìn)行讀取數(shù)據(jù)
-->HasRows()
判斷是否有數(shù)據(jù),返回一個(gè)BOOL值,不會(huì)連接數(shù)據(jù)庫(kù)
-->Read()
讀取查到的數(shù)據(jù),每執(zhí)行一次Read,這個(gè)指向數(shù)據(jù)的“標(biāo)記”由SqlDataReader對(duì)象控制,這個(gè)“標(biāo)記“就會(huì)下移一次,
如果有數(shù)據(jù),就返回一個(gè)truename可以使用Get...方法獲得對(duì)應(yīng)列上的數(shù)據(jù),如果下移以后沒有數(shù)據(jù),那么就返回一個(gè)false
注:使用get方法的時(shí)候如果用的不是object 類型接收,如果數(shù)據(jù)是null會(huì)拋異常,
獲取值通過列號(hào)來獲取,列號(hào)從0開始
-->GetValue(列號(hào)) 獲得指定列好號(hào)對(duì)應(yīng)的值
--》getint32(列號(hào)) 獲得指定列號(hào)的整形形式的值
--》getstring(列號(hào)) 獲得指定列號(hào)的字符串 形式的值
.......
--》還可以直接通過下標(biāo)形式來獲取值
SqlDataReader對(duì)象[列號(hào)]
二、注入漏洞攻擊
對(duì)于用戶登錄的實(shí)現(xiàn),提供SQL語句
--》使用字符串拼接,不安全,有漏洞,如果輸入密碼為:1‘ or '1'='1 這時(shí)候數(shù)據(jù)庫(kù)解析SQL語句會(huì)把后面的or當(dāng)做一個(gè)條件,那么’1‘=’1‘永遠(yuǎn)成立
select * from 表名 where Uid=‘{0}’ and pwd=‘{1}’
--》使用參數(shù)查詢
select * from 表名 where Uid=@name and pwd=@pwd
再通過執(zhí)行對(duì)象SqlCommand提供的屬性parameters屬性調(diào)用Add方法給變量賦值,不使用時(shí)記得清空
cmd.parameters.AddWithValue("@name",值) --這時(shí)候 1‘ or '1'='1 就會(huì)整個(gè)被當(dāng)做一個(gè)值賦給pwd,不會(huì)再被解析成一個(gè)條件
ExecuteReader的執(zhí)行
public static class SQLHelper { //連接字符串,readonly--》讀取進(jìn)來就不可改變 private static readonly string sqlcon = ConfigurationManager.ConnectionStrings["sql"].ConnectionString; /// <summary> /// 連接SQL語句,返回受影響行數(shù) /// </summary> /// <param name="sql">要執(zhí)行的T-SQL語句</param> /// <param name="par">SQL語句的參數(shù)</param> /// <returns>受影響行數(shù)</returns> public static int ExecuteNonQuery(string sql, params SqlParameter[] par) { if (sqlcon == null) { throw new Exception("沒有連接字符串"); } using (SqlConnection con = new SqlConnection(sqlcon)) { using (SqlCommand cmd = new SqlCommand(sql, con)) { if (con.State == System.Data.ConnectionState.Closed ) { con.Open(); } if (par!=null) { cmd.Parameters.AddRange(par); } return cmd.ExecuteNonQuery(); } } } /// <summary> /// 執(zhí)行查詢,返回執(zhí)行查詢的結(jié)果集的第一行第一列 /// </summary> /// <param name="sql">要執(zhí)行的T-SQL語句</param> /// <param name="par">T-SQL語句里的參數(shù)</param> /// <returns></returns> public static object ExcuteScalar(string sql, params SqlParameter[] par) { using (SqlConnection con = new SqlConnection(sqlcon)) { using (SqlCommand cmd = new SqlCommand(sql, con)) { if (par!=null) { cmd.Parameters.AddRange(par); } if (con.State == System.Data.ConnectionState.Closed ) { con.Open(); } return cmd.ExecuteScalar(); } } } public static SqlDataReader ExecuteReader(string sql, params SqlParameter[] par) { SqlConnection con = new SqlConnection(sqlcon); using (SqlCommand cmd = new SqlCommand(sql, con)) { if (par!=null) { cmd.Parameters.AddRange(par); } if (con.State == System.Data.ConnectionState.Closed ) { con.Open(); } return cmd.ExecuteReader(System.Data.CommandBehavior .CloseConnection); } } public static DataTable ExecuteDataTable(string sql, params SqlParameter[] par) { using (SqlDataAdapter ada = new SqlDataAdapter(sql, sqlcon)) { //SqlDataAdapter內(nèi)部hui 創(chuàng)建yige SqlCommand對(duì)象, //直接通過SqlDataAdapter的selectCommand屬性就可以調(diào)到 if (par!=null) { ada.SelectCommand.Parameters.AddRange(par); } DataTable ta = new DataTable(); ada.Fill(ta); return ta; } } }
--=======================SQLHelper實(shí)現(xiàn)省市聯(lián)動(dòng)案例===================================
private void Form1_Load(object sender, EventArgs e) { string ssql = "select proid,proName from promary "; using (SqlDataReader reader = SQLHelper.ExecuteReader(ssql)) { if (reader.HasRows) { while (reader.Read()) { Area temp = new Area(); temp.AreaId = reader.GetInt32(0); temp.AreaName = reader.GetString(1); comboBox1.Items.Add(temp); } } } comboBox1.SelectedIndex = 0; } private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) { comboBox2.Items.Clear(); int r = ((Area)comboBox1.SelectedItem).AreaId; string sql = "select cityName from city where proid=@pid"; using (SqlDataReader reader = SQLHelper.ExecuteReader(sql, new SqlParameter("@pid", r))) { if (reader.HasRows) { while (reader.Read()) { Area shi = new Area(); shi.AreaName = reader.GetString(0); comboBox2.Items.Add(shi); } } } comboBox2.SelectedIndex = 0; } }// 封裝一個(gè)類 把數(shù)據(jù)庫(kù)表里的每一行的數(shù)據(jù)都看成是這個(gè)類的一個(gè)對(duì)象 class Area { public int AreaId { get; set; } public string AreaName { get; set; } public override string ToString() { return AreaName; } }
一、SQLHelper
實(shí)際上就是你自己封裝的方法,專門用來執(zhí)行增刪改查等操作
沒有SQLHelper之前反反復(fù)復(fù)的寫
--》使用連接對(duì)象、命令對(duì)象、讀取器等,都是重復(fù)的代碼
--》實(shí)際上自己封裝成方法即可,但是由于數(shù)據(jù)庫(kù)的操作都一樣,因此可以將其封裝成類庫(kù)進(jìn)行調(diào)用
1)SqlParameter
當(dāng)SqlParameter的第二個(gè)參數(shù)是數(shù)字時(shí),需要考慮是哪一個(gè)重載,常用的有兩個(gè)
--》一個(gè)是object Value
--》一個(gè)是sqlDbType 是一個(gè)枚舉,由于枚舉本身就是個(gè)數(shù)字,如果第二個(gè)參數(shù)直接傳個(gè)數(shù)字,那么這個(gè)數(shù)字和枚舉就沖突了,可能會(huì)出錯(cuò),為了避免出錯(cuò)當(dāng)?shù)诙€(gè)參數(shù)是數(shù)字的時(shí)候要轉(zhuǎn)換成object類型
SqlParameter par= new SqlParameter("@num", SqlDbType.Int);
par.Value =0;
二、Case函數(shù)
需要在哪里控制顯示就在誰的前面加case
兩個(gè)版本
-->等價(jià)于switch-case結(jié)構(gòu)
case 字段
when 值 then 替換值,
when 值 then 替換值
...
else 替換值
end
--》if-else if結(jié)構(gòu)
case
when 表達(dá)式 then 值
when 表達(dá)式 then 值
else 值
end
select
name 單號(hào),
case
when [money]>0 then [money]
else 0
end as 收入,
case
when [money]<0 then abs( [money])
else 0
end as 支出
from FTable
三、子查詢
就是將查出來的結(jié)果集,作為一個(gè)數(shù)據(jù)源 (就是在一個(gè)結(jié)果集的基礎(chǔ)上再做其他的查詢)
結(jié)果集就是查詢出來具有滿足一些特定的格式的結(jié)果
結(jié)果集的特征
--》單值結(jié)果集 就是只有一行一列的結(jié)果集
--》行結(jié)果集 顧名思義就是只有一行,可以有多列。或者只有一列,可以有多行
--》表結(jié)果集 就是查詢出來的整張表有多行多列
--查詢某個(gè)班級(jí)的所有學(xué)生
select * from TStudent where classid IN(select classId from TClass where cName='.net學(xué)院' and cDescr-- 查詢某些學(xué)生的成績(jī)
select * from TScore where scoreid in (select scoreid from TStudent WHERE sName ='安半青')
--快速實(shí)現(xiàn)刪除多個(gè)學(xué)生
delete from TStudent where classid in (select classId from TClass where cName='C++學(xué)院' and cdescription='基礎(chǔ)班')
--查詢學(xué)生表中最高分與最低分和平均分
select
(select max(math) from TsCore)as 最高分,
(select min(math) from TsCore)as 最低分,
(select AVG(math) from TsCore)as 平均分
select * from (select studentid from TStudent where studentId between 1 and 5)
use MyName
go
select * from dbo.LobinTable
select top 5 * from MyStudent where Fid not in(select top (5*2) Fid from MyStudent )
一、case 兩種語法
switch-case 結(jié)構(gòu)
---》 case 字段
when 值 then 顯示的值
when 值 then 現(xiàn)實(shí)的值
else 顯示的值
end
if-else if
--> case
when 表達(dá)式 then 現(xiàn)實(shí)的值
when 表達(dá)式 then 顯示的值
else 顯示的值
end
2、子查詢就是將結(jié)果集作為數(shù)據(jù)源
select 字段
3、聯(lián)合
union
-->將兩個(gè)結(jié)果集縫到一起
二、連接 Join
將兩張表或多張表做為數(shù)據(jù)源
語法:
內(nèi)連接,兩張表中,如果有沒有數(shù)據(jù)的記錄(行),則不顯示
select 字段 from //這里不建議用* 你不需要的信息顯也示出來 ,這里可以通過下面給表起的別名 table1.字段 來顯示要顯示的列
表1 as table1
inner Join
表2 as table2
on table1.外鍵=table2.主鍵 (迪卡爾積:table1的外鍵分別會(huì)連接table2的每一個(gè)主鍵,把兩個(gè)鍵相等的都連接起來)
select t1.studentId,t1.sName,t1.sAge,t1.sGender,t2.cName,t2.cDescription from
TStudent as t1
inner join
TClass as t2
on t1.classid=t2.classId
--------------案例------------------ 內(nèi)連接如果某條記錄的外鍵是空的或者這個(gè)記錄的外鍵沒有在主鍵表上,那么這個(gè)記錄就不會(huì)被顯示出來
4 韋天磊 74 1 .Net學(xué)院 就業(yè)班
32 童凡霜 79 0 .Net學(xué)院 就業(yè)班
42 惠爾蝶 30 0 .Net學(xué)院 就業(yè)班
44 夏侯哲瀚 88 1 .Net學(xué)院 就業(yè)班
49 訾燁偉 64 1 .Net學(xué)院 就業(yè)班
52 巴詩(shī)雙 73 0 .Net學(xué)院 就業(yè)班
102 仲孫冰巧 58 0 .Net學(xué)院 就業(yè)班
114 曾雅柔 93 0 .Net學(xué)院 就業(yè)班
136 任炎彬 30 1 .Net學(xué)院 就業(yè)班
181 楊天佑 76 1 .Net學(xué)院 就業(yè)班
230 姜元楓 29 0 .Net學(xué)院 就業(yè)班
左外連接 left join
以左邊的表為主,如果左邊的表的外鍵是空的或者是主鍵表上沒有這個(gè)記錄的值,那么對(duì)應(yīng)的右邊的表(主鍵表)的數(shù)據(jù)就是空的
select t1.studentId,t1.sName,t1.sAge,t1.sGender,t2.cName,t2.cDescription from
TStudent as t1
left join
TClass as t2
on t1.classid=t2.classId
------------案例------------
1001 李四 20 1 2012-06-11 11:14:39.833 0 NULL NULL NULL NULL NULL
980 扈綺琴 7 0 2012-06-09 19:43:00.873 0 980 1 1 .Net學(xué)院 就業(yè)班
944 胥易蓉 17 0 2012-06-09 19:43:00.490 0 944 1 1 .Net學(xué)院 就業(yè)班
954 萬文昊 67 1 2012-06-09 19:43:00.603 0 954 1 1 .Net學(xué)院 就業(yè)班
956 郤偉宸 96 1 2012-06-09 19:43:00.620 0 956 1 1 .Net學(xué)院 就業(yè)班
962 勞博超 89 1 2012-06-09 19:43:00.673 0 962 1 1 .Net學(xué)院 就業(yè)班
964 陶燁偉 44 1 2012-06-09 19:43:00.690 0 964 1 1 .Net學(xué)院 就業(yè)班
865 呂煜城 93 1 2012-06-09 19:42:59.773 0 865 1 1 .Net學(xué)院 就業(yè)班
884 茹翠風(fēng) 51 0 2012-06-09 19:42:59.947 0 884 1 1 .Net學(xué)院 就業(yè)班
904 辛修潔 67 1 2012-06-09 19:43:00.130 0 904 1 1 .Net學(xué)院 就業(yè)班
右外連接 right join
一右邊的表為主,如果左邊的表的記錄外鍵是空的或者是主鍵表上沒有這個(gè)記錄的值,那么對(duì)應(yīng)的左邊的表(外鍵表)的數(shù)據(jù)就是空的
select * from
TStudent as t1
right join
TClass as t2
on t1.classId =t2.classId
-------------------案例------------------
576 丁南蓮 86 0 2012-06-09 19:42:56.890 0 576 14 14 Web學(xué)院 基礎(chǔ)班
585 慕容迎夢(mèng) 46 0 2012-06-09 19:42:56.973 0 585 14 14 Web學(xué)院 基礎(chǔ)班
527 袁靖琪 67 1 2012-06-09 19:42:56.360 0 527 14 14 Web學(xué)院 基礎(chǔ)班
524 宓鵬飛 97 1 2012-06-09 19:42:56.293 0 524 14 14 Web學(xué)院 基礎(chǔ)班
545 于凌翠 47 0 2012-06-09 19:42:56.590 0 545 14 14 Web學(xué)院 基礎(chǔ)班
609 竺志澤 15 1 2012-06-09 19:42:57.260 0 609 14 14 Web學(xué)院 基礎(chǔ)班
638 莘以云 50 0 2012-06-09 19:42:57.530 0 638 14 14 Web學(xué)院 基礎(chǔ)班
680 萬俟曉博 23 1 2012-06-09 19:42:57.950 0 680 14 14 Web學(xué)院 基礎(chǔ)班
NULL NULL NULL NULL NULL NULL NULL NULL 15 Web學(xué)院 黑馬班
NULL NULL NULL NULL NULL NULL NULL NULL 16 狗屁學(xué)院 白馬班
多表連接
select * from
TStudent as t1
right join
TClass as t2
inner join
TScore as t3
on t1.classId =t2.classId
inner join
......
可以一直練下去
-----------------------案例----------------------------
select t1.studentId,t1.sName,t1.sAge,t1.sGender,t2.cName,t2.cDescription,t3.chinese,t3.english,t3.math from
TStudent as t1
inner join
TClass as t2
on t1.classId =t2.classId
inner join
TScore as t3
on t1.scoreId =t3.scoreId
1 章夏槐 9 0 java學(xué)院 黑馬班 69 132 99
3 符夢(mèng)琪 50 0 .Net學(xué)院 基礎(chǔ)班 148 85 50
4 韋天磊 74 1 .Net學(xué)院 就業(yè)班 14 33 134
5 璩偉祺 32 1 Java學(xué)院 就業(yè)班 144 43 121
6 滑燁磊 1 1 Java學(xué)院 就業(yè)班 73 130 103
7 柴傲柏 36 0 C++學(xué)院 就業(yè)班 98 8 57
8 梅天荷 14 0 Web學(xué)院 就業(yè)班 96 43 99
9 左雅彤 91 0 C++學(xué)院 就業(yè)班 88 80 44
10 東方香寒 17 0 Java學(xué)院 黑馬班 32 146 11
12 麹博濤 42 1 .Net學(xué)院 黑馬班 30 142 114
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注