下载 第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 下载
278Asp;高编程 Chinapub.com 下载 参数 adParamInput,参数是传给存储过程的输入参数 adParamOutput,参数是从存储过程检索出的输出参数 dParamInputOutput,参数可同时作为输入和输出参数 ad Param Retum value,该参数包含存储过程返回的状态 参数长度。对于固定长度的类型,比如整型,该值可以忽略 旦创建了参数就可以将其追加到 Parameters集合中,例如: Set parvalue cmdUpdate CreateParameter('@Type", adVarwchar, adParamInput 12, Business·) cmdUpdate Parameters Append parvalue Set parvalue cmdUpdate CreateParameter('@Percent, adur maUpdate Parameters Append parvalue 没有必要显式地创建一个对象去保存参数,缺省的 Variant类型已经可以工作得相当好。 如果不想创建一个变量,也可以走捷径,例如下面的代码 mdUpdate. Parameters Append cmdUpdate. CreateParameter("pErcent, adCurrency, adParamInput,, 10) 这使用 Create Parameter方法返回一个 Parameter对象,并用 Append方法接收它。这种方法 比使用变量运行得快,却加长了代码行,可读性比较差。可以根据自己的爱好选择其中一种 方法。 参数加到 Parameters集合后,就保留在其中,因此,不一定在创建参数时就为每个参数赋 值。可以在命令运行前的任何时候设置参数的值。例如 cmdUpdate Parameters Append cmaUpdate. CreateParameter ("@percent", adcurrency, adParamInput) cmdUpdate. Parameters(@Percent)= 10 前一章提到了访问集合中的值有好几种方法, Parameters集合并没有什么不同。上面的例 子使用参数的名字在集合中检索参数,也可以使用索引号进行检索: 以上代码对参数集合中第一个( Parameters集合从0开始编号)参数进行了赋值。使用索引号 比使用名字索引速度快,但很显然使用名字使代码更易读, 重点注意 Parameters集合中参数的顺序必须与存储过程中参数的顺序相一致。 运行带参数的命令 旦加入参数,就可立即运行命令,同时这些参数的值传入存储过程。现在可用一个友 好的网页去更新用户选择的类型的书价。例如,假设有一个名为 Update Prices. asp的网页,其 运行时的界面如图92所示 通过从数据库中获取书类型的列表,可以很轻松地动态创建该页面。首先要做的是包含 文件 Connection.asp,该文件包含了连接字符串(保存在变量 str Conn中)以及对ADO常数的引用
(续) 参 数 说 明 a d P a r a m I n p u t,参数是传给存储过程的输入参数 a d P a r a m O u t p u t,参数是从存储过程检索出的输出参数 a d P a r a m I n p u t O u t p u t,参数可同时作为输入和输出参数 a d P a r a m R e t u r n Va l u e,该参数包含存储过程返回的状态 S i z e 参数长度。对于固定长度的类型,比如整型,该值可以忽略 Va l u e 参数的值 一旦创建了参数就可以将其追加到 P a r a m e t e r s集合中,例如: 没有必要显式地创建一个对象去保存参数,缺省的 Va r i a n t类型已经可以工作得相当好。 如果不想创建一个变量,也可以走捷径,例如下面的代码: 这使用C r e a t e P a r a m e t e r方法返回一个P a r a m e t e r对象,并用A p p e n d方法接收它。这种方法 比使用变量运行得快,却加长了代码行,可读性比较差。可以根据自己的爱好选择其中一种 方法。 参数加到P a r a m e t e r s集合后,就保留在其中,因此,不一定在创建参数时就为每个参数赋 值。可以在命令运行前的任何时候设置参数的值。例如: 前一章提到了访问集合中的值有好几种方法, P a r a m e t e r s集合并没有什么不同。上面的例 子使用参数的名字在集合中检索参数,也可以使用索引号进行检索: 以上代码对参数集合中第一个 ( P a r a m e t e r s集合从0开始编号)参数进行了赋值。使用索引号 比使用名字索引速度快,但很显然使用名字使代码更易读。 重点注意P a r a m e t e r s集合中参数的顺序必须与存储过程中参数的顺序相一致。 运行带参数的命令 一旦加入参数,就可立即运行命令,同时这些参数的值传入存储过程。现在可用一个友 好的网页去更新用户选择的类型的书价。例如,假设有一个名为 U p d a t e P r i c e s . a s p的网页,其 运行时的界面如图9 - 2所示 通过从数据库中获取书类型的列表,可以很轻松地动态创建该页面。首先要做的是包含 文件C o n n e c t i o n . a s p,该文件包含了连接字符串(保存在变量s t r C o n n中)以及对A D O常数的引用, 278计计ASP 3 高级编程 下载
aopub.com 第9章连接、命令和过程 279 这在前面的章节已经讨论过。 Command object Calling a stored procedure with parameters ns page shows how to run a stored procedure with parameters. It uses the atabase and updates the prices of books by a percentage vale, for books or for a particular book type, You should enter the percentage value without the 9 sign(so for a 10% ncrease, ust enter 10). For a decrease enter a negative number. Book Type:「 business Percent Value 10 91999 wrox Press- Professiona ASP 3.Q(ISBN: 1-861002-61-0) 图9-2 Update Prices.asp网页运行时的界面 接下来,可以创建一个窗体(在这儿不显示大量文本,仅仅用一个样本文件)。该窗体调用 个名为 StoredProcedure. asp的文件 FORM NAME=UpdatePrices.Method=Post ACTION="StoredProcedure. asp'> TD>Book Type: 现在开始编写ASP脚本从 titles表中读取书的类型。使用一个SQL字符串只返回唯一的书类 型,然后将返回值放到HTML的 OPTION标记中: im retype im strsQL im strquote Predefine the quote character strQuote Chr (34) Create a recordset strsoL ='SELECT DISTINCT type FRoM titles rsTypes. Open strsQL, strconn Create the book types Response. write <OPTION VALUE="& strquote
这在前面的章节已经讨论过。 图9-2 UpdatePrices.asp网页运行时的界面 接下来,可以创建一个窗体 (在这儿不显示大量文本,仅仅用一个样本文件 )。该窗体调用 一个名为S t o r e d P r o c e d u r e . a s p的文件。 现在开始编写A S P脚本从t i t l e s表中读取书的类型。使用一个 S Q L字符串只返回唯一的书类 型,然后将返回值放到H T M L的O P T I O N标记中: 第 9章 连接、命令和过程计计279 下载
280Asp高箱程 Chinapub.com 下载 rsTypes( Type)& strquote &*>"&rsTypes(*Type) rsTypes MoveNext se Set rsTypes Nothing 显示书的类型后,接着可以构建窗体的其他部分,包括一个允许用户输入书价变化百分 数的文本框 Percent value /TABLE> INPUT TYPE="Submit" VALUE='Run Query> / FORM> 现在看一下 Run Query按钮调用的ASP文件 StoredProcedure. asp。首先,声明变量并从调 用窗体取出书的类型和百分数 Dim Dim Dim Dim ent Get the form values strType w Request Form('lstTypes") curPercent Request Form('txtPercent') 现在可以向用户显示一些确认信息,告诉他们将发生什么 Tell the user what's being done Response. Write "Updating all books*& f type .& strType &.& by·& curPercent&·8 现在重新回到代码内部,在此创建 对象和参数。 with cmdupdate ActiveConnection a strconn CommandText =.usp_UpdatePric 利用从前面网页的窗体中提取的数据值,使用快捷方法创建和增加参数。 Add the parameters Parameters Append CreateParameter('@Type, advarwchar, adParamInput Parameters Append CreateParameter('@Percent, adcurrency, adParamInput,, curpercent) 现在,运行存储过程 Execute the command Execute lngRecs, adExecuteNoRecords
显示书的类型后,接着可以构建窗体的其他部分,包括一个允许用户输入书价变化百分 数的文本框。 现在看一下Run Query按钮调用的A S P文件S t o r e d P r o c e d u r e . a s p。首先,声明变量并从调 用窗体取出书的类型和百分数。 现在可以向用户显示一些确认信息,告诉他们将发生什么。 现在重新回到代码内部,在此创建 C o m m a n d对象和参数。 利用从前面网页的窗体中提取的数据值,使用快捷方法创建和增加参数。 现在,运行存储过程。 280计计ASP 3 高级编程 下载
inapub.com 第连接,命和过程281 End with 为了确认,可以告诉用户已经更新多少条记录。 And finally tell the dure complet happened Response. Write ' Proce lngRecs &.records were updated Set cmaupdate Nothing 这样就有了两个简单页面。前者创建了一个供选择的项目列表,后者使用其中某个项目 值更新数据。这是许多需要显示和更新数据的ASP页面的基础。 传递数组参数 Parameters参数集合一般来说比较好用,但有时稍有麻烦(尤其对于新手)。好在有一种快 捷方法,使用 Execute方法的 Parameters参数。例如,调用存储过程usp_ Update Prices,但不使 Parameters集合。 创建一个 Command对象,并同前面一样设置其属性 Set cmdUpdate Server Createobject('ADODB. Command. Set the pr。pert f the command with cmaupdat ActiveConnection strconn CommandText ="usp_UpdatePrices CommandType adcmdstoredproc 但这里正是差异所在。我们仅是通过 Execute方法传递参数给存储过程,而不是创建参数 并添加到集合中 Execute the command Execute lngRecs, Array(strType, curPercent), adExecuteNoRecords End with 里使用了Aray函数,将单个变量转换为数组,以适于方法调用。这种方法当然也有缺 只能使用输入参数。因为不能指定参数的类型和传递方向,而缺省为输入参数。 ·如果要多次调用存储过程,这种方法速度就比较慢,因为ADO将向数据存储询问参数的 内容及数据类型 集合方法和数组方法之间在速度上的差异非常之小,几乎可以忽略。所以,如果只有输 入参数,可随便使用哪一种。实际上,人们更喜欢使用 Parameters集合的方法,尽管它稍为繁 琐,但是使参数的属性更加明确。 4.输出参数 我们已经知道如何获得受命令影响的记录数,如果需要更多信息,却又不想返回一个记 集,怎么办?也许想从存储过程中返回两个或三个值,但又不想费心创建一个记录集。在 这时,可以定义一个输出参数,其值由存储过程提供。 例如,对于更新书价的程序,如果想在更新之后找出最高价格,可将存储过程改成: Money OuTPUT
为了确认,可以告诉用户已经更新多少条记录。 这样就有了两个简单页面。前者创建了一个供选择的项目列表,后者使用其中某个项目 值更新数据。这是许多需要显示和更新数据的 A S P页面的基础。 3. 传递数组参数 P a r a m e t e r s参数集合一般来说比较好用,但有时稍有麻烦 (尤其对于新手)。好在有一种快 捷方法,使用E x e c u t e方法的P a r a m e t e r s参数。例如,调用存储过程 u s p _ U p d a t e P r i c e s,但不使 用P a r a m e t e r s集合。 创建一个C o m m a n d对象,并同前面一样设置其属性。 但这里正是差异所在。我们仅是通过 E x e c u t e方法传递参数给存储过程,而不是创建参数 并添加到集合中。 这里使用了A r r a y函数,将单个变量转换为数组,以适于方法调用。这种方法当然也有缺 点: • 只能使用输入参数。因为不能指定参数的类型和传递方向,而缺省为输入参数。 • 如果要多次调用存储过程,这种方法速度就比较慢,因为 A D O将向数据存储询问参数的 内容及数据类型。 集合方法和数组方法之间在速度上的差异非常之小,几乎可以忽略。所以,如果只有输 入参数,可随便使用哪一种。实际上,人们更喜欢使用 P a r a m e t e r s集合的方法,尽管它稍为繁 琐,但是使参数的属性更加明确。 4. 输出参数 我们已经知道如何获得受命令影响的记录数,如果需要更多信息,却又不想返回一个记 录集,怎么办?也许想从存储过程中返回两个或三个值,但又不想费心创建一个记录集。在 这时,可以定义一个输出参数,其值由存储过程提供。 例如,对于更新书价的程序,如果想在更新之后找出最高价格,可将存储过程改成: 第 9章 连接、命令和过程计计281 下载
282 SP3高级编程 Chinapub.com 下载 IN BEGI UPDATE Titles Price Price *(1 +@Percent /100) WHERE Type=@Typ SELECt @Max MAx(Price) fRom Titles END 这只是在执行更新后运行了一个简单的 SELECT语句,并将值赋给输出参数 现在可以改写 StoredProcedure. asp的代码从而获取变量@MAx的值。 Dim cmdUpdate Dim strype urPercent Get the form values strType s Request Form("lstTypes' curPercent Request Form("txtPercent) Tell the user what's being done Response. Write Updating all books& Set the properties of the command with cmdUpdate ActiveConnection strcon CommandText ="usp_UpdatePricesMax' 我们只是在集合中加入了另一个参数,但这次指定为输出参数。注意它并没有赋值,因 为其值将由存储过程提供,记住这是一个输出参数 Add the parameters Parameters Append .CreateParameter ("@Type", adVarwchar, adParamInput Parameters Append. CreateParameter ("@Percent, adcurrency, aramInput ParametersAppend CreateParameter (*@Max, adcurrency, adParamoutput) adExecuteNoRecord 一旦执行了这个过程,就可从集合中取得该值 Extract the output parameter, which the stored procedure has supplied to the parameters collection curMax = Parameters(*@Max') End with And finally tell the user what's happened Response. Write Procedure complete. ' lngrecs records were updated. Response. Write "The highest price book is now.& Formatcurrency(curMax)
这只是在执行更新后运行了一个简单的 S E L E C T语句,并将值赋给输出参数。 现在可以改写S t o r e d P r o c e d u r e . a s p的代码从而获取变量@ M A X的值。 我们只是在集合中加入了另一个参数,但这次指定为输出参数。注意它并没有赋值,因 为其值将由存储过程提供,记住这是一个输出参数。 一旦执行了这个过程,就可从集合中取得该值。 282计计ASP 3 高级编程 下载