通過ADO.Net在程序中執行SQL語句。
ADO.Net中提供了對各種不同數據庫的統一操作接口。
連接SQLServer
1. 連接字符串:程序通過連接字符串指定要連哪臺服務器上的、哪個實例的哪個數據庫、用什麼用戶名密碼等。
2. 項目內嵌mdf文件形式的連接字符串:
“Data Source=.\SQLEXPRESS; AttachDBFilename=|DataDirectory|\Database1.mdf;
Integrated Security=True; User Instance=True”.
“.\SQLEXPRESS”表示“本機上的SQLEXPRESS實例”,如果數據庫實例名不是SQLEXPRESS,則需要修改。
“Database1.mdf”爲mdf的文件名。
3. ADO.Net中通過SqlConnection類創建到SQLServer的連接。
4. ADO.Net中的連接等資源都實現了IDisposable接口,可以使用using進行資源管理。
類:
SqlConnection:代表一個數據庫連接;
SqlCommand:表示向服務器提交的一個命令(SQL語句等);
SqlDataReader:提供一種從 SQL Server 數據庫讀取行的只進流的方式。
1. 執行有多行結果集的用ExecuteReader
2. SqlDataReader類的GetString、GetInt32等方法只接受整數參數,也就是序號。
用GetOrdinal方法根據列名動態得到序號。
方法:
SqlCommand類的方法:
ExecuteNonQuery():執行SQL語句,返回受影響的行數。
ExecuteScalar():執行查詢,並返回結果集中第一行的第一列,返回值object類型.
ExecuteReader():執行查詢,返回多行多列,返回值是SqlDataReader類型。
ExecuteScalar()應用1:查表中數據條數,查數據最大值等。
應用2:得到自動增長字段的主鍵值。
A. cmd CommandText = “select count(*) from T_Users”
int i = Convert.ToInt32(cmd.ExecuteScalar());
B. cmd.CommandText = “Insert into T_Users(UserName,Password)
output inserted Id values(‘admin’,’666666’)”;
int i = Convert.ToInt32(cmd.ExecuteScalar()); //得到自動增長字段的主鍵值
ExecuteReader()應用:
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read()) //每次讀一行,返回值爲true表示讀到了數據,否則無數據。
//讀取多行數據時,只能逐行向前處理,無法回頭,無法向前跳着走
{
String username = reader.GetString(reader.GetOrdinal(“UserName”));
}
//GetOrdinal():在給定列名稱的情況下獲取序列號
例1:
向數據庫插入數據
using(SqlConnection conn =new SqlConnection(@“Data Source=.\SQLEXPRESS;
AttachDBFilename=|DataDirectory|\Database1.mdf;
Integrated Security=True; User Instance=True”))
//字符串前要加@,否則字符串裏面的’\’將被當成轉義字符。
{
conn.Open();
using(SqlCommand cmd = conn.CreateCommand())
//向服務器提交的一個命令
{
cmd.CommandText = “Insert into MyTable(Name) values(‘aaa’)”; //創建插入命令
cmd.ExecuteNonQuery(); //執行命令
}
}
例2:
從數據庫中查詢數據
using(SqlConnection conn =new SqlConnection(@“Data Source=.\SQLEXPRESS;
AttachDBFilename=|DataDirectory|\Database1.mdf;
Integrated Security=True; User Instance=True”))
{
conn.Open();
using(SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = “select * from T_Users”; //創建查詢命令
using (SqlDataReader reader = cmd.ExecuteReader()) //執行查詢
{
while (reader.Read()) //reader.Read()爲true表示讀到了數據,否則沒讀到數據。
{
//取得表中字段值
string username = reader.GetString(reader.GetOrdinal(“UserName”));
int id = reader.GetInt32(reader.GetOrdinal(“Id”));
string password = reader.GetString(reader.GetOrdinal(“Password”));
//下面做一些邏輯業務處理
}
}
}
}
例3:
簡單的登錄程序
Console.WriteLine(“請輸入用戶名:”);
string username = Console.ReadLine();
Console.WriteLine(“請輸入密碼:”);
string password = Console.ReadLine(); //輸入1’ or ‘1’=’1造成SQL注入漏洞攻擊
using (SqlConnection conn =new SqlConnection(@“Data Source=.\SQLEXPRESS;
AttachDBFilename=|DataDirectory|\Database1.mdf;
Integrated Security=True; User Instance=True”))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
//向服務器提交的一個命令對象
{
cmd.CommandText = “select * from T_Users where UserName=’”+username+”’”;
//先到表中查用戶輸入的用戶名對應的信息
using (SqlDataReader reader = cmd.ExecuteReader()) //執行查詢
{
if(reader.Read())
{
//用戶名存在
string dbpassword = reader.GetString(reader.GetOrdinal(“Password”));
if(dbpassword == password) //比較數據庫中保存的密碼與輸入的密碼是否一致
{
Console.WriteLine(“登錄成功!”);
}
else
{
Console.WriteLine(“密碼錯誤,登錄失敗!”);
}
}
else //Read()返回false,就是沒有查找到這個用戶名
{
//用戶名不存在
Console.WriteLine(“用戶名錯誤!”);
}
}
}
}
SQL注入與參數化查詢
簡單的登錄程序(另一種實現方法)
只部分修改:
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = “select count(*) from T_Users where UserName=’”+username+”’”+
" and Password=’’’+password+”’”;
int i=Convert.ToInt32(cmd.ExecuteScalar()); //返回count(*)的值(即符合條件數據條數)
if (i>0)
{
Console.WriteLine(“登錄成功!”);
}
else
{
Console.WriteLine(“用戶名或密碼錯誤!”);
}
}
以上方法的CommandText是拼接字符串所成,會有sql注入漏洞。
例如用戶輸入用戶名爲admin,密碼爲“1’ or ‘1’= '1”的字符串,
則上面的查詢語句就變爲:
select count(*) from T_Users where UserName=’admin’ and Password=’1’ or ‘1’= '1’;
後一個條件爲真,則整個條件爲真。故查找出來的是表中所有行數,則i>0,即登錄成功。
防止Sql注入,用參數化查詢cmd.Parameters.Add():
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = “select count(*) from T_Users where UserName=@UserName and
Password=@Password”; //相當於佔位符
cmd.Parameters.Add(new SqlParameter(“UserName”,username));
cmd.Parameters.Add(new SqlParameter(“Password”,password));
int i=Convert.ToInt32(cmd.ExecuteScalar()); //返回count(*)的值(即符合條件數據條數)
if (i>0)
{
Console.WriteLine(“登錄成功!”);
}
else
{
Console.WriteLine(“用戶名或密碼錯誤!”);
}
}
總結:程序中一般分五步:
首先加入SqlConnection所在的命名空間:using System.Data.SqlClient;
1. 創建連接數據庫的對象
2. 打開數據庫
3. 創建命令對象
4. 執行命令
5. 獲取數據庫返回的結果,進行處理
防止Sql注入,儘量用參數化查詢
---------------------- Windows Phone 7手機開發、.Net培訓、期待與您交流! ----------------------