ADO.NET的数据库查询2009-12-07 02:20 P.M.ADO.NET的数据库查询

来源:互联网 发布:数码管与单片机连接图 编辑:程序博客网 时间:2024/06/06 00:03
ADO.NET的数据库查询
2009-12-07 02:20 P.M.
ADO.NET的数据库查询
一.SqlCommand对象
1:创建SqlCommand对象
l         使用New关键字创建对象的新实例,然后设置实例的属性;
l         使用构造函数指定查询的Sql语句和SqlCommand对象;
l         调用SqlConnection对象的CreaterCommand方法;
2:使用SqlCommand执行查询
l         执行返回记录行的查询-ExecuteReader
设置SqlCommand对象的CommandText属性设置为Sql查询字符串,然后调用SqlCommand的ExecuteReader 方法返回一个SqlDateReader对象,SqlDateReader对象包含查询结果集。读取结果集前先调用SqlDateReader的Read 方法,如果结果集有数则返回True,并将结果集游标置于第上行;如果结果集没有数据,Read方法则返回False。
l         执行获取单一值的查询-ExecuteScalar
设置SqlCommand对象的CommandText属性设置为Sql查询字符串,调用SqlCommand的ExecuteScalar方法,返回结果集的第一行第一列的值,此值为Object数据类型,应用时根据实际情况进行数据类型的显式转换。
l         执行不返回结果集的查询-ExecuteNonQuery
此类型查询包括两大类:数据操作语言(DML)查询-INSERT、UPDATE、DELETE;数据定义(DDL)查询-CREATE、ALTER、DROP。
调用SqlCommand的ExecuteNonQuery方法执行DML查询时其返回为int类型,代表查询影响的行数;如果执行DML以外的查询返回值为-1。
l         批量操作查询
SqlCommand对象的ExecuteReader和ExecuteNonQuery两种方法都支持批量查询操作,即一次可以执行一条以上的 Sql语句;SqlCommand的StatementCompleted事件(属性)可以收集批量查询中的每条语句所影响的记录数。
二.SqlDataReader对象
1:查检结果集
l         读取结果集中的内容前需要调用Read方法,将结果集的游标移动到记录集的第一行;传入结果集的字段序号或字段名称,即可读取相应的字段值,默认情况下SqlDataReader使用Object数据类型返回列的内容。
l         结果集的数据读取后,应该关闭结果集对象,可将SqlDataReader对象置于Using代码块内,这样可以实现系统自动清理关闭对象。
2:结果集架构
l          结果集字段的数量
SqlDataReader的FieldCount属性用来确定返回的结果集字段的数量,如果SqlCommand的CommandText的Sql语句为UPDATE等类型时将不返回任何字段。
l         字段名称
SqlDataReader的GetName方法接受字段序号参数(从0开始),返回相应的字段名称。
l         字段数据类型
SqlDataReader的GetFieldType方法和GetDataTypeName方法均接受字段序号参数(从0开始),分别返回对应字段的.Net数据类型名称和该字段在数据库中数据类型名称。
l         确定字段序号
基于字段序号从结果集中获取数据能够提高代码的性能,当知道字段的名称但不知道其序号时,可以使用SqlDataReader的GetOrdinal方法,此方法的参数为字段名称的字符串,返回值为相应字段在结果集中的序号。
l         结果集其它附加架构信息
详细的架构信息可由SqlDataReader的GetSchemaTable方法获取,此方法返回一个DataTable对象。
l         使用CommandBehavior
SqlCommand类的ExecuteReader方法被重载,接受CommandBehavior的枚举值作为参数来控制返回的内容;无参数 的ExecuteReader方法返回的SqlDataReader对象包含查询的结果及基本架构信息;以 CommandBehavior.SchemaOnly作为参数的ExecuteReader方法只返回结果集的架构信息(相当于表头),返回的 SqlDataReader没有数据行。
3:结果集的字段数据类型问题
l         强类型Getter
以Object数据类型作为中间数据类型从SqlDataReader中获取数据存在装箱与开箱的过程,为减少此不必要的系统开销,使用 SqlDataReader的强类型Get方法(GetString、GetInt32、GetDateTime等)分别获取与结果集数据类型相同的数据 可以提供数据获取速度。
l         处理Null
当数据库的字段值为null时,使用SqlDataReader的强类型Get方法去获取数据时会产生一个SqlNullValueException错误,因此对于数据库中可以为空的字段获取数据之前一定要检查其值是否为null。
如果数据库某字段的值为null,在.Net环境下,它被设置为DBNull.Value。
SqlDataReader的IsDBNull方法确定结果集中的某列是否为Null值,接受列序号的整数为参数,返回值为True和False,
4:SqlTypes
l         数据溢出问题
       SqlDataReader从数据库中获取数据并将数据转换成对应的.Net数据类型,此过程可以产生 OverflowException错误,例如SQL中的Decimal数据利用SqlDataReader的GetDecimal方法转换成Net的 Decimal时有发生数据溢出的可能。SqlTypes类用来解决此类问题。
l         SqlTypes的强类型Getter
SqlDataReader的SqlTypes的强类型的Get方法(GetSqlDecimal、GetSqlInt32等)从结果集中返回SqlTypes类型的数据,而且这些已经具备处理Null值的能力,在获取数据前不用检查是否为null值。
SqlTypes类位于System.Data.SqlTypes命名空间下。
5:处理查询结果的多个结果集
       当SqlCommand的CommandText属性多条Sql语句时,其执行ExecuteReader方法时产生的SqlDataReader对象将包含多个结果集,SqlDataReader的NextResult方法能够使游标指针在不同的结果集中遍历。
三.参数化查询
1:非参数化的查询存在安全问题
       当应用系统的用户信息以一个表的形式存储在数据库中,用户登陆应用系统时用以下语句来判断用户是否合法:
       Select Count(*) From Userinfo where UserName=’txt1.text’ And PassWord=’txt2.text’
其中txt1和txt2为两个text控件,当恶意用户输入“×××’ Or 1=1 --”Sql语句如下:
Select Count(*) From Userinfo where UserName=’ ×××’ Or 1=1 --’ And PassWord=’txt2.text’
双连字符“--”在SQL Server中表示后面的内容为注释,如此恶意用户可以正常进入系统。
2构成参数化查询的两种方式
       查询语句如下:StrSql=”Select * from Orders where CustomerID=@CustomerID”,其中“@CustomerID”代表一个查询参数。
       在.Net对象模型下执行一个参数化查询,需要像SqlCommand对象的Parameters集合中添加Parameter对象。
l         AddWithValue方法
例如cmd.Parameters.AddWithValue(“@CustomerID”,”ALFKI”)。AddWithValue方法生成一个新的SqlParameter对象,并设置新对象的ParameterName和Value属性。
l         用New关键字创建新的参数对象
SqlParameter p=New SqlParameter(); p.ParameterName=@CustomerID;
p.Value=”ALFKI”; cmd.Parameters.Add(p);
3:参数的数据类型
l         推断数据类型
在上述两种构成参数化查询的两种方法中都没有设置参数的数据类型,这是因为SqlParameter可以根据它的Value属性的内容判断数据类型。
l         显式设置参数的数据类型
SqlParameter类的重载构造方法可以接受SqlDbType的枚举值来设置参数的类型以及int值确定参数的Size。例如:
SqlParameter p=New SqlParameter(“@CustomerID”, SqlDbType.NVarChar,5);
4:参数方向
       参数化查询包括输入参数和输出参数两种,可以利用参数化查询的输出参数达到SqlCommand的ExecuteScalar方法的功能,从数据库中输出单行单列的值。例如:
       Strsql=”Select @UnitPrice=UnitPrice from Products where ProductName=@ProductName”;
       SqlParameter pUnitPrice,pProductName;
       pUnitPrice=cmd.Parameters.Add(“@UnitPrice”,SqlDbType.Money);
       pUnitPrice.Direction=ParameterDirection.Output;
                     ……
       cmd.ExecuteNonQuery();
       pUnitPrice.Value 即为所需要的结果,如果查询结果没有记录行,则pUnitPrice.Value的值为DBNull.Value 。
5:存储过程
       利用SqlCommand对象调用存储过程,将SqlCommand对象的CommandText属性 设置为存储过程名;CommandType属性设置为CommandType.StoredProcedure;向SqlCommand对象的 Parameters集合中添加SqlParameters,其中对应的存储过程中的输入输出参数只要正确设置参数的Dirction属性即可。