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