查詢和操作數據庫
要想從數據庫中讀取多條記錄就必須用到Command對象的ExecuteReader()方法,該方法返回一個DataReader對象,通過其對象的程序就可以訪問數據庫。
基礎知識
conn.close(); //關閉之后還能打開;
conn.dispose(); //直接銷毀不能再次利用,dispose內部有close方法;
認識DataReader對象
使用其DataReader對象可以從數據庫中檢索只讀數據,且每次只能從查詢結果中讀取一行到內存中,非常的快,使用其時不能對其進行修改,只能讀取。而且在讀取是一定要與數據庫連接,不能斷開連接。
要創建一個DataReader對象需要調用Command對象的ExecuteRead()方法,此方法返回值就是一個DataReader對象,之后調用其對象的Reader()方法來讀取一行數據,{將其放在一個while循環中,這樣就可以將所有的值全部都顯示出來}
步驟:
1:創建Command對象
string connSting=”Data Source=zhanghui; Initial Catalog=Ahui; User ID=sa; Pwd=111”
sqlconnection conn=new sqlconnection(connString);
conn.open();
string sql=”saelect count(*) from Student”;
sqlCommand md=new sqlCommand(sql,conn);
2:調用Command的ExecuteReader()方法創建DataReader對象。
sqlDataReader dataReader=md.ExecuteReader();
3:使用其的Read()方法按行去讀取數據,此方法返回一個布爾類型,若讀到數據則返回true,否則返回false,此時用到了while循環。
while(dataReader.read())
{
獲取數據集中的值;
}
4:
4.1讀取當前行的某列數據,可以像數組一樣進行索引,按下標進行查詢顯示。
(string)dataReader[0];
4.2還有一種方法也可以獲取當前行的某列數據。
string name=dataReader.GetString(0); //獲取其第一行的值。
5:關閉其DataReader對象,調用其Close()方法。
eg one : 在前臺輸入用戶,看是否為數據庫表中的數據,若是則顯示成功,不是報錯。
Console.WriteLine("請輸入用戶名");
string username = Console.ReadLine();
//數據庫連接字符串
string connString = "Data Source=zhanghui;Initial Catalog=Ahui;User ID=sa;Pwd=111";
//創建數據庫的連接
SqlConnection conn = new SqlConnection(connString);
conn.Open(); //打開數據庫
using (SqlCommand kfc = conn.CreateCommand()) //創建Command對象。
{
kfc.CommandText = "select * from Student where Name= '"+username +"' "; //SQL語句
using (SqlDataReader read = kfc.ExecuteReader())
{
if (read.Read())
{
Console.WriteLine("用戶存在");
}
else
{
Console.WriteLine("用戶錯誤");
}
}
}
Console.WriteLine("打開數據庫連接成功");
conn.Close(); //關閉數據庫,切記每次用完之后一定要關閉數據庫。
Console.ReadKey();
eg two :從數據庫中讀取數據,顯示在窗口中。
一般的注意事項
User是關鍵字,一般情況下表名以T_開頭,字段以F_開頭;,這樣做的好處是防止表名與字段和系統的關鍵字重復,報錯。
reader的GenString,GetInt32等方法只能接受整數參數,也就是序號用GetOrdinal方法根據列名動態得到序號。
特殊: eg three :
改變上一個登錄程序,使用其count(*)來進行比較,來查看是否登錄成功;
static void Main(string[] args)
{
Console.WriteLine("請輸入用戶名");
string username = Console.ReadLine();
Console.WriteLine("請輸入密碼");
string passWord = Console.ReadLine();
//數據庫連接字符串
string connString = "Data Source=zhanghui; Initial Catalog=Ahui; User ID=sa; Pwd=111";
//創建數據庫連接
SqlConnection conn=new SqlConnection(connString);
//打開數據庫
conn.Open();
using (SqlCommand ka=conn.CreateCommand())
{
ka.CommandText = "select count(*) from login where UserName='"+username+"' and Password='"+password+"' ";
//當時在做的時候,不知道在UserName和Password之間加and,花費了很多的時間,最后才知道了,這是SQL語法里面的知識。
int i = Convert.ToInt32(ka.ExecuteScalar());
//在這里的ka.ExecuteScalar()代表的就是ka.Command里面傳出來的值。
if (i>0)
{
Console.WriteLine("登錄成功");
}
else
{
Console.WriteLine("用戶名或密碼錯誤?");
}
}
Console.WriteLine("OK");
Console.ReadKey();
但是為什么我這樣子輸入的話,也會出現登錄成功。
老師說這是一種注入漏洞,只要是登錄名和數據庫中的登錄名一樣,就可以顯示登錄成功。
但是如果想避免情況的發生,就必須使用參數化查詢。
eg:
static void Main(string[] args)
{
Console.WriteLine("請輸入用戶名");
string username = Console.ReadLine();
Console.WriteLine("請輸入密碼");
string password = Console.ReadLine();
//數據庫連接字符串
string connString = "Data Source=zhanghui; Initial Catalog=Ahui; User ID=sa; Pwd=111";
//創建數據庫連接
SqlConnection conn=new SqlConnection(connString);
//打開數據庫
conn.Open();
using (SqlCommand ka=conn.CreateCommand())
{
ka.CommandText = "select count(*) from login where UserName=@UserName and Password=@Password";
//上面的可以先看成占位符,通過下面的語句在給其賦值,。
ka.Parameters.Add(new SqlParameter("UserName",username));
//Parameters是其ka的一個屬性,是一個集合,通過調用Add來為其上面的占位符來賦值。
ka.Parameters.Add(new SqlParameter("Password",password));
int i = Convert.ToInt32(ka.ExecuteScalar());
if (i>0)
{
Console.WriteLine("登錄成功");
}
else
{
Console.WriteLine("用戶名或密碼錯誤?");
}
}
Console.WriteLine("OK");
Console.ReadKey();
上面的修改,是用了其試占位符的字段,來賦值,不是用參數的形式來設值,這樣子就堵注了SQL漏洞攻擊;
在其占位符下面在為其占位符賦值,是將拿輸入的東西當成字符串的值,在數據庫中進行比較,如果有則登陸成功,否則登錄失敗。
***在同一個連接中如果sqlDataReader沒有關閉,那么是不能執行update之類的語句;
下面是一個登錄的實例,但是出現不了自己想要的結果,總是說出錯,有誰做過可以幫我看看,謝謝。
代碼:
/*將第二個要用的數據庫連接必須重新寫在一個類中,進行調用,如果在一個數據庫連接字符串中
同時進行兩個sql語句的操作就會出現錯誤。
這樣就相當于將其封裝起來,如果后面要用到,直接調用就行。
*/
PRivate void hui()
{
string connSting = "Data Source=zhanghui; Initial Catalog=Ahui; User ID=sa; Pwd=111;";
SqlConnection conn = new SqlConnection(connSting);
conn.Open();
using (SqlCommand updata = conn.CreateCommand())
{
updata.CommandText = "update login Set errorTimes=errorTimes+1 where UserName=@UserName ";
updata.Parameters.Add(new SqlParameter("UserName", txtUserName.Text));
updata.ExecuteNonQuery();
}
}
private void btnLand_Click(object sender, EventArgs e)
{
string connString = "Data Source=zhanghui; Initial Catalog=Ahui; User ID=sa; Pwd=111;";
SqlConnection conn=new SqlConnection(connString);
conn.Open();
using (SqlCommand lg=conn.CreateCommand())
{
lg.CommandText = "select * from login where UserName=@UserName";
lg.Parameters.Add(new SqlParameter("UserName",txtUserName.Text));
using (SqlDataReader reader=lg.ExecuteReader())
{
if (reader.Read())
{
int errorTime = reader.GetInt32(reader.GetOrdinal("errorTimes"));
if (errorTime > 3)
{
MessageBox.Show("登陸次數過多,禁止登錄!");
return;
}
string Ahuipassword = reader.GetString(reader.GetOrdinal("Password"));
if (AhuiPassword==txtPassword.Text)
{
MessageBox.Show("登陸成功");
}
else
{
hui(); //調用了本類中上面的一個類。
MessageBox.Show("登錄失敗");
}
}
else
{
MessageBox.Show("用戶名不存在");
}
}
}
}
下面為數據庫截圖和登錄窗口截圖
運行結果如下,剛開始還可以運行3次,說是登錄失敗,現在只要是輸入就說登錄此數過多,求大神支招
這個問題我自己一直解決不了,困擾我了很久,希望遇到大神,幫幫我。謝了。
新聞熱點
疑難解答