下载 第9章连接、命令和过程 上一章讨论了ADO的基础知识,内容主要涉及 Recordset对象以及对数据的处理。在大多 数例子中,只是通过指定数据库的表名来获取数据,但正如从对象模型中看到的,ADO还有 其他允许访问数据的对象 本章将要更详细地介绍这些对象,特别将研究以下内容 · Connection对象,以及如何用它来获取数据和运行命令。 Command对象,为什么需要该对象及其所具有的功能。 如何运行存储过程,特别是那些需要参数的存储过程 些简单的改善ADO性能的优化技巧 数据整形的概念及如何使用。 如同介绍 Recordset对象那样,我们不打算覆盖所涉及对象的全部方法和属性。在这里只 探讨其中最重要的主题,以及那些适用于ASP开发人员的方法与属性。 9.1 Connection对象 前一章中已经提及, Connection对象是为我们与数据存储提供连接的对象,但这并非 Connection对象的全部功能。除了存储连接的细节外(比如数据存储的类型,以及其支持的特 性),也可以利用 Connection对象运行命令。 这些命令可能是査询动作,比如更新、插入或删除操作,也可以是返回一个记录集的命 令。读者可能会觉得奇怪:既然有了 Recordset对象,这又有什么用?这正是ADO的灵活性所 在,可以根据当前的情况,以及对当前任务的适用性选择使用任一种对象。 从 Connection对象运行的命令一般是查询动作,但了解能够得到返回的记录集也是非常有 用的 9.11返回一个记录集 为了从 Connection对象返回一个记录集,要使用 Execute方法。语法是: Connection. Execute CommandText, [Records Affected], [Options 参数及说明如表9-1所示。 表9-1 Connection对象的 Execute方法的参数及说明 参数 说明 Commands text 执行的命令文本。与 Recordset的Open方法中的 Source参数相同,也能代表一个现 受命令执行影响的记录数 Options 命令选项,可以是一个或多个 CommandType Enum或 Execute Enum常数,详 细的值请见上一章
下载 第9章 连接、命令和过程 上一章讨论了A D O的基础知识,内容主要涉及 R e c o r d s e t对象以及对数据的处理。在大多 数例子中,只是通过指定数据库的表名来获取数据,但正如从对象模型中看到的, A D O还有 其他允许访问数据的对象。 本章将要更详细地介绍这些对象,特别将研究以下内容: • Connection对象,以及如何用它来获取数据和运行命令。 • Command对象,为什么需要该对象及其所具有的功能。 • 如何运行存储过程,特别是那些需要参数的存储过程。 • 一些简单的改善A D O性能的优化技巧。 • 数据整形的概念及如何使用。 如同介绍R e c o r d s e t对象那样,我们不打算覆盖所涉及对象的全部方法和属性。在这里只 探讨其中最重要的主题,以及那些适用于 A S P开发人员的方法与属性。 9.1 Connection对象 前一章中已经提及, C o n n e c t i o n对象是为我们与数据存储提供连接的对象,但这并非 C o n n e c t i o n对象的全部功能。除了存储连接的细节外 (比如数据存储的类型,以及其支持的特 性),也可以利用C o n n e c t i o n对象运行命令。 这些命令可能是查询动作,比如更新、插入或删除操作,也可以是返回一个记录集的命 令。读者可能会觉得奇怪:既然有了 R e c o r d s e t对象,这又有什么用?这正是 A D O的灵活性所 在,可以根据当前的情况,以及对当前任务的适用性选择使用任一种对象。 从C o n n e c t i o n对象运行的命令一般是查询动作,但了解能够得到返回的记录集也是非常有 用的。 9.1.1 返回一个记录集 为了从C o n n e c t i o n对象返回一个记录集,要使用 E x e c u t e方法。语法是: Connection.Execute CommandText, [RecordsAffected], [Options] 参数及说明如表9 - 1所示。 表9-1 Connection对象的E x e c u t e方法的参数及说明 参 数 说 明 C o m m a n d s Te x t 执行的命令文本。与R e c o r d s e t的O p e n方法中的S o u r c e参数相同,也能代表一个现 有的C o m m a n d对象 R e c o r d s A ff e c t e d 受命令执行影响的记录数 O p t i o n s 命令选项,可以是一个或多个 C o m m a n d Ty p e E n u m或E x e c u t e O p t i o n E n u m常数,详 细的值请见上一章
274Asp;高编程 Chinapub.com 下载 Execute方法可选择地返回一个记录集,在这种情况下只要将返回值赋给记录集变量。例如: Set conPubs Server Createobject(" ADODB Connection") conPubs. Open strconn Set rsAuthors conPubs Execute ('Authors") 读者可能会奇怪使用 Connection对象的 Execute方法与使用 Recordset对象的open方法之间 到底有什么区别?看上去区别不是很大,使用 Recordset对象的open方法可以改变光标类型和 锁定类型。这些选项对于 Connection对象的 Execute方法是不可用的,因此永远只能得到一个 只能前移的、只读的记录集 9.1.2操作命令 如果正在运行操作命令,比如一个 SQL UPDATE语句,那么可以使用 Records A ffected参 数找出有多少条记录受到该命令的影响。例如 s string strsqL "UPDATE Titles SET Price Price *1.10& HERE Type=.'. conPubs. Execute strsqL, lngRecs, adcmaText esponse. Write lngRecs & records were updated 上述代码将所有类型为 Business的书的单价增加了10%一旦 Execute命令执行完毕,受 Update命令影响的记录数就返回到变量 Ing recs中,这就是 Records ffected参数 注意,已经为命令指定了 ad CmdText选项,告诉 ADOCommandText参数是一个文本命令。 一般这不是严格必须的,其目的只是让ADO预先知道执行的命令属于何种类型,这样能够提 高性能。记住,这个值可以是一个或多个 Command Type Enum值 无记录集返回 如果上面的例子不返回记录集,那么在 Execute语句中加入另一个选项也是较好的方法 conPubs. Execute strSQL, lngRecs, adcmdText adExecuteNoRecords 使用 adExecute Norecords告诉ADO执行的命令不返回任何记录。所以,ADO不必费心去 创建一个记录集。如果省略了该选项,那么ADO将会创建一个空的记录集,很明显这浪费了 时间,因此加上这个选项将会加快语句的执行 92 Command对象 Command对象特定地为处理各种类型的命令而设计,特别是那些需要参数的命令。与 Connection对象相似, Command对象可以运行返回记录集和不返回记录集两种类型的命令 实际上,如果命令不含有参数,那么它并不关心是使用 Connection对象,还是 Command对象, 还是 Records对象。 921返回记录集 对于一个返回记录集的命令,可使用 Execute方法。然而,与 Connection对象不同,必须
Execute方法可选择地返回一个记录集,在这种情况下只要将返回值赋给记录集变量。例如: 读者可能会奇怪使用 C o n n e c t i o n对象的E x e c u t e方法与使用R e c o r d s e t对象的O p e n方法之间 到底有什么区别?看上去区别不是很大,使用 R e c o r d s e t对象的O p e n方法可以改变光标类型和 锁定类型。这些选项对于 C o n n e c t i o n对象的E x e c u t e方法是不可用的,因此永远只能得到一个 只能前移的、只读的记录集。 9.1.2 操作命令 如果正在运行操作命令,比如一个 SQL UPDAT E语句,那么可以使用 R e c o r d s A ff e c t e d参 数找出有多少条记录受到该命令的影响。例如: 上述代码将所有类型为 B u s i n e s s的书的单价增加了 1 0 %。一旦E x e c u t e命令执行完毕,受 U p d a t e命令影响的记录数就返回到变量 l n g R e c s中,这就是R e c o r d s A ff e c t e d参数。 注意,已经为命令指定了 a d C m d Te x t选项,告诉A D O C o m m a n d Te x t参数是一个文本命令。 一般这不是严格必须的,其目的只是让 A D O预先知道执行的命令属于何种类型,这样能够提 高性能。记住,这个值可以是一个或多个 C o m m a n d Ty p e E n u m值。 无记录集返回 如果上面的例子不返回记录集,那么在 E x e c u t e语句中加入另一个选项也是较好的方法: 使用a d E x e c u t e N o R e c o r d s告诉A D O执行的命令不返回任何记录。所以, A D O不必费心去 创建一个记录集。如果省略了该选项,那么 A D O将会创建一个空的记录集,很明显这浪费了 时间,因此加上这个选项将会加快语句的执行。 9.2 Command对象 C o m m a n d对象特定地为处理各种类型的命令而设计,特别是那些需要参数的命令。与 C o n n e c t i o n对象相似, C o m m a n d对象可以运行返回记录集和不返回记录集两种类型的命令。 实际上,如果命令不含有参数,那么它并不关心是使用 C o n n e c t i o n对象,还是C o m m a n d对象, 还是R e c o r d s e t对象。 9.2.1 返回记录集 对于一个返回记录集的命令,可使用 E x e c u t e方法。然而,与 C o n n e c t i o n对象不同,必须 274计计ASP 3 高级编程 下载
第连接,命争和过程275 使用 CommandText属性,而不能在 Execute方法中使用命令文本 Set cmdAuthors Server Createobject(ADODB. Command) uthors. CormmandText . Authorg rsAuthors cmdAuthors Execut 这是告诉 Command对象去执行一个简单的、返回一个只读记录集的命令的最简便方法 Execute方法也有一些可选参数,如表9-2所示。 表92 Command对象的 Execute方法的参数及说明 Records A ffected 命令影响的记录数 Parameters 参数值数组 命令选项,与 Recordset的open方法中的 Options选项相似 参数 Records Affected与 Options同前面解释的一样,另外也可以使用 CommandType属性设 置命令类型 Set cmdAuthors Server Createobject(ADODB. Command.) cmdAuthors CommandText Authors cmdAuthors CommandType adCmdTable Set rsAuthors e cmdAuthors Execute 如果不设置其他参数,也可以在 Execute行上设置,必须为它们使用逗号: Set rsAuthors cmdAuthors Execute( 在本章后面处理存储过程和参数时,将会看到参数 Parameters的用途 改变光标类型 值得注意是,使用 Execute方法返回的记录集具有缺省的光标和锁定类型。这意味着这 只能前移的、只读的记录集。虽然使用 Execute方法不能改变这种情况,但对这个问题有一个 解决的方法。 如果需要使用一个命令,并且要求不同的光标和锁定类型,那么应该使用 Record pen方法,此时 Command对象作为 Recordset的数据源。例如 cmdAuthors Activeconnection strConn cmdAuthors. CommandText = Authors cmdAuthors CommandType adcmaTable rsAuthors. Open cmdAuthors, adopenDymamic, adLockoptimistic 意,在Open命令行中忽略了连接细节,因为连接设置在 Command对象中。连接细节在 命令打开前已经设置在 Command对象的 Active Connetion属性中 922操作命令 对于操作命令,比如那些无记录返回的更新命令,整个过程相似,只需移去设置记录集 的代码: Set cmdUpdate= Server Createobject("ADODB. Command
使用C o m m a n d Te x t属性,而不能在E x e c u t e方法中使用命令文本。 这是告诉C o m m a n d对象去执行一个简单的、返回一个只读记录集的命令的最简便方法。 E x e c u t e方法也有一些可选参数,如表 9 - 2所示。 表9-2 Command对象的E x e c u t e方法的参数及说明 参 数 说 明 R e c o r d s A ff e c t e d 受命令影响的记录数 P a r a m e t e r s 参数值数组 O p t i o n s 命令选项,与R e c o r d s e t的O p e n方法中的O p t i o n s选项相似 参数R e c o r d s A ffected 与O p t i o n s同前面解释的一样,另外也可以使用 C o m m a n d Ty p e属性设 置命令类型: 如果不设置其他参数,也可以在 E x e c u t e行上设置,必须为它们使用逗号: 在本章后面处理存储过程和参数时,将会看到参数 P a r a m e t e r s的用途。 改变光标类型 值得注意是,使用 E x e c u t e方法返回的记录集具有缺省的光标和锁定类型。这意味着这是 只能前移的、只读的记录集。虽然使用 E x e c u t e方法不能改变这种情况,但对这个问题有一个 解决的方法。 如果需要使用一个命令,并且要求不同的光标和锁定类型,那么应该使用 R e c o r d s e t的 O p e n方法,此时C o m m a n d对象作为R e c o r d s e t的数据源。例如: 注意,在O p e n命令行中忽略了连接细节,因为连接设置在 C o m m a n d对象中。连接细节在 命令打开前已经设置在C o m m a n d对象的A c t i v e C o n n e t i o n属性中。 9.2.2 操作命令 对于操作命令,比如那些无记录返回的更新命令,整个过程相似,只需移去设置记录集 的代码: 第 9章 连接、命令和过程计计275 下载
270Ap;海箱程 Chinapub.com 下载 strsQL·“ UPDATE Titles sET Price Price*1,10&· WHERE Type=" Busines cmdUpdate ActiveConnection strConn cmdUpdate CommandText m SSQL cmdUpdate CommandType adcmdText cmdUpdate. Execute , adExecuteNoRecords 注意,我们在此设置了命令类型,然后在 Execute行中增加了额外的设置选项。这段代码 运行 UPDATE命令,并且保证不会创建新的记录集 92.3存储过程 存储过程的使用是 Command对象得到应用的一个领域。存储过程(有时也称存储查询)是 存储在数据库中预先定义的SQL查询语句 为什么应该创建和使用存储过程而不是在代码中直接使用SQL字符串呢?主要有以下几 个理由: ·存储过程被数据库编译过。这样可以产生一个“执行计划”,因此数据库确切地知道它 将做什么,从而加快了过程的执行速度 ·存储过程通常被数据库高速缓存,这样使它们运行得更快,因为此时不需从磁盘中读取 它们。并非所有的数据库都支持这种缓存机制,比如微软的 Access就不支持,而SQL Server却支持 通过指定数据库中的表只能被存储过程修改,可以确保数据更安全。这意味着具有潜在 危险的SQL操作不会执行 可以避免将ASP代码和冗长的SQL语句混在一起,从而使ASP代码更易于维护。 可以将所有SQL代码集中存放于服务器。 可以在存储过程中使用输出参数,允许返回记录集或其他的值。 般说来,存储过程几乎总是比相当的SQL语句执行速度快 为了使用存储过程,只要将存储过程的名字作为命令文本,并设置相应的类型。例如, 考虑前面更新书价的例子。如果在 SQL Server上创建一个存储过程,可以编写代码 CREATE PROCEDURE usp_UpdatePrices UPDATE Titles 1,10 WHERE Type=Business 对于微软的 access数据库,可以使用一个简单的更新 查询语句完成相同的任务,如图9-1所示 要在ASP网页中运行该存储过程,只需使用以下代码: t cmdupdate Server createobject( ADODB. Command") cmdUpdate. ActiveConnecti strconv cmdUpdate. CommandText =usp_UpdatePrices mdUpdate CommandType adCmdstoredProc 图9-1使用微软的 Access ndupdate. Execute , adExecuteNoRecords 数据库完成更新查询 这只是运行存储过程。没有记录集返回,因为只是在更新数据。需要记住的是,除非确
注意,我们在此设置了命令类型,然后在 E x e c u t e行中增加了额外的设置选项。这段代码 运行U P D AT E命令,并且保证不会创建新的记录集。 9.2.3 存储过程 存储过程的使用是 C o m m a n d对象得到应用的一个领域。存储过程 (有时也称存储查询 )是 存储在数据库中预先定义的 S Q L查询语句。 为什么应该创建和使用存储过程而不是在代码中直接使用 S Q L字符串呢?主要有以下几 个理由: • 存储过程被数据库编译过。这样可以产生一个“执行计划”,因此数据库确切地知道它 将做什么,从而加快了过程的执行速度。 • 存储过程通常被数据库高速缓存,这样使它们运行得更快,因为此时不需从磁盘中读取 它们。并非所有的数据库都支持这种缓存机制,比如微软的 Access 就不支持,而S Q L S e r v e r却支持。 • 通过指定数据库中的表只能被存储过程修改,可以确保数据更安全。这意味着具有潜在 危险的S Q L操作不会执行。 • 可以避免将A S P代码和冗长的S Q L语句混在一起,从而使A S P代码更易于维护。 • 可以将所有S Q L代码集中存放于服务器。 • 可以在存储过程中使用输出参数,允许返回记录集或其他的值。 一般说来,存储过程几乎总是比相当的 S Q L语句执行速度快。 为了使用存储过程,只要将存储过程的名字作为命令文本,并设置相应的类型。例如, 考虑前面更新书价的例子。如果在 SQL Server上创建一个存储过程,可以编写代码: 对于微软的 A c c e s s数据库,可以使用一个简单的更新 查询语句完成相同的任务,如图 9 - 1所示。 要在A S P网页中运行该存储过程,只需使用以下代码: 这只是运行存储过程。没有记录集返回,因为只是在更新数据。需要记住的是,除非确 276计计ASP 3 高级编程 下载 图9-1 使用微软的A c c e s s 数据库完成更新查询
china-pup.com 第9章连接、命令和过程277 实需要,不要创建记录集。 虽然这样做也可以,但并不是很灵活,因为仅仅处理一种类型的书。更好的做法是创 个允许我们选择书类型的过程,这样就不必为每类书创建一个过程。同样也可去掉固定的 10%的更新,这样使得灵活性更好。那么,如何才能做到这一点呢,很简单,使用参数。 参数 存储过程的参数(或变量)与一般的过程和函数的参数一样,可以传到函数内部,然后函数 可以使用它的值。 SQL Server(其他数据库也一样,包括 Access)中的存储过程都具有这样的功 为了使存储过程能处理多种类型的书,甚至允许用户指定价格的增加(或减少),需要增加 一些参数 CREATE PROCEDURE usp_UpdatePrices percent Money 大(1+ PErcent/100) 现在,存储过程 usp UpdatePrices'带有两个参数 一个是书的类型(@Type)。 一个是书价变化的百分比( pErcent) 与Ⅴ SCript的函数一样,这些参数都是变量。然而,与 VBScript和其他脚本语言不同是: 在这些脚本语言中的变量都是 variant类型,而SQL变量具有确定的类型(char、 Money等等) 必须遵守SQL变量的命名规范,即变量必须以符号@开始 注意,我们让百分数作为一个整数(如10代表10%),而不是作为一个分数值传入此过程 这只是让存储过程变得更直观一些。 2. Parameters集合 那么,现在有了带参数的存储过程,但如何通过ADO来调用它呢?我们已经见到了如何 用 Command对象调用不带参数的存储过程,实际上,它们之间并没有什么不同。不同之处在 于 Parameters集合的使用。 Parameters集合包含存储过程中每个参数的 Parameter对象。然而,ADO并不会自动地知 道这些参数是什么,因此,必须用 Create Parameter方法创建它们,采用下面的形式: Set Parameter Command CreateParameter (Name, [Type], [Direction) 参数及说明如表9-3所示。 表9-3 Create Parameter方法的参数及说明 Name 参数名。这是 Parameters集合中的参数名,不是存储过程中的参数名。然而,使用相同 的名字是一个好的做法 参数的数据类型。可以是一个 adData Type常数,详见附录 Direction 参数的方向,指明是参数向存储过程提供信息,还是存储过程向ADO返回信息。可以 是下面的值之
实需要,不要创建记录集。 虽然这样做也可以,但并不是很灵活,因为仅仅处理一种类型的书。更好的做法是创建 一个允许我们选择书类型的过程,这样就不必为每类书创建一个过程。同样也可去掉固定的 1 0 %的更新,这样使得灵活性更好。那么,如何才能做到这一点呢,很简单,使用参数。 1. 参数 存储过程的参数(或变量)与一般的过程和函数的参数一样,可以传到函数内部,然后函数 可以使用它的值。SQL Server(其他数据库也一样,包括 A c c e s s )中的存储过程都具有这样的功 能。 为了使存储过程能处理多种类型的书,甚至允许用户指定价格的增加 (或减少),需要增加 一些参数: 现在,存储过程u s p _ U p d a t e P r i c e s带有两个参数: • 一个是书的类型( @ Ty p e )。 • 一个是书价变化的百分比( @ P e r c e n t )。 与V B S c r i p t的函数一样,这些参数都是变量。然而,与 V B S c r i p t和其他脚本语言不同是: 在这些脚本语言中的变量都是 v a r i a n t类型,而S Q L变量具有确定的类型 ( c h a r、M o n e y等等)。 必须遵守S Q L变量的命名规范,即变量必须以符号 @开始。 注意,我们让百分数作为一个整数 (如1 0代表1 0 % ),而不是作为一个分数值传入此过程。 这只是让存储过程变得更直观一些。 2. Pa r a m e t e r s集合 那么,现在有了带参数的存储过程,但如何通过 A D O来调用它呢?我们已经见到了如何 用C o m m a n d对象调用不带参数的存储过程,实际上,它们之间并没有什么不同。不同之处在 于Pa r a m e t e r s集合的使用。 Pa r a m e t e r s集合包含存储过程中每个参数的 Pa r a m e t e r对象。然而, A D O并不会自动地知 道这些参数是什么,因此,必须用 C r e a t e P a r a m e t e r方法创建它们,采用下面的形式: 参数及说明如表9 - 3所示。 表9-3 CreateParameter方法的参数及说明 参 数 说 明 N a m e 参数名。这是P a r a m e t e r s集合中的参数名,不是存储过程中的参数名。然而,使用相同 的名字是一个好的做法 Ty p e 参数的数据类型。可以是一个 a d D a t a Ty p e常数,详见附录 D i r e c t i o n 参数的方向,指明是参数向存储过程提供信息,还是存储过程向 A D O返回信息。可以 是下面的值之一: 第 9章 连接、命令和过程计计277 下载