在连接环境下的数据存取主讲:梁瑞仕Email:liangrs@foxmail.com本节内容在连接的环境中工作创建Command 执行返回多行记录的Command执行返回单值的Command执行无返回值的Command使用事务本节内容在连接 的环境中工作创建Command执行返回多行记录的Command执行返回单值的Command执行无返回值的Comman d使用事务在连接的环境中工作需要持续的连接使用场景:证券公司股票交易软件需要实时显示股票报价银行软件需要实时查询货币 汇率工厂监控软件需要实时监控产品的产量和库存数量......连接环境中数据访问模式在连接的环境中,资源保持在服务器端,直到 连接关闭1.连接到SQLServer2.提交查询命令3.通过DataReader读取查询结果4.关闭DataReader 5.关闭连接编程模型本节内容在连接的环境中工作创建Command执行返回多行记录的Command执行返回单值的Co mmand执行无返回值的Command使用事务什么是Command对象?一个Command对象表示要在数据库服务器 上执行的SQL语句或存储过程不同的数据提供程序实现了不同的Command类Command对象属性参考MSDN:Sql Command属性P69表2.2Command对象方法参考MSDN:SqlCommand方法P68表2.1 创建一个Command对象示例代码查询Northwind数据库的products表,步骤:1.构造Command对象; 2.设置Command对象的连接属性;3.设置Command对象的SQL语句及其类型;4.执行Command对象的Ex ecuteReader()方法获取数据课堂练习创建一个SqlConnection对象,设置正确的连接字符串(可连接到SQLS erver2005示例数据库)创建一个SqlCommand对象,编写一个select查询语句(可查询任意数据表的任意字段), 设置SqlCommand对象的相关属性执行ExecuteReader方法并赋值给一个SqlDataReader对象使用Sql DataReader的HasRows属性来判断是否获取到数据,并在控制台输出提示信息参考:P68C#代码构造更加复杂的C ommand对象1.通过直接的参数赋值建立查询命令课堂练习:新建一个项目,拷贝前面的代码,并将前面的sql语句改写为直 接参数赋值形式构造更加复杂的Command对象2.通过Parameter对象生成查询参数,并传递给Command对象的P arameters属性Why?关于SQL注入攻击用户可以提交一段数据库查询代码,根据程序返回的结果,获得某些他想得知的数据 ,这就是所谓的SQLInjection,即SQL注入。通过直接的参数赋值建立查询命令的方式没有对用户输入数据的合法性进行判断, 使应用程序存在安全隐患,这就是SQL注入攻击。编程为Command对象创建参数创建SqlParameter对象SqlPar ametersp1=newSqlParameter();设置参数属性主要参数将参数添加到Command.Parame ters集合使用Command.Parameters.Add()方法添加参数Parameter对象的公共属性参考MSDN :SqlParameter属性P73表2.5课堂练习编写一个SQL查询语句,将其中where部分待查询的具体数值用参 数实现,并通过Parameter对象生成查询参数,例如:selecttop4fromcustomerswhere ContactTitle=‘owner‘,改为:selecttop4fromcustomerswhereCon tactTitle=@ContactTitle示例示例:Parameter对象的使用示例本节内容在连接的环境中工作 创建Command执行返回多行记录的Command执行返回单值的Command执行无返回值的Command使用事 务执行返回多行记录的命令DataReader类负责以只读和只进的方式,读取结果集中的每行记录效率高,因为每次仅有一条记录调 入内存中,无需等待整个查询结束SQLServer:SqlDataReader创建和使用DataReader对象1.Co mmand.ExecuteReader()方法创建一个DataReader对象2.通过DataReader.Read()函数逐 行读取记录3.通过DataReader.Close()关闭DataReader,释放连接,否则连接始终被占用示例代码读取返 回结果的前2列的值本例采用索引器和GetValue方法的方式获取各个列值采用类型化访问方法读取列值通过向DataReade r传递列的名称或序号引用,可以访问返回行的每一列。为了实现最佳性能,DataReader提供了一系列方法,能够访问其本机数据 类型(GetDateTime、GetDouble、GetString、GetInt32等)的列值,这些方法通过参数对列进行定位 显然,如果已知相应数据类的数据类型,那么使用类型化访问器方法,将减少在检索列值时所需的类型转换时间,提高最佳访问性能。示例代 码读取返回结果的前2列的值本例采用类型化方法获取各个列值多活动结果集的使用多个活动结果集(MARS)是用于SQL Server2005的一项新功能,允许在单个连接上执行多个批处理。在以前版本的SQLServer上使用SqlData Reader对象访问多个结果集,必须对每个SqlCommand对象使用独立的SqlConnection对象,或者在不同的 时间段独立使用同一个SqlConnection对象。演示:分别使用多个命令查询不同数据而在SQLServer2005中, 如果启用了MARS,则可以透明的使用同一个连接打开多个结果集,这样避免创建多个连接,减少了开销和代价。演示:使用MARS参考 P56sample1_12,P58sample1_13演示:分别使用多个命令查询不同数据Step1:建立2个Sq lCommand查询命令,使用相同的SqlConnection对象演示:分别使用多个命令查询不同数据Step2:创建2个Sq lDataReader数据阅读器,注意:在使用某个SqlDataReader对象时,必须先关闭前面正在使用的SqlDataRead er对象课堂练习课堂练习1参照刚才的演示步骤,理解并完成相似的代码课后练习2.利用不同的SqlConnection对 象分别为多个查询命令使用,步骤:1.创建多个不同的SqlConnection2.创建多个不同的SqlCommand查询命 令,每个SqlCommand查询命令分别绑定不同的SqlConnection对象3.创建多个SqlDataReader数据阅读器 ,每个SqlDataReader数据阅读器执行不同的SqlCommand查询命令。注意:在使用某个SqlDataReader对象时 ,无需关闭其他正在使用的SqlDataReader对象back演示:使用MARS1.启用MARS选项默认情况下SQL Server2005禁用MARS功能。可以通过在连接字符串中添加“MultipleActiveResultSets=True ”关键字来启用此功能。“True”是启用MARS的唯一有效值。演示:使用MARS2.与前面演示的步骤完全相同创建2个S qlCommand查询命令(使用相同的SqlConnection对象),创建2个SqlDataReader数据阅读器(但无需关闭任 何一个)。批处理T-SQL语句,多结果集的使用批处理T-SQL语句是指同时一次性执行多个SQL命令,并返回所有的查询结 果,因此,存在多个结果集。注意:多结果集与MARS中的多活动结果集不同,多结果集是指一个查询SqlCommand对象包含一批(多 个)查询命令,经过执行批处理SQL语句,返回了一个SqlDataReader结果,但其中包含了多部分的查询结果;而多活动结果集是指 多个不同的查询命令分别使用不同的SqlCommand对象,并且返回多个不同的SqlDataReader查询结果演示:批处理T -SQL语句,多结果集的使用演示:批处理T-SQL语句,多结果集的使用1.创建一个SqlCommand查询命令,其中 包含了多条查询语句演示:批处理T-SQL语句,多结果集的使用2.创建SqlDataReader数据阅读器,执行SqlCo mmand查询命令。SqlDataReaderreader2=cmd2.ExecuteReader();演示:批处理 T-SQL语句,多结果集的使用3.使用NextResult()方法,循环读取多结果集课堂练习参照多结果集使用的演示 ,编程实现批处理T-SQL语句小结Command对象属性参考MSDN:SqlCommand属性P69表2.2 小结Command对象方法参考MSDN:SqlCommand方法P68表2.1小结Parameter对象的公 共属性参考MSDN:SqlParameter属性P73表2.5小结SqlDataReader一些重要的方法注意 事项若要创建SqlDataReader,必须调用SqlCommand对象的ExecuteReader方法,而不要直接使 用构造函数。在使用SqlDataReader时,关联的SqlConnection正忙于为SqlDataReader 服务,对SqlConnection无法执行任何其他操作,只能将其关闭。除非调用SqlDataReader的Close方 法,否则会一直处于此状态。例如,在调用Close之前,无法检索输出参数。SqlDataReader的用户可能会看到在读取 数据时另一进程或线程对结果集所做的更改。但是,确切的行为与执行时间有关。当SqlDataReader关闭后,只能调用Is Closed和RecordsAffected属性。尽管当SqlDataReader存在时可以访问RecordsAffe cted属性,但是请始终在返回RecordsAffected的值之前调用Close,以保证返回精确的值。本节内容在 连接的环境中工作创建Command执行返回多行记录的Command执行返回单值的Command执行无返回值的Comm and使用事务检索单个值(例如一个聚合值)。何时返回结果为单一值?查询某种股票的价钱查询员工人数COUNT,MAX ,MIN,AVE......SqlCommand类的ExecuteScalar方法返回查询结果集中第一行的第一列。 忽略其他列或行。返回值类型为Object传统ADO中,整个结果集从服务器端返回到客户端ADO.NET比ADO更高效 示例示例:返回聚合函数值例如:若想查询满足某个条件的结果的数目,可以使用COUNT()函数,步骤:1.定义SqlCom mand查询命令2.对查询结果进行强制类型转换示例:返回单个查询结果值例如:若只需要某个查询结果的第1行第1列的值,同样可 以使用ExecuteScalar方法,步骤:1.定义SqlCommand查询命令2.对查询结果进行强制类型转换本节内容 在连接的环境中工作创建Command执行返回多行记录的Command执行返回单值的Command执行无返回值的Com mand使用事务执行无返回结果的命令什么是DDL和DCL语句?如何执行DDL和DCL语句?什么是DML更新语 句?如何执行DML更新语句?排查和解决数据更新错误DDL和DCL语句DDL:DataDefinitionLa nguage创建和管理数据库对象DCL:DataControlLanguage授予访问权限DDL和DCL语句 示例DDL语句示例:DCL语句示例:执行DDL和DCL语句使用Command.ExecuteNonQuery( )执行DDL和DCL,但不查询数据返回受影响的行数代码示例:演示参考P150代码步骤:建立连接设置SqlC ommand命令对象使用ExecuteNonQuery方法执行命令课堂练习:执行DDL创建一个数据表CREATETA BLECustomer_Data(customer_idsmallint,first_namechar(20),las t_namechar(20),phonechar(10))课堂练习:执行DDL修改数据表(增加一列)ALTERTA BLECustomer_DataADDmiddle_initialchar(1)删除数据表DROPTABLECu stomer_DataDML语句DataManipulationLanguage数据加工语句,用于修改数据库中的数据 DML语句:执行DML语句使用Command.ExecuteNonQuery()返回受影响的行数示例:演示参考 P150代码关于DDL的使用,完全一致课堂练习:执行DML语句1插入一行数据(所有列)INSERTINTOCu stomer_DataVALUES(777,''Frankie'',''Stein'',''4895873900'')2插入一 行数据(指定列)INSERTINTOCustomer_Data(customer_id,first_name,last _name)VALUES(777,''Frankie'',''Stein'')课堂练习:执行DML语句更新或改变一行或多行 中指定列的值UPDATECustomer_DataSETfirst_name=''Franklin''WHERElas t_name=''Stein''andcustomer_id=777课堂练习:执行DML语句1删除一行或多行D ELETEFROMCustomer_DataWHEREcustomer_id<1002删除所有的数据行DELE TEFROMCustomer_Data或DELETECustomer_Data综合实验(延后):连接数据源并执行查询1.在SQLServer2005创建一个数据库,并设计若干数据表,填充相应的数据到数据表中2.使用Connection连接数据库3.输出相关的连接配置信息4.编写一个select查询语句,并使用Command对象执行这个查询5.执行ExecuteReader方法并赋值给一个SqlDataReader对象,判断是否获取到数据,并打印输出相关的查询结果6.更进一步:连接到远程服务器的数据库(例如:周围的同学),并使用try-catch-finally方式编程在连接环境下的数据存取DepartmentofComputerEngineering,ZSC在连接环境下的数据存取DepartmentofComputerEngineering,ZSC |
|