第三讲 数据集对象DataRader

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

第三讲SqlDataReader对象
一、SqlDataReader对象
SqlDataReader对象是对连接执行Transact-SQL 语句返回的一个只读的数据流。

常用属性:
1)Item 索引器属性,以原始格式获得一列的值
SqlDataReader对象名.[索引值]
SqlDataReader对象名.[“表中的字段名”]
2)FieldCount 获取当前行的列数
3)HasRows 获取一个值,以表示SqlDataReader对象中是否包含一行或多行记录。

二、常用方法:
1)Read 使DataReader对象前进到下一条记录(如果有)
2)Close 关闭DataReader对象。

注意,关闭阅读器对象并不会自动关闭底层连接
三、应用举例
例1:用户管理时自动添加所有用户的用户名到下拉列表。

Read方法及索引器属性的应用
string constr = "Data Source=.;Initial Catalog=学生管理;Integrated Security=True";
SqlConnection con;
string sqlstr = "select 用户名from 用户表";
SqlCommand com;
SqlDataReader dr;
private void Form1_Load(object sender, EventArgs e)
{
con = new SqlConnection(constr);
con.Open();
com = new SqlCommand(sqlstr, con);
dr= com.ExecuteReader();
comboBox1.Items.Clear();
while (dr.Read())
{
comboBox1.Items.Add(dr[0].ToString());
}
dr.Close();
if(comboBox1.Items.Count >0)
comboBox1.Text = comboBox1.Items[0].ToString();
con.Close();
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (comboBox1.SelectedIndex >= 0)
{
if (con.State != ConnectionState.Open)
con.Open();
sqlstr = "select 密码,用户类型from 用户表where 用户名='" + comboBox1.Text + "'";
com = new SqlCommand(sqlstr, con);
dr = com.ExecuteReader();
dr.Read();
textBox1.Text = dr[0].ToString();
textBox2.Text = dr[1].ToString();
con.Close();
}
}
private void button1_Click(object sender, EventArgs e)
{
con.Open();
sqlstr = "delete 用户表where 用户名='" + comboBox1.Text.Trim() + "'";
com = new SqlCommand(sqlstr, con);
if (com.ExecuteNonQuery() > 0)
{
MessageBox.Show("记录已删除!");
comboBox1.Items.Remove(comboBox1.Text);
comboBox1.SelectedIndex = 0;
}
con.Close();
}
例2:用户登录功能通过DataReader对象验证用户身份,减少访问数据库的次数。

HasRows属性的应用
private void button1_Click(object sender, EventArgs e)
string constr = "Data Source=.;Initial Catalog=学生管理;Integrated Security=True";
SqlConnection con = new SqlConnection(constr);
con.Open();
string sqlstr = "select * from 用户表where 用户名='"+textBox1.Text +"'";
SqlCommand com = new SqlCommand(sqlstr, con);
SqlDataReader dr = com.ExecuteReader();
if (dr.HasRows)
{
dr.Read();
if (textBox2.Text == dr["密码"].ToString().Trim())
{
if (comboBox2.Text.Trim() ==dr["用户类型"].ToString().Trim() )
MessageBox.Show("登录成功!");
else
MessageBox.Show("用户类型错误!");
}
else
MessageBox.Show("密码错误!");
}
else
MessageBox.Show("用户名不存在!");
con.Close();
}
例3:通过列表框对象显示所有用户的信息。

FieldCount属性的应用,循环访问所有的列。

窗口加载时,用列表的方式显示所有用户信息。

private void Form1_Load(object sender, EventArgs e)
string constr = "Data Source=.;Initial Catalog=学生管理;Integrated Security=True";
SqlConnection con = new SqlConnection(constr);
con.Open();
string sqlstr = "select * from 用户表";
SqlCommand com = new SqlCommand(sqlstr, con);
SqlDataReader dr = com.ExecuteReader();
//新建一个datareader对象,保存获取的只读的流式数据集
while (dr.Read())
//获取数据集中的下一条记录
{
string s="";
for (int i = 0; i < dr.FieldCount; i++)
s = s + string.Format( dr[i].ToString(),"@@@@@@@");
listBox1.Items.Add(s);
}
con.Close();
}
删除当前选中的用户信息,然后更新列表框中的信息。

private void button1_Click(object sender, EventArgs e)
{
if (listBox1.SelectedIndex >= 0)
{
string constr = "Data Source=.;Initial Catalog=学生管理;Integrated Security=True";
SqlConnection con = new SqlConnection(constr);
con.Open();
string s = listBox1.Items[listBox1.SelectedIndex].ToString().Substring(0, 7);
string sqlstr = "delete 用户表where 用户名='" + s + "'";
SqlCommand com = new SqlCommand(sqlstr, con);
if (com.ExecuteNonQuery() > 0)
MessageBox.Show("记录已删除!");
listBox1.Items.Clear();
Form1_Load(sender, e);
con.Close();
}
}
四、自我练习
练习1:用户登录窗口自动添加所有用户类型。

private void Form1_Load(object sender, EventArgs e)
{
string constr = "Data Source=.;Initial Catalog=学生管理;Integrated Security=True";
SqlConnection con = new SqlConnection(constr);
con.Open();
string sqlstr = "select distinct 用户类型from 用户表";
SqlCommand com = new SqlCommand(sqlstr, con);
SqlDataReader dr = com.ExecuteReader();
//新建一个datareader对象,保存获取的只读的流式数据集
while (dr.Read())
//获取数据集中的下一条记录
{
comboBox2.Items.Add(dr[0].ToString());
//将当前记录的第0列添加到combobox中
}
con.Close();
comboBox2.Text = comboBox2.Items[0].ToString();
}
练习2:
例:
在学生成绩数据库中新建一个成绩表,输入期若干个学生的学号及语文、数学、英语三门课的成绩,创建一个视图,可输出所有学生的成绩及总分和平均分,并按总分的降序排列。

设计一个应用程序,可查看全班所有学生的总分及平均分。

创建视图的SQL代码参考如下:
CREATE VIEW dbo.成绩排名AS SELECT TOP 100 PERCENT 学号, 语文, 数学, 英语, 语文+ 数学+ 英语AS 总分, (语文+ 数学+ 英语) / 3 AS 平均分FROM dbo.成绩表ORDER BY 总分DESC
程序代码参考如下:
string SqlStr = "Server=192.168.200.61;User Id=sa;Pwd=;DataBase=stu";
SqlConnection con = new SqlConnection(SqlStr);
con.Open();
SqlStr = "select * from view1 ";
SqlCommand cmd = new SqlCommand(SqlStr, con);
SqlDataReader dr = cmd.ExecuteReader();
string s = "学号语文数学外语总分平均分\n";
while (dr.Read())
{
int i = 0;
while (i < dr.fieldcount)
{
s = s + " " + dr[i].ToString();
i++;
}
s = s + "\n";
}
MessageBox.Show(s);
con.Close();
con.Dispose();
实作练习:
在航班信息管理数据库中建立一个用户表(用户名,密码,用户类型),输入若干条记录,编程查看并输出用户表中的所有记录。

string constr = "Data Source=0F6A988FB791401;Initial Catalog=航班信息管
理;Integrated Security=True";
SqlConnection con = new SqlConnection(constr);
con.Open();
string comstr = "select * from 用户表";
SqlCommand com = new SqlCommand(comstr, con);
SqlDataReader dr = com.ExecuteReader();
string str = "" ;
while (dr.Read())
{
for (int i = 0; i < dr.FieldCount - 1; i++)
{
str = str + dr[i].ToString() + " ";
}
str = str + "\n";
}
MessageBox.Show(str);
con.Close();
三、案例:用户登录界面设计及实现:
需要引用的命名空间为:
using System.Data.SqlClient;
登录界面代码:
string str = "Server=(local);User Id=sa;Pwd=;DataBase=航班信息管理";
SqlConnection con = new SqlConnection(str);
con.Open();
str = "select * from 用户表 where 用户名='" + textBox1.Text + "'";
SqlCommand com = new SqlCommand(str, con);
com.Connection = con;
SqlDataReader dr = com.ExecuteReader();
if(dr.HasRows)
{
dr.Read();
string s = dr[1].ToString();
if (s.Trim()==textBox2.Text)
{
Form1 f1 = new Form1();
f1.Show();
}
else
MessageBox.Show("密码错误!");
}
else
MessageBox.Show("用户名不存在!");
}
四、实作练习:
编程实现航班信息管理的用户注册功能。

参考代码如下:
string constr = "Data Source=0F6A988FB791401;Initial Catalog=航班信息管
理;Integrated Security=True";
SqlConnection con = new SqlConnection(constr);
con.Open();
string comstr = "select * from 用户表 where 用户名='" + textBox1.Text + "'";
SqlCommand com = new SqlCommand(comstr, con);
SqlDataReader dr = com.ExecuteReader();
if (dr.HasRows)
MessageBox.Show("用户名已存在,重新注册!");
else
{
con.Close();
con.Open();
comstr = "insert into 用户表 (用户名,密码,用户类型) values('" + textBox1.Text
+ "','" + textBox2.Text + "','学生')";
com = new SqlCommand(comstr, con);
if (com.ExecuteNonQuery() == 1)
MessageBox.Show("注册成功!");
else
MessageBox.Show("数据库写入失败!");
}
con.Close();
五、向组合框中添加数据库中的信息
string str = "Server=(local);User Id=sa;Pwd=;DataBase=航班信息管理";
SqlConnection con = new SqlConnection(str);
con.Open();
SqlCommand cmd = new SqlCommand("select 航班号 from 航班信息表");
cmd.Connection = con;
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
comboBox3.Items.Add(dr[0]);
comboBox3.Text = comboBox3.Items[0].ToString();
con.Close();
向下拉列表框图中添加数据集
string constr = "Data Source=417-80;Initial Catalog=student;Integrated Security=True";
SqlConnection con = new SqlConnection(constr);
con.Open();
string sqlstr = "select userType from userType";
SqlCommand com = new SqlCommand(sqlstr, con);
SqlDataReader dr = com.ExecuteReader();
while (dr.Read())
{
cmbUserTpe.Items.Add (dr[0].ToString ());
}
con.Close();
cmbUserTpe.SelectedIndex = 0;
定义用户类型类
public class UserTypeClass
{
int userTypeID;
string userType;
public int UserTypeID
{
get { return userTypeID; }
}
public string UserType
{
get { return userType; }
}
public UserTypeClass(int id,string type)
{
userTypeID = id;
userType = type;
}
}
将用户类型对象添加到下拉列表框中
string constr = "Data Source=417-80;Initial Catalog=student;Integrated
Security=True";
SqlConnection con = new SqlConnection(constr);
con.Open();
string sqlstr = "select * from userType";
SqlCommand com = new SqlCommand(sqlstr, con);
SqlDataReader dr = com.ExecuteReader();
while (dr.Read())
{
UserTypeClass x = new UserTypeClass(Convert.ToInt16 ( dr[0]),dr.GetString(1)); cmbUserTpe.Items.Add (x);
}
con.Close();
cmbUserTpe.SelectedIndex = 0;
cmbUserTpe.DisplayMember = "UserType";
完成用户注册
string constr = "Data Source=417-80;Initial Catalog=student;Integrated
Security=True";
SqlConnection con = new SqlConnection(constr);
con.Open();
string sqlstr = "insert into usertabel(username,userpwd,usertypeid)
values('{0}','{1}',{2})";
UserTypeClass x=cmbUserTpe.SelectedItem as UserTypeClass ;
sqlstr = string.Format(sqlstr, txtUsername.Text, txtUserPWD.Text, erTypeID);
SqlCommand com = new SqlCommand(sqlstr, con);
if (com.ExecuteNonQuery() > 0)
MessageBox.Show("用户注册成功!");
con.Close();
用户注册功能的完善(二次输入密码是否一致,用户名是否已注册)
if (txtUserPWD.Text != txtUserPWD2.Text)
MessageBox.Show("二次输入的密码不一致!");
else
{
string constr = "Data Source=417-80;Initial Catalog=student;Integrated Security=True";
SqlConnection con = new SqlConnection(constr);
con.Open();
string sqlstr = "select * from usertabel where username='" + txtUsername.Text + "'";
SqlCommand com = new SqlCommand(sqlstr, con);
if (com.ExecuteScalar() !=null)
MessageBox.Show("用户名已注册!");
else
{
sqlstr = "insert into usertabel(username,userpwd,usertypeid)
values('{0}','{1}',{2})";
UserTypeClass x = cmbUserTpe.SelectedItem as UserTypeClass;
sqlstr = string.Format(sqlstr, txtUsername.Text, txtUserPWD.Text,
erTypeID);
com = new SqlCommand(sqlstr, con);
if (com.ExecuteNonQuery() > 0)
MessageBox.Show("用户注册成功!");
}
con.Close();
}
用户登录功能的实现与SQL注入式攻击的防范:
string constr = "Data Source=417-80;Initial Catalog=student;Integrated
Security=True";
SqlConnection con = new SqlConnection(constr);
con.Open();
string sqlstr = "select * from usertabel where username='{0}' and userpwd='{1}'"; sqlstr =string .Format (sqlstr,txtUsername.Text ,txtUserPWD.Text );
SqlCommand com = new SqlCommand(sqlstr, con);
if (com.ExecuteScalar() != null)
{
MessageBox.Show("登录成功!");
this.Close();
}
else
MessageBox.Show("登录失败!");
con.Close();
SQL注入式攻击
若用户输入的用户名为abc,密码为' or '1'='1
则sqlstr =string .Format (sqlstr,txtUsername.Text ,txtUserPWD.Text );命令生成的sqlstr为:select * from usertabel where username='abc' and userpwd='' or '1'='1' 使得用户身份验证无效。

SQL注入式攻击的防范
将以下代码
string sqlstr = "select * from usertabel where username='{0}' and userpwd='{1}'"; sqlstr =string .Format (sqlstr,txtUsername.Text ,txtUserPWD.Text );
SqlCommand com = new SqlCommand(sqlstr, con);
改为:
string sqlstr = "select * from usertabel where username=@pa1 and userpwd=@pa2";
SqlCommand com = new SqlCommand(sqlstr, con);
SqlParameter p1 = new SqlParameter("@pa1", txtUsername.Text);
SqlParameter p2 = new SqlParameter("@pa2", txtUserPWD.Text);
com.Parameters.Add(p1);
com.Parameters.Add(p2);
也就是说,可通过向SqlCommand传递参数的方式,防止将用户输入的’号理解为字符常量的定界符,从而防止了SQL注入式攻击。

相关文档
最新文档