发布新日志

  • QTP参考资料收集(6)-2

    2009-03-31 20:03:08

    a)        检查点概述

    在录制会话过程中或在编辑测试或组件时添加检查点。在录制了初始测试或组件之后,通常可以更为方便地定义检查。有几种方法可以添加检查点。

    在录制或编辑时添加检查点

             使用插入菜单上的命令,或者单击测试工具栏上的插入检查点按钮旁边的箭头。这将显示与关键字视图的选定步骤相关的检查点选项的菜单。

    只在编辑时添加检查点

             右键单击关键字视图中您要添加检查点的步骤,然后选择插入标准检查点

             右键单击 Active Screen 中的任意对象,然后选择插入标准检查点。可使用该选项为 Active Screen 中的任意对象创建检查点(即使该对象不是关键字视图中任一步骤的组成部分)。

    注意:

    如果使用“Active Screen”方法,请确保 Active Screen 包含有关待检查对象的充足数据。

    了解检查点类型

    检查点类型

    描述

    用法示例

    标准检查点

    检查对象的属性值。

    检查是否选中某单选按钮。

    图像检查点

    检查图像的属性值。

    检查图像源文件是否正确。

    表检查点

    检查表中的信息。

    检查表单元格中的值是否正确。

    页面检查点

    检查网页的特性。

    检查加载网页所需的时间,或者检查网页是否包含中断链接。

    文本/文本区域检查点

    检查文本字符串是否显示在网页或应用程序窗口中的适当位置。

    检查预期的文本字符串是否显示在网页或对话框上的预期位置。

    位图检查点

    将网页或应用程序的某个区域捕获为位图后对其进行检查。

    检查网页或网页的任何部分是否能按预期显示。

    数据库检查点

    检查应用程序或网站所访问的数据库内容

    检查数据库查询中的值是否正确。

        可访问性检查点

    对网站区域进行识别,以检查是否符合 508 部分。

    检查网页上的图像是否包含 ALT 属性(该属性是 W3C Web 内容可访问性规则所要求的)。

    XML 检查点

    检查 XML 文档的数据内容。

    注意:XML 文件检查点用于检查特定的 XML 文件;XML 应用程序检查点用于检查网页中的 XML 文档。

    您可以插入下列检查点类型以检查网站或应用程序中的各种对象。

             “标准检查点检查应用程序或网页中对象的属性值。标准检查点会检查各种对象,如按钮、单选按钮、组合框、列表等等。例如,您可以检查在选择单选按钮之后它是否处于激活状态,或者可以检查编辑字段的值。标准检查点在所有加载项环境中都受到支持。

             “图像检查点检查应用程序或网页中的图像的值。例如,您可以检查所选图像的源文件是否正确。

    注意:可以通过在图像对象上插入标准检查点来创建图像检查点。图像检查点在 Web 环境中受到支持。

             “位图检查点检查位图格式的网页或应用程序区域。例如,假设您有一个网站,可以显示用户指定的城市的地图。该地图具有用于缩放的控制键。在单击放大地图的控制键后,您可以录制所显示的新地图。使用位图检查点,您可以检查该地图是否正确放大。位图检查点在所有加载项环境中都受到支持。

             “表检查点检查表内部的信息。例如,假设您的应用程序或网站包含一个表,该表列出了从纽约到旧金山的所有可用航班。您可以添加一个表检查点,以检查该表中的第一个航班的时间是否正确。

    注意:可以通过在表对象中插入标准检查点来创建表检查点。表检查点在 Web ActiveX 环境中受到支持。表检查点还在很多外部加载项环境中受到支持。

             “文本检查点检查文本字符串是否显示在应用程序或网页的适当位置中。例如,假设您的应用程序或网页显示句子:从纽约到旧金山的航班。您可以创建一个文本检查点,检查词语纽约是否显示在到旧金山的航班之间。文本检查点在所有加载项环境中受到支持(请参阅下面的受支持的检查点)。

             “文本区域检查点检查文本字符串是否按照指定的条件显示在 WindowsApplications 中所定义的区域内。例如,假设您的 Visual Basic 应用程序有一个按钮,显示查看文档< 号码>”,其中< 号码> 会被输入到应用程序中其他位置的窗体的四位数字代码替换。您可以创建一个文本区域检查点,以确认在该按钮上显示的号码与在窗体中输入的号码相同。文本区域检查点在标准 WindowsVisual Basic ActiveX 加载项环境中受到支持。文本区域检查点还在一些外部加载项环境中受到支持。

             “可访问性检查点确定可能不符合万维网联盟 (W3C) Web 内容可访问性规则的网站区域。例如, W3C Web 内容可访问性规则的规则 1.1 要求您为每个非文本元素提供等效文本。您可以添加“Alt”属性检查,检查按照该规则要求具有“Alt”属性的对象是否确实具有这样的标记。可访问性检查点在 Web 环境中受到支持。

             “页面检查点检查网页的特性。例如,您可以检查加载网页所需的时间,或者检查网页是否包含损坏的链接。

    注意:可以通过在页面对象上插入标准检查点来创建页面检查点。页面检查点在 Web 环境中受到支持。

             “数据库检查点检查由您的应用程序访问的数据库的内容。例如,您可以使用数据库检查点来检查网站上包含航班信息的数据库的内容。数据库检查点在所有环境中都受支持(请参阅下面的受支持的检查点)。

             “XML 检查点检查 XML 文件中的 XML 文档的数据内容,或检查网页和帧中的 XML 文档的数据内容。有关 XML 检查点的详细信息,请参阅第 11 检查 XML”XML 检查点(网页/ 帧)在 Web 环境中受到支持; XML 检查点(文件)在所有环境中受到支持(请参阅下面的受支持的检查点)。

  • QTP参考资料收集(6)-1

    2009-03-31 16:14:48

    QTP常用快捷方式

    下表这些快捷方式是我们经常用得到的,而其它的快捷方式记忆起来比较复杂,具体参见QTP的帮助文档:

    Command

    Shortcut Key

    Function

    Record (普通录制)

    F3

    Starts a recording session.

    Run (运行)

    F5

    Starts a run session from the beginning or from the line at which the session was paused.

    Stop (停止)

    F4

    Stops the recording or run session.

    Run from Step (丛当前步骤运行)

    Ctrl+F5

    Starts a run session from the selected step.

    Analog Recording (模拟录制)

    Shift+Alt+F3

    Starts recording in analog recording mode.

    Low Level Recording(低级录制)

    Ctrl+Shift+F3

    Starts recording in low level recording mode.

    Object Repository(打开对象库)

    Ctrl+R

    Opens the Object Repository dialog box.

    Step Into (单步调试运行到)

    F11

    Runs only the current line of the script. If the current line calls a method the method is displayed in the view but is not performed.

    Step Over (跳出断点)

    F10

    Runs only the current line of the script. When the current line calls a method the method is performed in its entirety but is not displayed in the view.

    Step Out (跳过断点)

    Shift+F11

    Runs to the end of the method then pauses the run session. (Available only after running a method using Step Into.)

    Run to Step (运行到)

    Ctrl+F10

    Runs until the current step.

    Add to Watch (添加到观察表)

    Ctrl+T

    Adds the selected item to the Watch tab.

    Insert/Remove Breakpoint (断点)

    F9

    Sets or clears a breakpoint in the test.

    Enable/Disable Breakpoint

    (启用/停用断点)

    Ctrl+F9

    Enables or disables a breakpoint in the test.

    Clear All Breakpoints

    (清除所有端点)

    Ctrl+Shift+F9

    Deletes all breakpoints in the test.

    Check Syntax (语法检查)

    Ctrl+7

    Checks the syntax of the active document.

     

  • QTP参考资料收集(5)

    2009-03-31 16:13:16

    5、QuickTest Plus小工具,大作用

    象我这样初学QTP的朋友刚开始时很可能没有注意到QuickTest Plus,因为QTP安装后默认是

    没有安装plus的,千回百转知道了plus,大概看了看,发现plus虽然都是些辅助性的小工具,但

    往往会给你的工作带来事半功倍的效果。

     

    一、安装QuickTest plus

     

      QTP安装后,在 程序 > QuickTest Professional下点击QuickTest Plus,然后按照提示一步步往下安装即可,

      其中要求输入序列号,输入和QTP安装时相同的序列号就可以了(8888-8888888888)。

     

    二、提示和技巧

     

      plus不仅提供了一些工具,还在它的帮助手册里给出了一些提示和技巧,以及一些实用的Function。

      在这里我把一些比较常用的好东东贴出来,其他的就看plus的帮助吧。

     

    1、创建action template.

        当希望在每一个新建action时都增加一些头部说明,比如作者、创建日期、说明等,用action template

        来实现最简单快捷。

        方法:用记事本等文本编辑器,输入如下类似的内容:

              'Company: xxxx

              'Author: xxx

              'Product: xxx

              'Date: xx

             然后将文件保存为ActionTemplate.mst,并存放到QTP安装目录下的dat目录,重启QTP,新建一个action试试,新建的action会包含以上信息。

     

    2、关于设置测试报告里只显示error的信息。

        帮助中说:修改安装目录下bin\QTReport.ini文件,增加以下内容:

             [FilterDialog]

             ReportAppDefaultFilter=1 # for error only

             ReportAppDefaultFilter=3 # shows all messages (default)

        但根据我的测试结果,不尽其然:

         1)当ReportAppDefaultFilter=1时,如果Object Repository中缺少对象,在报告中会在相应的

           action前打叉,但不会提示具体错误,而成功的步骤都有具体信息显示。

         2)用Reporter.ReportEvent测试的结果是:

            ReportAppDefaultFilter=1时,只显示micDone的具体信息;

            ReportAppDefaultFilter=2时,只显示micFail的具体信息;

            ReportAppDefaultFilter=3时,只显示micDone和micFail的具体信息;

            ReportAppDefaultFilter=4时,只显示micPass的具体信息;

     

        似乎无规律可寻,所以我的结论暂时是:不要设置这个参数,用默认的,显示所有信息,更多的信息有利于分析结果。

     

    3. 启动IE的语句:SystemUtil.Run "iexplore.exe", "http://www.mercuryinteractive.com"

    4. 关闭IE或其他程序的语句:SystemUtil.CloseProcessByName "app.exe"

         or  SystemUtil.CloseProcessByWndTitle "Some Title"

     

    三、Function Libraries

     

        plus的帮助中提供了一些常用的Function,把这些function copy到文本编辑器中保存为.vbs文件,并添加到Resources中就可以直接调用了,

      或直接copy到你的action中,就可以在当前的action中调用。更推荐第一种方法,所有的action都可以调用。

     

    1、文件操作相关的function,如下,望名则可生意:

        Function CreateFile(sFilename, bOverwrite);

        Function OpenFile(sFilename, iomode, create);

        Function AppendToFile(sFilename, sLine);

        Function WriteToFile(sFilename, sLine);

       

    2、Function NormalizeString(OrgStr); (将字符串变成regular express)

     

    3、GlobalDictionary的使用,这是另外一种可以共享全局变量的方法,在所有的action中,包括local和external action中都可以访问。

     

    4、使用文件系统相关的function:

        Function ReadLineFromFile (byref FileRef);

        Sub FileDelete ( FilePath);

        Function FileCompare (byref FilePath1, byref FilePath2, byref FilePathDiff, ignoreWhiteSpace);

        Function CheckFileExists (FilePath)

     

    5. web table相关的function:

        Function ItemByKeyColumn(): 根据table中某列的值,得到同一行中另一列的对象。(这个功能非常有用。)

        Function ObjectsByMicClass(Obj, micClass): 得到table中所有的micClass类型的对象集合。

     

     

    四、工具

      1、Automation Generator Utility

         添加一系列动作,然后自动完成。如:启动QTP,然后执行test1, test2, test3...,最后关闭QTP,还可以连接或断开Quality center.

         值得注意的是,每个test都可以分别指定test result文件,这样可以把所有test result指定到同一个目录下,所有test执行完成后,

         用Test Result Viewer就可以快速的查看测试报告。

     

      2、External Action Call Modifier Utility

         外部Action调用修改工具。当删除一个Reusable action前,如果没有先删除其他test中对它的调用,则打开其他test时,会提示找不到某某

         action,这种情况下启用该工具,工具会列出test下所有调用的外部action(如果调用的action是使用相对路径,则不会列出来),如果外部

         action找不到,会用红色的问号表示,删除它并保存后就OK了。

         也可以在此处修改外部action的来源,修改后原来的action parameter仍会保留。

      3、Repository Merge Utility

         合并多个对象库文件中的对象,如果出现冲突,可以选择忽略,或手工合并,或自动合并。

         对象库文件是Action目录下的Resource.mtr文件。

     

      4. Report Analyzer

         Test Result的另一个查看工具,提供了一些过滤条件,比如只查看failed step, 或只查看checkpoints,或只查看某个action。

     

    先就写这么多了,抛砖引玉,希望你能发现你想要的东西。写得不对的,不要客气,请指出来,不胜感激。

  • QTP参考资料收集(4)

    2009-03-31 16:11:46

    4、QTP连接数据库

    一、OLE-DB连接方式 

    1  字符串方式

    ConnectionString="Provider=SQLOLEDB.1; Data Source=YourSrc;

    UID=YourUid; PWD=YourPwd; Database=YourDB"

    ConnectionString="Provider=SQLOLEDB.1; Data Source=YourSrc;

    User ID=YourUid; Password=YourPwd; Initial Catalog=YourDB"

    其中,Provider为服务于连接的底层OLE-DB数据供应程序的名称;Data Source为服务于底层数据供应程序的数据源名称;UID或User ID为连接时使用的用户名;PWD或Password为连接时使用的密码;Database或Initial Catalog为位于数据库服务器上的一个特定数据库。

    2  数据链接文件方式

    创建一个空文本文件,将其扩展名改为.udl来创建一个数据链接文件。双击该文件打开Data Link Properties对话框,在Provider页选择提供者(不要选择基于ODBC的提供者,因为这样实际上是间接藉由ODBC实现数据库连接),在Connection页指定实现连接的细节。使用数据链接文件进行连接的ConnectionString如下:

    ConnectionString="File Name=C:YourFile.udl"

    用记事本打开数据链接文件,可以看到第三行文本是一个连接字符串,指定了连接的细节。如果在Connection页选中了“Allow saving password”,则在该文件中也会记录用户的密码信息。

    二、ODBC连接方式 

    使用ODBC连接方式,首先要配置ODBC数据源。ODBC数据源配置成功后,就可以相应指定下面介绍的连接字符串进行数据库连接。

    1  ODBC的系统DSN连接方式

    ConnectionString="DSN=SysDSNName;UID=YourUid;PWD=YourPwd;Database=YourDB"

    其中,DSN为系统DSN的名称,其它参数与3.1中介绍的参数相同。

    2  ODBC的文件DSN连接方式

    ConnectionString="FileDSN=FileDSNName;UID=YourUid;PWD=YourPwd;Database=YourDB"

    其中,FileDSN为文件DSN的名称,其它参数与3.1中介绍的参数相同。

    用记事本打开相应的.dsn文件(一般位于C:Program FilesCommon FilesODBCData Sources目录下),可以看到,类似于数据链接文件,该文件中也指定了连接的细节。

    3  ODBC的无DSN连接方式

    ConnectionString="Driver={SQL Server};Server=YourServer;

    UID=YourUid;PWD=YourPwd;Database=YourDB")

    此方式不用配置ODBC数据源。其中,Driver为ODBC驱动程序名称,Server为数据库服务器名称,其它参数与3.1中介绍的参数相同。

    4  数据链接文件方式

    首先,采用3.2中的方法创建数据链接文件。但进行文件配置时,在Provider页中选择基于ODBC的提供者——Microsoft OLE DB Provider for ODBC Drivers。此方式的ConnectionString与3.2中介绍的相同。

    三、实例

    下面是采用OLE-DB的字符串方式,连接到SQL Server2000数据库的示例代码:

    ConnectionString="Provider=SQLOLEDB.1; Data Source=YourSrc;

    UID=YourUid; PWD=YourPwd; Database=YourDB";初始化连接字符串

    Set Conn=Server.CreateObject("ADODB.Connection")  ;创建Connection对象

    Conn.Open  ConnectionString                       ;调用Open方法,建立连接

    …                                                ;进行数据存取操作

    Conn.Close                                        ;关闭连接

    Set Conn=Nothing                                  ;释放Connection对象

    需要注意的是,应尽可能晚的建立连接,同时又尽可能早的关闭连接,这样保证连接打开的时间最短,可以充分发挥OLE-DB的连接缓冲池的作用,节省连接资源。

    文章2:http://bbs.51testing.com/viewthread.php?tid=87825&highlight=oracle

  • QTP参考资料收集(3)

    2009-03-31 16:07:12

    3、QTP读取Excel数据的方法

     

    在构建自己的测试框架时,或者是从Excel读入外部数据进行检查时都要用到Excel的COM对象编程方法,下面脚本中的ReadFile函数就实现了这样的功能,首先创建Excel应用程序对象,然后打开Excel文件,把Excel数据读取到一个数组中。
     
    arrRange = ReadFile("D:\QTP\MyWork\ReadExcelFileTest1\ObjectTree.xls","Tree")
    'Msgbox UBound (arrRange,1)
    'Msgbox UBound (arrRange,2)
    ' 读取其中一个单元格的数据
    Msgbox arrRange(3,1)
     
     
    ' 输入:
    '             sFileName: Excel文件
    '             sSheetName:表单名称
    ' 返回:
    '             包含Excel数据的数组
    Function ReadFile(sFileName,sSheetName)
           Dim oExcel
           Dim oSheet
           Dim oRange
           Dim arrRange
     
           On Error Resume Next
               ' 创建Excel应用程序对象
                  Set Excel = CreateObject("Excel.Application")
                  If err.Number <> 0 Then
                         MsgBox "未能初始化Excel" & vbCrLf & _
                                     "请确保Excel已安装", vbCritical
                         Exit Function
                  End If
           On Error Goto 0
                        
           On Error Resume Next
                         ' 打开Excel文件
                         oExcel.Workbooks.Open(sFileName)
                      If err.Number <> 0 Then
                                MsgBox "未能加载Excel文件" & vbCrLf & _
                                       "请确保Excel文件路径正确或格式正确", vbCritical
                                Exit Function
                         End If
           On Error Goto 0
          
           ' 获取表格的使用范围
           Set Sheet = oExcel.Worksheets(sSheetName).UsedRange
           ' 获取从A列到Z列,从第1行到第1000行的范围i中的所有值
           Set Range = oSheet.Range("A1:Z1000")
           '把Excel数据转换到数组
           arrRange = oRange.Value
           ' 关闭工作簿
           oExcel.WorkBooks.Item(1).Close
           ' 退出Excel
           oExcel.Quit
           Set Excel = Nothing
        ' 返回包含Excel数据的数组
         ReadFile = arrRange
    End Function

  • QTP参考资料收集(2)

    2009-03-31 16:03:03

    2、TD与QTP连接

    1 、安装 TD,检验 TD 是否安装成功,启动 TD Server 服务器后,在与 Server 相连的其他计算机上,打开 IE 浏览器,在地址栏输入 http://TD Server 的 ip 地址 /TDbin/start_a.htm 如果能够浏览到 TD 界面 , 说明安装成功。51Testing软件测试网 @*mY5a‑kuY x
    51Testing软件测试网 k| q L#SC?J.fM
    2、安装 QTP,验证 QTP 安装成功,进入 windows 操作系统,点击,开始 -> 程序 ->Quick Test Professional-> Quick Test Professional ,打开 QTP 使用界面,进行简单的录制,保证脚本录制成功,并且可以回放,与你的预操作达到的结果一致,证明 QTP 安装成功。
    ­sx*b"Kb)t0
    S#w7ivS03、安装插件,进入 TD 首页,点击见面上的 TD Add In,进入 TD Add In 界面点击 More TestDirector Add Ins 进入 More TestDirector Add Ins 界面,下载名为 TDplugInsSetup 的插件,大约 35 兆并且在 Server 与 QTP 客户机上安装这个插件,安装成功后,会要求你重启电脑,重启后会看到,开始-程序中有个新安装的程序 “Quick Test Professinal add in for Quality Center” ,登入 TD 进入 test plan 检测是否可以在 test plan 中添加 QTP 类型的测试用例,点击后 , 出现QUICKTEST.TEST , 并且可以建立 QTP 的测试用例。
    m$y d‑w1r'd7R0
    ‑v^1AO zd(g+W04、检查没有问题之后 , 还需要在安装 QTP 的机子上做一些相应的设定,进入 QTP 主界面 , 点击文件栏的 Tools-Options , 进入 Options 对话框 在 Run Tab 中选择 Allow other Mercury products to run test and components , 以及 Submit a defect to Qualiyt Center for each failed step 选中后 , 点击 ok 保存这个设置,在 QTP 主界面中点击 Tool - Quality Center Connection,在 Server 中输入 http:// TDServer ip 地址 /TDbin( 本例中使用 htt......) , 点击 connect 按钮 , QTP 连接到服务器上 , 如果服务器连接有问题 , 则会提示连接失败。
    5a?*`R6j,q0
    U"t,v3y"M05、在 project connection 中包含一下几项:
    h JN]"|0   Domain : TD 服务器站点管理中建立项目的域51Testing软件测试网fq S"F t-L G O.n
       Project :域中你所建立的项目
    cL ?_R­j Y(pk0   User :登陆项目所用的用户名51Testing软件测试网 n8Xd.B8JO^+\‑z5G
       Password :相应用户名使用的密码51Testing软件测试网G v5k?'@F N
       Reconnect on startup 在下次启动 QTP 时自动登陆到你的项目中 51Testing软件测试网+Jv[1]c%Zt NZ
       Save password for reconnection on startup 为下次登陆保存密码51Testing软件测试网 B}}y'[ L
    完成了上述操作就 TD 和 QTP 就连接起来 , 可以从 TD 调用 QTP 脚本了

     

  • QTP参考资料收集(1)

    2009-03-31 15:46:36

    QTP的Action间的信息共享的4种方法

    通过Action参数来传递数据

    Action2的脚本如下:

    ' Input Parameters
    Message = Parameter("Msg")
    Msgbox Message
    ' Output Parameters
    If NOT Message = "" Then
           Parameter("ReturnMsg") = "The Message is " & Message
    Else
           Parameter("ReturnMsg") = "The Message is Empty!"
    End If
     
    ' RetuenValue
    ExitAction "HAHAHAHHAHA!!!!!"
    'ExitAction Parameter("ReturnMsg")
     
     
    3种调用Action的方法,Action1的脚本如下:
    ' 调用Action2,输入参数为 “ Hello!”,把输出参数值写到ReturnMessage1变量
    RunAction "Action2", oneIteration,"Hello!" ,ReturnMessage1
    Msgbox ReturnMessage1
     
    ' 调用Action2,输入参数为 “ Hello!”,通过Parameter方法读取输出参数值
    RunAction "Action2", oneIteration,"Hello!"
    ReturnMessage2= Parameter("Action2","ReturnMsg")
    Msgbox ReturnMessage2
     
    ' 如果被调用的Action使用了ExitAction来退出Action并返回ReturnValue,则可以使用下面的方式来获取Return Value的值
    ' 注意OutPut Parameters与Return Value的区别
    ReturnMessage3 = RunAction( "Action2", oneIteration ,"Hello!")
    Msgbox ReturnMessage3
     
     通过全局数据表(Global Data Table)来共享数据
     
    在Action1中设置参数值,Action1的脚本如下:
    ' 获取全局数据表
    Set Sheet = DataTable.GetSheet("Global")
    ' 查找参数列
    Set Parameter1 = Sheet.GetParameter("Column1")
    Set Parameter2 = Sheet.GetParameter("Column2")
    ' 设置参数值
    Parameter1.Value="Hello"
    Parameter2.Value="World!"
    ' 调用Action2,Action2将使用前面设置的参数值
    RunAction "Action2", oneIteration
    在Action2中读取参数值,Action2的脚本如下:
    ' 获取全局数据表
    Set Sheet = DataTable.GetSheet("Global")
    ' 读取参数值
    Set Parameter1 = Sheet.GetParameter("Column1")
    Set Parameter2 = Sheet.GetParameter("Column2")
    ' 使用参数值
    Msgbox Parameter1 &" " & Parameter2

    QTP的Action间的信息共享的4种方

    通过Action参数来传递数据

    Action2的脚本如下:

    ' Input Parameters
    Message = Parameter("Msg")
    Msgbox Message
    ' Output Parameters
    If NOT Message = "" Then
           Parameter("ReturnMsg") = "The Message is " & Message
    Else
           Parameter("ReturnMsg") = "The Message is Empty!"
    End If
     
    ' RetuenValue
    ExitAction "HAHAHAHHAHA!!!!!"
    'ExitAction Parameter("ReturnMsg")
     
     
    3种调用Action的方法,Action1的脚本如下:
    ' 调用Action2,输入参数为 “ Hello!”,把输出参数值写到ReturnMessage1变量
    RunAction "Action2", oneIteration,"Hello!" ,ReturnMessage1
    Msgbox ReturnMessage1
     
    ' 调用Action2,输入参数为 “ Hello!”,通过Parameter方法读取输出参数值
    RunAction "Action2", oneIteration,"Hello!"
    ReturnMessage2= Parameter("Action2","ReturnMsg")
    Msgbox ReturnMessage2
     
    ' 如果被调用的Action使用了ExitAction来退出Action并返回ReturnValue,则可以使用下面的方式来获取Return Value的值
    ' 注意OutPut Parameters与Return Value的区别
    ReturnMessage3 = RunAction( "Action2", oneIteration ,"Hello!")
    Msgbox ReturnMessage3
     
     通过全局数据表(Global Data Table)来共享数据
     
    在Action1中设置参数值,Action1的脚本如下:
    ' 获取全局数据表
    Set Sheet = DataTable.GetSheet("Global")
    ' 查找参数列
    Set Parameter1 = Sheet.GetParameter("Column1")
    Set Parameter2 = Sheet.GetParameter("Column2")
    ' 设置参数值
    Parameter1.Value="Hello"
    Parameter2.Value="World!"
    ' 调用Action2,Action2将使用前面设置的参数值
    RunAction "Action2", oneIteration
    在Action2中读取参数值,Action2的脚本如下:
    ' 获取全局数据表
    Set Sheet = DataTable.GetSheet("Global")
    ' 读取参数值
    Set Parameter1 = Sheet.GetParameter("Column1")
    Set Parameter2 = Sheet.GetParameter("Column2")
    ' 使用参数值
    Msgbox Parameter1 &" " & Parameter2

  • (转)组合查询之核心:拼接字符串

    2009-03-30 18:59:05

    '组合查询之核心:拼接字符串
      '功能:定义查询条件,定义返回集,定义排序方式
      '平台:Windows 2000 Server + IIS5.0 + SQL Server 2000
      '语言:VBScript.
      '作者:Cheery_Ke
      '***********Start************
      '**************读取变量*************
      .
      .
      .
      seaLastUpdTime = Request("seaLastUpdTime1")&"-"&Request("seaLastUpdTime2")&"-"&Request("seaLastUpdTime3")
       
      returnItem = Request("ReturnItem")'******个人设定要返回的字段
       
      'Response.Write returnItem
       
      '***********拼接字符串***************************
       
      If returnItem <> "" Then
       
      SQL = "Select ComID,ComName, " & returnItem & " From ClientInfo Where ISInva = 0"
       
      Else
       
      SQL = "Select ComID,ComName From ClientInfo where IsInva = 0"
       
      End If
       
      If seaComName <> "" Then
       
       SQL = SQL & " And ComName Like '%"&seaComName&"%'"
       
      End If
       
      If seanexus1 <> "" Then
       
       SQL = SQL & " And nexus like '%"&seanexus1&"%'"
       
      End If
       
      If seanexus2 <> "" Then
       
       SQL = SQL & " And nexus like '%"&seanexus2&"%'"
       
      End If
       
      If seaComType <> "" Then
       
       SQL = SQL & " And ComType = '"&seaComType&"'"
       
      End If
       
      If seaComProv <> "" Then
       
       SQL = SQL & " And ComProv = '"&seaComProv&"'"
       
      End If
       
      If seaTimeFrist11 <> "" Then
       
       seaTimeFrist1 = seaTimeFrist11&"-"&seaTimeFrist12&"-"&seaTimeFrist13
       
       SQL = SQL & " And TimeFrist > '"&seaTimeFrist1&"'"
       
      End If
       
      If Request(seaTimeFrist1) <> "" Then
       
       seaTimeFrist1 = Request(seaTimeFrist1)
       
       SQL = SQL & " And TimeFrist > '"&seaTimeFrist1&"'"
       
      End If
       
      If seaTimeFrist21 <> "" Then
       
       seaTimeFrist2 = seaTimeFrist21&"-"&seaTimeFrist22&"-"&seaTimeFrist23
       
       SQL = SQL & " And TimeFrist < '"&seaTimeFrist2&"'"
       
      End If
       
      If Request(seaTimeFrist2) <> "" Then
       
       seaTimeFrist2 = Request(seaTimeFrist2)
       
       SQL = SQL & " And TimeFrist < '"&seaTimeFrist2&"'"
       
      End If
       
      If seaNearTime11 <> "" Then
       
       seaNearTime1 = seaNearTime11&"-"&seaNearTime12&"-"&seaNearTime13
       
       SQL = SQL & " And TimeNear > '"&seaNearTime1&"'"
       
      End If
       
      If Request(seaNearTime1) <> "" Then
       
       seaNearTime1 = Request(seaNearTime1)
       
       SQL = SQL & " And TimeNear > '"&seaNearTime1&"'"
       
      End If
       
      If seaNearTime21 <> "" Then
       
       seaNearTime2 = seaNearTime21&"-"&seaNearTime22&"-"&seaNearTime23
       
       SQL = SQL & " And TimeNear < '"&seaNearTime2&"'"
       
      End If
       
      If Request(seaNearTime2) <> "" Then
       
       seaNearTime2 = Request(seaNearTime2)
       
       SQL = SQL & " And TimeNear < '"&seaNearTime2&"'"
       
      End If
       
      If seaAppTime11 <> "" Then
       
       seaAppTime1 = seaAppTime11&"-"&seaAppTime12&"-"&seaAppTime13
       
       SQL = SQL & " And AppTime > '"&seaAppTime1&"'"
       
      End If
       
      If Request(seaAppTime1) <> "" Then
       
       seaAppTime1 = Request(seaAppTime1)
       
       SQL = SQL & " And AppTime > '"&seaAppTime1&"'"
       
      End If
       
      If seaAppTime21 <> "" Then
       
       seaAppTime2 = seaAppTime21&"-"&seaAppTime22&"-"&seaAppTime23
       
       SQL = SQL & " And AppTime < '"&seaAppTime2&"'"
       
      End If
       
      If Request(seaAppTime2) <> "" Then
       
       seaAppTime2 = Request(seaAppTime2)
       
       SQL = SQL & " And AppTime < '"&seaAppTime2&"'"
       
      End If
       
      If Request("seaLastUpdTime1") <> "" Then
       
      // seaLastUpdTime0 = seaLastUpdTime1&"-"&seaLastUpdTime2&"-"&seaLastUpdTime3
       
       SQL = SQL & " And LastUpdTime > '"&seaLastUpdTime&"'"
       
      End If
       
      If Request(seaLastUpdTime1) <> "" Then
       
       //seaLastUpdTime0 = Request(seaLastUpdTime0)
       
       SQL = SQL & " And LastUpdTime > '"&seaLastUpdTime&"'"
       
      End If
       
      If Session("Pop") = "1" Then
       
       AdminName = Session("UserName")
       
      SQL = SQL & " And (OurSales Like '%"&AdminName&"%' Or nexus Like '%w%') Order By " & Order
       
      Else
       
      Response.Write SQL
       
      SQL = SQL & " Order By "& Order 'Order设定排序方式
       
      End If
       
      'Response.Write SQL
  • (转)OLEDB的连接字符串

    2009-03-30 18:56:17

    有许多种办法可以连上一个数据库. 你可以用System DSN, DSN-less连接或是本地的OLEDB provider. OLEDB? 这是什么什么玩艺儿? 也许你们中的许多人以前没有听说过. 要回答这个问题,我们先得回顾一下数据库连接的历史.

    早期的数据库连接是非常困难的. 每个数据库的格式都不一样,开发者得对他们所开发的每种数据库的底层API有深刻的了解. 因此,能处理各种各样数据库的通用的API就应运而生了. 也就是现在的ODBC(Open Database Connectivity), ODBC是人们在创建通用API的早期产物. 有许多种数据库遵从了这种标准,被称为ODBC兼容的数据库.
    ODBC兼容的数据库包括Access, MS-SQL Server, Oracle, Informix等.

    但ODBC并不是完美无缺的,它仍然含有大量的低级的调用,开发ODBC应用程序仍较困难. 开发者不得不将大量的精力花在底层的数据库通信中,而不能专注于他们所要处理的数据. 后来微软提出了一个解决方案: DAO(Data Access Objects). DAO的代码看起来象这样:

    objItem.AddNew
    objItem.Name = "Chair"
    objItem.Price = 10
    objItem.Update

    你也许看过DAO的代码. 后来DAO演变为RDO(Remote Data Objects, 为分布式数据库体系设计), 再后来是ADO. 尽管它们都有各自的不足之处. 根据微软的说法,"ODBC提供了本地SQL数据的存取,DAO提供了高级的数据对象". DAO和RDO都需要数据以SQL(Structured Query Language)的格式存储. 针对这些缺陷,微软提出了OLEDB,一个基于COM的数据存储对象,能提供对所有类型的数据的操作,甚至能在离线的情况下存取数据(比方说,你使用的是你的便携机,你可以毫不费力地看到最后一次数据同步时的数据映像).

    OLEDB位于ODBC层与应用程序之间. 在你的ASP页面里,ADO是位于OLEDB之上的"应用程序". 你的ADO调用先被送到OLEDB,然后再交由ODBC处理. 你可以直接连接到OLEDB层,如果你这么做了,你将看到服务器端游标(recordset的缺省的游标,也是最常用的游标)性能的提升. 那我们该如何直接连接到OLEDB呢?

    要想直接连到OLEDB层,你必须改变你的connection对象连接字符串. 先用老办法创建一个connectiong对象:

    Dim objConn
    Set bjConn = Server.CreateObject("ADODB.Connection"

    接下去,我们不用常规的类似DSN=pubs or DRIVER={MS SQL-
    Server};UID=sa;PWD=;DATABASE=pubs;SERVER=myMachine的连接字符串,而采用下面的连接字符串:

    objConn.ConnectionString = "Provider=ProviderName; Data
    Source=DatabaseSource; Initial Catalog=DatabaseName; User ID=UserID;
    Password=Password"

    对于SQL:
    ProviderName = SQLOLEDB
    Data Source = Server Name
    Initial Catalog = Database Name

    对于Access:
    ProviderName = Microsoft.Jet.OLEDB.3.51
    Data Source = Full path to .MDB file

    下面让我们来看两个例子,一个是针对Access的,还有一个是针对SQL的. 如果你的连接SQL的DSN-less连接串是这样的:

    DRIVER={MS SQL-Server};UID=sa;PWD=;DATABASE=pubs;SERVER=myMachine

    那么直接连接到OLEDB的连接字符串应该是这样的:

    Provider=SQLOLEDB; Data Source=myMachine; Initial Catalog=pubs; User
    ID=sa; Password=

    让我们来看看Access,如果你的Access的连接字符串是:

    DRIVER={Microsoft Access Driver (*.mdb)};
    DBQ=c:\inetpub\wwwroot\users.mdb

    那么直接连接到OLEDB的连接字符串应该是这样的:

    Provider=Microsoft.Jet.OLEDB.3.51; Data
    Source=c:\inetpub\wwwroot\users.mdb

    就是这么简单,挺棒的吧?

    这很重要吗?
    现在你也许对为什么要学习这种新的数据库连接方法感到有些儿迷惑,为什么不走标准的DSN-less/System DSN路子呢? 让我来告诉你为什么. 据Wrox出的ADO 2.0
    Programmer's Reference一书中的测试,用OLEDB连接而不是DSN或DSN-less的连接会得到的性能提升如下:

    性能比较
    SQL Access
     OLEDB DSN OLEDB DSN
    Connection Times: 18 82 Connection Times: 62 99
    Iterating through 1,000 Records Times: 2900 5400 Iterating through
    1,000 Records Times: 100 950


    我希望这篇文章能对你有点儿帮助,我相信你会对你的连接SQL及Access数据库的方法做一些小小的改进的.

  • (转)WebComputing━ADO总结报告

    2009-03-30 18:52:54

    在当今提出的多种动态网页(Dhtml)解决方案中都强调了与数据库的连接,其实网页接挂后台数据库也是当前的热门应用,在电子商务等领域有着广泛的应用.MicroSoft为了适应其发展推出了新的ADO(Active Data Object)模型,通过ODBC的连接可以对当前流行的桌面数据库系统提供方便,快洁的连接.在这里,我想通过ADO在ASP技术中的应用来总结一下ADO对象以及其各自的属性和方法.51Testing软件测试网 A@2[.f6J s
    一、ADO对象模型:
    z2_ PWnnPb138711下面简单介绍一下ADO的对象模型
    2t7}'J!V&pda@s g138711ADO有三大对象,即Connection对象,Command对象,RecordSet对象.51Testing软件测试网%M+_g\7J,{
    Connection(对象)
    +Lm8p$N Tf V8{5N138711─Errors(集合)─Error(对象)51Testing软件测试网'lM.T2CN
    Command(对象)
    ?#Ql&_+ns138711─Parameters(集合)─Parameter(对象)51Testing软件测试网 W)[M T7HR;fM1w Ro,y
    RecordSet(对象)
    v){ ^2R,]W138711─Fields(集合)─Field(对象)
    51Testing软件测试网;L V[&s)?Lfv$x51Testing软件测试网k3o B*d(l Wo X}#v

      其中Connection对象,Command对象,RecordSet对象和Field对象又分别具有Properities集合而产生Properity对象.我们在asp编程中已经对这几个对象有了足够的了解.下面是以上三大对象的相互关系.
    _^rVS138711Command.ActiveConnection-$#@62;Connection51Testing软件测试网i_:p5\tt
    RecordSet.ActiveConnection-$#@62;Connection
    \$k'zP$s B+Qkb138711Connection.Execute-$#@62;RecordSet
    *f f*G`7^'aI138711Command.Execute-$#@62;RecordSet
    JZ U"IC138711RecordSet.Source-$#@62;Command51Testing软件测试网G!RX%G6SD'Jm,r
    好了,有了以上的关系表后,你应该能理解有一些等价的表达形式了.51Testing软件测试网(XQZ@)og.Lsn
    形式151Testing软件测试网O5?}3v|#K
    set rs = Server.CreateObject("ADODB.RecordSet")
    ,?5ePdD^138711strConn = "driver={SQL Server};server=srv;"& _
    i V5x;S"o$n138711"uid=sa;pwd=;database=pubs"51Testing软件测试网h'p7yyGt)f@8b
    strSQL = "Select * From Employee ;"51Testing软件测试网L-KpsB8e/`
    rs.open strSQL,strConn,,,adCmdText
    A,y P:p6afy k P'N138711形式251Testing软件测试网*k}'X7i%G9J o
    set conn = Server.CreateObject("ADODB.Connection")
    ~|aMua138711strConn ="driver={SQL Server};server=srv;"& _
    B!jJ{M#A I7zb138711"uid=sa;pwd=;database=pubs"
    5YT`4R-R7\l138711conn.open strConn
    'l@9^ MZ W OU p138711set rs = Server.CreateObject("ADODB.RecordSet")51Testing软件测试网3?4xvo[/m3AV&s
    rs.ActiveConnection=conn(注意此句)51Testing软件测试网OX+EN(A
    strSQL = "Select * From Employee ;"51Testing软件测试网 y WP[mUE
    rs.open strSQL,,,,adCmdText
    ,M0D wQaa`0L138711"上面这句也可以写成rs.open strSQL,conn,,,adCmdText
    ;B*M YIrg6yi*f8m'}:v138711形式351Testing软件测试网3v1wg9sR(v
    set conn = Server.CrreateObject("ADODB.Connection")
    kzSo&L'Zvd138711set rs = Server.CreateObject("ADODB.RecordSet")
    Y/Z*H/I3rU0AG&U&eM%v138711strConn ="driver={SQL Server};server=srv;"& _
    2bS4c(t-t:c.q138711"uid=sa;pwd=;database=pubs"51Testing软件测试网,TT1{;oXt w x$k
    conn.open strConn
    $BL4c @\b7\138711strSQL = "Select * From Employee ;"
    v i?i^ c138711rs=conn.Execu strSQL(注意次句)
    v|"Q;L$DK:i:A138711形式451Testing软件测试网cSLqW Cq
    set rs = Server.CreateObject("ADODB.RecordSet")
    @F]N7^v)N+uAz138711strConn ="driver={SQL Server};server=srv;"& _
    0DILUm_138711"uid=sa;pwd=;database=pubs"51Testing软件测试网3T*^_tr rB
    strSQL = "Select * From Employee ;"
    +t)UR^8M.J-N4o138711rs.open strSQL,strConn,,,adCmdText

    Kcc$sF%l$E138711

    r9LoR-l m3{ eq138711注:上面的例子中均假设SQL Server的name=srv,使用SQL Server Authentication采用了默认的帐号sa,该帐号没有设定密码。

    t4l)J o2t138711

    -eOg&|d:k138711  上面这几种形式都能够产生一个相同的RecordSet对象的实例rs,但方法各异,在后面的讨论中我们将看到它们不同的优越性.

    :Pv'io R3yC:T138711

    ?h5[5F)G9P0n138711二、Connection对象:
    'g rl k"@P2LymLO"N138711
      在ADO的模型中,Connection对象是最基本的对象,他主要是提供与数据库的连接。其他的两个对象都是通过它与数据库的连接来完成操作的。它的属性、方法如下所示。
    8KxN5c^\138711Connection对象的主要属性
    Y4kprEZ#GOBrt138711  1、 CursorLocation,它的取值有两个,一个是adUseClient,一个是adUseServer(默认),从其英语本身的含义就可以看出,前者是使用客户端的游标,而后者是使用服务器端的游标。二着的差别在于adUseClient游标可以提供供应商所没有提供的额外的属性,因而灵活性更大。需要注意的是Connection对象与RecordSet对象均有此属性,由Connection对象产生的RecordSet对象会自动的继承这个属性。另外要让此属性对Connection和RecordSet对象的实例起作用的话,必须在打开它们之前先定义。
    Z&w i(hAu[138711
    Eu9L(ES'OA138711下面看一个例子51Testing软件测试网`u8V{6O
    Set conn=Server.CreateObject("ADODB.Connection")51Testing软件测试网 w#J&|e^#aE-hz
    conn.CursorLocation=adUseClient
    0y-p-J-]:Um$RN&u138711strConn ="driver={SQL Server};server=srv;"& _51Testing软件测试网F(H U8a"x#YG
    "uid=sa;pwd=;database=pubs"51Testing软件测试网_8eXb D;F
    conn.open strConn
    .q2Xw%fGB8tgl h+a138711set rs= Server.CreateObject("ADODB.RecordSet")
    [t@,^,_N5I%B ~138711rs.open "emloyee",conn,,,adCmdTable
    M [F1wq138711采用次种方式则conn与rs的游标均为adUseClient了。51Testing软件测试网zYI|AR+_9W j
      2、 ConnectionString,在打开一个Connection实例之前设定数据库的连接信息。在上面的例子中我们使用了一条语句conn.open strConn,其中的strConn就是ConnectionString,因此我们可以重写上面的语句如下:51Testing软件测试网;Ga$Z:Hb#L~)R T mV
    Conn.ConnectionString=strConn
    %Ed$EA |&^138711Conn.open51Testing软件测试网#g @1WEn8|-mM
      3、 ConnectionTimeOut,设置连接超时。51Testing软件测试网 T#j.gf"{7dy0I
      4、 CommandTimeOut,设置命令执行超时。
    xw2v3I}.@ F d+U/?138711
    Connection的主要方法
    q4yM c0p%nHB138711
      1、 open,打开一个Connection的对象实例,常用的写法为conn.open ConnectionString,如果在打开之前已经定义了ConnectionString属性的话,就可以直接的打开。51Testing软件测试网:Y a @V NzJ"^"r[E{,]
      2、 Execute,产生一个RecordSet实例,常用的写法为51Testing软件测试网w.O\9]r"G
    Rs=conn.Excute CommandText,RecordsAffected,Option51Testing软件测试网7m FN!?U+w-ny!yD7A
    其中的CommandText可以为以下的几种形式,主要由Option的值来决定1) SQL语句,此时Option的值为adCmdText,表示将执行一段SQL语句。2)数据库的一个表名,此时Option的值为adCmdTable,表示将对该表进行操作。51Testing软件测试网5dHA1y.P?y
      3、一个StoredProcedure名字,此时Option取值为adCmdStoredProc,它表示将要执行一个SQL上定义的存储过程。这是一个非常灵活而强大的方法,它可以对用户隐藏数据库的具体信息,而只需用户提供适当的参数就可以了,还能返还需要的参数值。在后面介绍Command对象时再做详细的介绍。值得注意的是,有时Excute后并不需要返回一个RecordSet对象,例如在表中删除记录。看下面的例子:51Testing软件测试网D3nVG*Fv4v:Oa9X1g
    set conn= Server.CreateObject("ADODB.Connection")
    0jk)SA/K2EC[A4n.x138711conn.ConnectionString="driver={SQL Server};server=srv;"& _51Testing软件测试网Y xuwx
    "uid=sa;pwd=;database=pubs"
    6J/I FPz4G0Z138711conn.open51Testing软件测试网p-u&^_4z
    conn.Execute "Delect From Employee Where Job_ID=1;",,adCmdText
    1e[)R8I!|PzGz3f138711  该例子删除Employee表中Job_ID为1的记录,并不需要再返回一个RecordSet的实例,但如果将最后一句变为rs= conn.Execute "Delect From Employee Where Job_ID=1;",,adCmdText那么我们就可以用此rs来指向表中的记录条了。返回的rs和后面RecordSet对象中用Source属性产生的rs是相同的。

    m:r6]A6b138711
    Connection对象的集合
    (M8|:V'CU)yxH138711
    1、 Errors集合,对应产生Error对象。我们将在后面做单独的讨论。51Testing软件测试网#dT%Ywd sir
    2、 Properties集合,对应产生Property对象,下面给出一段代码,它包含了Property对象的主要方法和属性。

    tw_OM8RH7n138711

    /bEFL-f13871151Testing软件测试网7]9O2Er-H1Qr,GB

    \9Z*?(B^138711$#@60;%51Testing软件测试网P2j$fM6g:ZR*\)h1y!O:E
    "this program is testing the ADO"s Property object
    "^mI,Jv*Yk+S138711Const adCmdTable = &H000251Testing软件测试网 b(?A.Y1|p4H
    set conn=Server.CreateObject("ADODB.Connection")51Testing软件测试网&P q*_*@`G8_t?
    set rs=Server.CreateObject("ADODB.RecordSet")51Testing软件测试网YF%GS`&tv(s
    conn.ConnectionString="Driver={Microsoft Access Driver (*.mdb)};DBQ="& _
    5Y(z-B m%GYo P hn138711Server.Mappath("/source_asp")&"/property/employee.mdb;"
    dR6B1`0UP ZZ138711conn.open
    L%ID8?J138711rs.ActiveConnection=conn
    (kz zR\k:ue(hC138711rs.open "employee",,,adCmdTable51Testing软件测试网meVa wj
    dim i,j
    1{+^o `n [/W6C138711for i=0 to rs.fields.count-1
    lX5^ D`6V138711Response.Write rs.fields(i).name&"$#@60;br$#@62;"
    S!R6q/TZ p138711next51Testing软件测试网i)bfs ynn0i
    for j=0 to rs.properties.count-1
    {J x Nu _"J q138711Response.write rs.properties(j).name&"$#@60;br$#@62;"
    [EP:i7a.gl r138711next
    YH ag%zt3X2z138711rs.close
    1M$~#~arV0v!m,y o138711conn.close51Testing软件测试网,s\8^IOL)@T
    %$#@62;51Testing软件测试网tM(Hj%^;\

    4I1d'y+|+]'E S138711三、Error对象:51Testing软件测试网'WL-J!I%M c f3nG
      前面讲到了Connection对象是用于与各类的数据库进行挂接的,但在此过程中将会出现一些不可预测的错误,因而有了Error这个对象。首先要清楚一个概念,Error对象是在连接数据库时产生的,而并非那些运行时的实时错误。也就是我们常用 On Error Resume Next来忽略到的错误。这些错误将在Err对象中,我们可以用一个统一的模板来集中处理,我会在后面给出一个实例。下面还是先来看Error对象的属性和方法:
    :j'\8pav3_138711  1、 Count属性:用来统计Errors集合的数目,它的特点与前面讲到的Property对象的Count对象相同。
    /zDS0^x{n]"m j$u138711  2、 Clear方法:写法为Error.Clear,是用来清除Errors集合中的原有对象的,在统计新的Error对象时应该先使用此语句。
    QG9q5Up"m{[.M138711  3、 Item方法:用来指定特定的一个错误,语法为Error.Item(number),其中number为一数字。由于Item为默认的方法,所以Error(number)的写法与前面的写法是等价的。下面是一段程序。用来列举Error的所有对象。
    *vd:G lN'R?U;V138711$#@60;%51Testing软件测试网_.L1\oNsH|3[
    "this program is testing the ADO"s Error object51Testing软件测试网DbfY7~ m
    Dim i
    ]M0e&fB7I$c8L138711Set conn=Server.CreateObject("ADODB.Connection")51Testing软件测试网"a f#rC\8H5_
    conn.ConnectionString="Driver={Microsoft Access Driver (*.mdb)};DBQ=" _51Testing软件测试网;]7bJLf;e6F Im
    &Server.Mappath("/source_asp")&"/property/employee.mdb;"51Testing软件测试网([1w{ Z X[/C`"rW;R
    conn.open51Testing软件测试网8T+Q"H3z5~*V
    if conn.errors.count$#@62;0 then
    ?Oe%{~9r&\138711response.write "connection to database cause problem!"&"$#@60;br$#@62;"51Testing软件测试网]2W:tEXk}/p
    for i =0 to conn.errors.count-1
    %L7UI;AVM138711response.write conn.errors.item(i)&"$#@60;br$#@62;"
    %\5Q B3NkK138711next
    &R1T Ole_P138711else51Testing软件测试网x0S%^/ac\4E}
    response.write "connection to database successfully!"51Testing软件测试网CoH+f;Tt5h-P,^)n9F
    end if51Testing软件测试网0JRoZ#zIs
    conn.close51Testing软件测试网,T5];~!{d/X
    %$#@62;51Testing软件测试网Z `*RJJOq6c
      对于Err对象的通用模板处理程序我将在讨论RecordSet对象时给出。
    r3k/VG&k+J k"Z138711  下面我们将讨论ADO的第二个大的对象━Command对象,我的一个做网站的朋友告诉我他在平时使用ASP挂接数据库时很少使用Command对象,原因是Command对象不好使用,而喜欢用RecordSet对象。是的,可以这么说Command对象是整个ADO模型中最难掌握的一个,但也是功能和性能最好的一个。特别是它的StoredProcedue,它将处理的过程大部分都使用了在SQL Server上已经编译和优化了的存储过程,用过SQL Server的朋友都会明白的。下面就让我们来看Command对象

    )@tVm^ x9tk138711

    X \~},kh]138711四、Command对象:
    '{_*m2I@138711
      从英语字面的意思就可以看出,Command是用来做命令执行和参数传递的。而Command对象的批量参数传递,StoredProcude执行等等灵活而强大的功能也是它受到青睐的原因。Command对象主要是向SQL语句、StoredProcude传递参数,依靠SQL Server的强大功能来完成数据库的操作;而RecordSet对象可以说是微软从新封装了数据对象,并提供了一系列的方法和属性来简化数据库的编程。我们看下面的一个例子,它用了两种不同的方法实现了向数据库中增加一新的记录条。从中可以清楚的看到Command对象与RecordSet对象的不同点。51Testing软件测试网4{S9h'v]
    方法1(Command)
    O6]"v1N t*i0gJ9_1N138711const adCmdText=&H0001
    b|].|&N138711const adInteger=3
    5uX0Z n;X`/Y4^]o138711const adVarChar=20051Testing软件测试网O }SG6c0Ha#N
    const adParamInput = &H0001
    cW,v%qQ2x138711set conn=Server.CreateObject("ADODB.Connection")51Testing软件测试网^9IH'Yd7px{
    set comm=Server.Createobject("ADODB.Command")
    +](X [hyd138711conn.open "Driver={ Microsoft Access Driver};DBQ="& _51Testing软件测试网0N%v/{5w~1wK_T'Z
    Server.Mappath("/source_asp")&"/property/employee.mdb;"51Testing软件测试网"p*l_"I"f"D/UmL Rv
    comm.ActiveConnection=conn
    b;fMt} X138711comm.CommandType=adCmdText
    a j:_6Mv:Eo138711comm.CommandText="insert into employee (Job_ID,Fri_Name,Last_Name)"& _51Testing软件测试网PY mMN
    &"values(?,?,?)"
    {|.A4yT6|+Z)gf138711set param=comm.CreateParameter("ID",adInteger,adParamInput,3,4)51Testing软件测试网Cbq~8t,L$M.k"N+f
    comm.Parameters.Append param51Testing软件测试网lrx.x U)e
    set param=comm.CreateParameter("FN",adVarChar,adParamInput,255,"bill")
    ;d:}f iPJ!R138711comm.Parameters.Append param
    u1@D)ap138711set param=comm.CreateParameter("LN",adVarChar,adParamInput,255,"Gates")
    Vk MX7n138711comm.Parameters.Append param
    v}YrM2M138711comm.Execute
    "M/U9H Ov"~;O1zYP138711conn.close
    51Testing软件测试网]'BZ9B G+{

    51Testing软件测试网 [tf_-Kd8s&O6S

    51Testing软件测试网 Pm-e'm1bq:c v

    }R cJ(ee6j5J138711方法2(RecordSet)
    2[0UP"ZoC138711const adCmdTable=&H0002
    mOt;yAk138711set conn=Server.CreateObject("ADODB.Connection")51Testing软件测试网;Hgb3`$eq Z
    set rs=Server.Createobject("ADODB.RecordSet")51Testing软件测试网'fH&a-u-y.~)Z
    conn.open "Driver={Microsoft Access Driver (*.mdb)};DBQ="& _51Testing软件测试网1U1k:U;^'E kN
    Server.Mappath("/source_asp")&"/property/employee.mdb;"51Testing软件测试网%E(H,^+\J
    rs.ActiveConnection=conn51Testing软件测试网sc5oser
    rs.open "employee",,,adCmdTable
    "z4?.r:X][138711rs.addnew51Testing软件测试网1T/VXOK_l
    rs("Job_ID")=4
    -q#sf0Jl3s;V138711rs("Fri_Name")="bill"51Testing软件测试网` h;ck0Ru%L4o
    rs("Last_Name")="Gates"51Testing软件测试网X O*M G%mTt:b&M?
    rs.update51Testing软件测试网-m G~}9N:d&M9^b
    rs.close51Testing软件测试网Y\^a0U'`Xv5AM
    conn.close
    1\ [j w+Y138711  从上面的例子就可以看出来了,这两个对象在处理一些问题上所用的不同的方法.RecordSet对象似乎更加好理解一些,因为它加入了一些在ANSI SQL中没有的元素,它其实是用 SQL在数据库上产生一个记录集,然后用一个游标来指向这个记录集,超作该游标来遍历这个记录集。但在性能上来讲的话Command的性能也相对要优越些.其可重应用性也非常的好。而且如果你是批量的加入记录的话,你也能体会到第一种方案的好处了,因为Command对象就是将SQL产生的记录集作为整体来处理。下面详细介绍Command对象的属性、方法和集合。
    o6@*L.^3v\13871151Testing软件测试网/F{0T,{I
       1、 CreateParameter方法:用来产生一个Parameter对象,常用的写法为Set param=comm.CreateParameter(name,type,direction,size,value),其中name为参数的引用名,在后面引用参数的值时会有用;type为指定参数的类型,例如整数为adInteger;direction指定参数是输入还是输出,相应的值为adParamInput和adParamOutput;size指定参数的最大长度或最大的值;value指定参数的值。可以将各个选项分开来写,下面的两种写法是等价的:
    &I tT%Cyn `o%U138711Set param= comm.CreateParameter(name,type,direction,size,value)
    M+p*@/Tk@;]13871151Testing软件测试网$fV'`tBFD ~
    set param= comm.CreateParameter(name,type,direction,size)
    \+?U%F P:K6r!s*n$v t-M138711param.value=value
    +WzQ!cP G138711  下面的方法其灵活性更大。大家请注意,在使用了CreateParameter方法后只是建立了新的 parameter对象,还需使用Parameter对象的append方法将该参数传递给Command对象。51Testing软件测试网#@wq0c(U
      2、 Execute方法:在指定了CommandText后,并将参数传递出去后,用Execute方法来完成执行。51Testing软件测试网l{9|"e:x
      3、 ActiveConnection属性:用来指定与Connection对象的连接,这里的一个技巧就是不同的Command对象指向同一个Connection连接。51Testing软件测试网g*e'mSF|XR&[
      4、 CommandText属性:其值可以是一条SQL命令句,可以是一个表名,也可以是一个StoredProcedure名。51Testing软件测试网9abc3UQ*ryk&v
      5、 CommandType属性:它的值由CommandText相应值的给出,分别为adCmdText,adCmdTable,adCmdStoredProc。与前面在讲Connection对象的Execute方法中的相应的选项的含义相同。
    )Py }O| Eg138711  6、 CommandTimeOut属性:设定命令执行的超时的值。
    .yIa/x } Je138711  7、 Properties集合:我们不多讲了,与Connection对象的Property集合相差不多。51Testing软件测试网)n6Tw Yy+Jeg
      8、 Parameters集合:也就是参数对象的集合了,他有主要Item方法、Append方法,和Count属性,用法与Property对象及Error对象的相应属性和方法类似,下面给出一个示例:51Testing软件测试网ahq3Wm \5W
    const adCmdText=&H000151Testing软件测试网Xy;gZg4s)[/ki
    const adInteger=351Testing软件测试网y,U4psG:p_i*U
    const adVarChar=200
    rB3VP5o138711Const adParamInput = &H000151Testing软件测试网4S%QZ X*`tQ$]
    set conn=Server.CreateObject("ADODB.Connection")
    D H?Qy|'l3n9]!K138711set comm=Server.Createobject("ADODB.Command")51Testing软件测试网Wu;? p LR'KyX
    conn.open "Driver={Microsoft Access Driver (*.mdb)};DBQ="& _
    ~,~ rf*L3\138711Server.Mappath("/source_asp")&"/property/employee.mdb;"
    n[M6ssA138711comm.ActiveConnection=conn51Testing软件测试网\-ow7Sf
    comm.CommandType=adCmdText
    ;\ B'h4WKCv*B138711comm.CommandText="Insert Into employee (Job_ID,Fri_Name,Last_Name)"& _51Testing软件测试网4i O1X%}M_%W
    "Values(?,?,?);"51Testing软件测试网1] M(e6x#{7JHj
    set param=comm.CreateParameter("ID",adInteger,adParamInput,3)51Testing软件测试网4mVa0D:C`
    param.value=1451Testing软件测试网K0M v g#g
    comm.Parameters.Append param51Testing软件测试网]`5a1Q1UDc8H
    set param=comm.CreateParameter("FN",adVarChar,adParamInput,255,"bill")
    U"Kg u9kQu9F138711comm.Parameters.Append param
    c*fdS9E;y#mp.B!i [[7a138711set param=comm.CreateParameter("LN",adVarChar,adParamInput,255,"Gates")
    Dk&Xer9K+UYH138711comm.Parameters.Append param
    S h,P3S:C P138711comm.Execute
    f`O'K(e1V?%OP138711conn.close
    e*Mkjk138711"The folowing statments show the value of parametrs
    0~E7Q6M)H-{4g m138711dim i
    O._\(CM Bv|-e138711for i=0 to comm.parameters.count-1
    .cUiX*Y-{K-}2[138711response.write comm.parameters.item(i)&"$#@60;br$#@62;"51Testing软件测试网;a#s\;Z[|
    next
    lI*L'X)I138711  当然,我们在引用参数时也可以不用数字,而用前面在CreateParameter时定义的名字,例如:FN、ID等等。另外我们可以将上面的程序的显示部分改为
    a KR \2w+sv~c138711dim key51Testing软件测试网y(C1pI x'k+e
    for each key in comm.parameters51Testing软件测试网vn2F4R6h.~'_i]1V:|;e$O
    response.write key&"$#@60;br$#@62;"51Testing软件测试网R's g,QUUh$|?,\
    next
    0J5l3e7E8[138711  下面我想重点讲一讲StoredProcedure,它的强大足以让我们对它关注,当然这其中会涉及到一些SQLServer的知识

    NN~,AHoC13871151Testing软件测试网%~]'u:a}QGGoQ

    五、StoredProcedure51Testing软件测试网WU V(R7u x:w [ E7wCX
      在讨论StoredProcedure之前,我还要对Command对象的Execute方法的作用进行一下阐述,一般来说使用Command的Execute方法有三个目的。1、用于进行一些简单的处理,例如删除一条记录:51Testing软件测试网+o]1Q1c+r `9A0O"q
    comm.CommandType=AdCmdText51Testing软件测试网,~_+tI%EF&U3D%P
    comm.CommandText="Delect From employee Where Job_ID=1"
    6f9K/xa"R138711comm.execute
    'N6xAy;~X138711  这样的工作不需要返回什么东西。2、用于进行一些复杂的处理,例如进行一个Transact的设计,这类一般都是和StoredProcedure一同工作的,而且有输出参数和输入的参数,这也是我们本章的讨论主题。3、用于返回一个RecordSet对象,用于其它的处理,例如:51Testing软件测试网nprF?` j C1`
    comm.CommandType=AdCmdText
    N+Q7Fzr kXx*l[,B138711comm.CommandText="Delect From employee Where Job_ID=1"51Testing软件测试网6P+wvh+Mc.zR$D z
    set rs=comm.execute
    ,o`Lm-lM7e%D!s138711dim i51Testing软件测试网 O-_ Z7fF.j'v&}(n
    while not rs.EOF
    Qo3}a)w'kG138711for i=0 to rs.fileds.count-151Testing软件测试网w*yurk@:ut@
    response.write rs.fileds.item(i).value&","
    !H!cSU$a JS138711next51Testing软件测试网)C!i?o{`P Xbu
    response.write "$#@60;br$#@62;"51Testing软件测试网*I2tB0] J0pL
    rs.MoveNext
    uPQ1w9M#|]ib138711wend51Testing软件测试网;?(AP.T6H"S1TtA
      好了,还是让我们从新回到StoredProcedure的讨论上来。StoredProcedure是什么呢?它是一个预先存储的数据库执行动作集,在SQL的管理结构中,对于一个数据库下有几个部分,一个是数据表的集合、一个就是StoredProcedure的集合。将两者结合可以完成很多强大的功能。StoredProcedure其实是对传统的SQL语句的一种扩展,主要是在参数的输入与输出上。下面我大致的介绍一下StoredProcedure的语法结构和与Command对象的参数的传递问题。
    zR0Mr1qGf138711StoredProcedure的标准写法:(在SQL Server上用Query Analyzer执行)51Testing软件测试网B#e9DBc/Ew+H(f P-x
    Create Procedure Procedure_Name
    3J.ie1b3J9p:zV138711Define Parameter51Testing软件测试网1_3zkz"_$[
    As51Testing软件测试网#m!?g,rB,o0uq
    SQL Structure
    H F6hTK*eo)x138711上  面的语法结构中,Procedure_Name为存储结构的的名字,也是你将在Command中引用的名字。然后是定义输出和输入的参数。最后是一个SQL结构化语句。下面是一个StoredProcedure的例子,它无需输入的参数,也没有输出。51Testing软件测试网6W%_%U*J(l!GZ
    Create Procedure Del_User
    51Testing软件测试网\t2_y~5y

    51Testing软件测试网RK&KJ'as\

    51Testing软件测试网 ^u/a m/A?x

    ,I\ [[1@138711As
    3Vfp\2H138711Delect From Employee Where Job_ID=151Testing软件测试网{VL#}@!o#s lqw
    如果我们要删除指定的 Job_ID该怎么办呢?,这时我们需要给这个StoredProcedure输入的参数。51Testing软件测试网9B-W%x[^'W mVO
    Create Procedure Del_User151Testing软件测试网8S:OFm6I
    @intID int51Testing软件测试网~[#gZU
    As51Testing软件测试网v}@0f7jd8k
    Delect From Employee Where Job_Id = @intID
    }:x?4eF6l!vExW |,?138711好了,这里的@intJob就是一个输入的参数,它可以从外部接受输入的值,下面是给它输入的asp程序:
    !q1B] bD TFr138711set conn=Server.CreateObject("ADODB.Connection")51Testing软件测试网i!ck/@9Ii
    set comm=Server.CreateObject("ADODB.Command")
    +T [O)S,Q138711conn.ConnectionString="Driver={SQL Server};Server=ser;"& _
    _MA u^138711"uid=sa;pass=;database=employee "51Testing软件测试网X;qRe~F
    conn.open
    U PVF T/GO*i b_138711comm.ActiveConnection=conn
    *E%d9onuH3G&@#vz8X9\138711comm.CommandType=adCmdStoredProc
    t5W,rZ5\138711comm.CommandType="Del_User1"
    :QJ)N;CK7W.`pB138711"这里的名字就是前面在SQL Server中定义过的StoredProcedure的名字。
    .[2[y)L,^138711"下面就是参数的输入
    q V4F'g8`2St138711param=comm.CreateParameter("ID",adInt,adParamInput,4)
    X'_hhD138711"这里的adParamInput定义是最重要的。51Testing软件测试网^-F N,N&c]:RA
    Param.Value=1 "这里的值可以输入你想要的值,也可以用Request来获得
    l C:~|/T3A G wk138711Comm.Parameters.Append param
    K(p2x a+`R!`@a(U138711Comm.Execute
    +^ `%\'e5D8E)f+`9G)[138711  这样我们就可以向StoredProcedure传递参数了。有时在一个StoredProcedure中,还存在有输出的参数,下面是一个例子它返回一个Job_ID确定的Fri_Name的值
    q S k5|.d!T3y138711Create Procedure Get_fName
    rP@/yA138711@intID int
    aLX4f(UvQ0j6k138711@fName varChar Output "说明为输出的参数51Testing软件测试网*Qm1Iw ~,km8B(L:^
    As51Testing软件测试网C VRG%v3G%VM
    Select @fName = Fri_Name Where Job_ID = @intID
    A%\A7X8r$]*hA6C$ps2f138711它相应的asp程序也要改写为下面的形式
    Tif/^b2f#_138711set conn=Server.CreateObject("ADODB.Connection")
    M+~8d6Du_9H138711set comm=Server.CreateObject("ADODB.Command")
    :a2{XC@138711conn.ConnectionString="Driver={SQL Server};Server=ser;"&_
    '^:e.v1f(@%C138711"uid=sa;psss=;database=employee"
    C;y]$N5_\138711conn.open
    K!q:opSiB$o*q;y138711comm.ActiveConnection=conn
    9R+X&sa uV*SK%l138711comm.CommandType=adCmdStoredProc
    4S0R@^9Uz-P138711comm.CommandType="Get_fName"
    _f%o q"Kh[&f8Q1@$p1U138711"这里的名字就是前面定义过的StoredProcedure的名字。51Testing软件测试网w!P"U0^l)Pcg/{k
    "下面就是参数的输入51Testing软件测试网b.d+O"Y'jr9t0ya,lYf
    param=comm.CreateParameter("ID",adInt,adParamInput,4)51Testing软件测试网3T-T:t/NC-jo;]
    "这里的adParamInput定义是最重要的。
    ;I9I$`;RS!VP6dZ138711Param.Value=2 "这里的值可以输入你想要的值,也可以用Request来获得51Testing软件测试网2F,\7M?^i:D0yQ:K%|
    Comm.Parameters.Append param
    dJA#u8W138711param=comm.CreateParameter("fName",adVarchar,adParamOutput,255,"")
    Q"l7\*q2{qV#ZFW138711"这里的adParamOutput定义是最重要的。说明它是一个输出的参数,默认的值 为一空的字符串51Testing软件测试网7jWO["n0ku r
    comm.Parameters.Append param
    }p|W t,c138711Comm.Execute51Testing软件测试网\"~/X F;sg:Jh*y&u
    Response.Write "Job_Id为"¶m(0)&"的员工的首姓为"¶m(1)
    p,S'Z]&?138711  我给大家简单介绍了一下StoredProcedure的基本概念,但StoredProcedure比较复杂,如果你想进一步的深入,必须对SQL Server的结构体系有全面的了解。另外,我们并没有在上面的里子中体会到StoredProcedure的优势,很多人会认为那还不如用普通的方法,其实在构建很多企业级的应用时才能够体会到用StoredProcedure的强大和必要性,这里我举一个简单的例子。一个网络银行的数据库(onLoan)中有两个相关的表Loan表和LoanHistory表,loan表用于记录贷款的信息,而每一笔贷款的记录在Loan表中登记后都必须在LoanHistory表中登记,因为定期的结算都是使用LoanHistory表的。你也许会说那很好办啊。用两个Insert Into语句分别向两个表中插入记录不就行了吗!但要注意的是在这个应用中,若记录在任何的一个表中插入失败都必须将整个的过程给取消(也就是一个事务的取消),那么若仅简单的使用两个Insert Into语句的话,若是在第一个语句执行完毕后,在第二个语句尚未完成时就发生了故障,这时第一个语句产生的效果是没法消除的了。如果我们将这整个的过程定义为一个事务,事务没有完整的结束就Roll Back所有的影响不就达到了要求吗?这在SQL Server中可以用Begin Transaction和Commit Transaction来完成的,例子如下:51Testing软件测试网.xg-Kx3eb
    Create StoredProcedure insert_loan51Testing软件测试网1cE8K2f%E
    As
    dR,L4E&E.Np-W138711Begin transaction51Testing软件测试网a(s/EID3F.JSvt i
    Inset into Loan (Loan_ID,Loan_Data,Loan_amount)
    $VY_dV$a138711Values(?,?,?)
    a't8n#]1e7v:^-h/_138711Inset into Loan (Loan_ID,Loan_Data,Loan_amount,Loan_Describle)51Testing软件测试网2b-B*M"Q#m6c'E5r
    Values(?,?,?,?)51Testing软件测试网y,W6l!Dx8S,{w)L
    Commit Transaction51Testing软件测试网ZD,I+R+bdl
      好了,这看上去好象没有什么不同吧,但需要注意的是我们现在将两个Insert into语句作为了一个的事务来处理,只有两个Insert into语句都完成的话才是一个整体的事务结束,那么它才会去作用这个数据库中的两个表,若在事务中发生了故障的话,则所有的影响将取消(Roll Back)。好了,这样的处理是只有在SQL Server中用StoredProcedure才能完成的。ANSI的SQL当然就不行了。这里讲的大家可能不太明白,你可以参看SQL Server的手册来作更多的了解。
    N S6Lv GD5l,S138711  下面我们来看最后的一个对象─RecordSet对象,也是属性和方法最多的一个了。我们使用的频率也是最高的一个,在这之后,我还想谈谈ADO与ORACLE的一些问题。

    qN,Pw*Z2w:w!k138711

    0plCr:e*vK {t138711六、RecordSet对象51Testing软件测试网6C^+[Q3`y~+~
      写到这一篇的时候,我不禁想到了先贤的两句话,一句是孟子在曹刿论战中所说的:一鼓作气,再而衰,三而竭。这篇ADO总结报告的前五部分都是一鼓作气之作,不知这后面的再而衰部分是否能保持连续了。另外的一句是王安石在游褒禅山记中所说的:世之奇伟、瑰怪、非常之观,常在于险远,而人之所罕至焉,故非有志者不能至也。我们学习编程又何尝不是这样了,若非有志,能及于险远是不能真正掌握的。51Testing软件测试网2Gl-S5Q#Q
      好了,讲了这么多的题外话,还是让我们回到正题上来,我想,由于大家对RecordSet都有足够的认识,所以我就不象前面的几章中那样对它的每一个属性和方法都做完整的介绍,我想通过几个有代表性的编程实例来给大家讲一讲。
    7R2\8W8nQwZ,uo1387111、 方法51Testing软件测试网n?k{hj-e
    AddNew, CancelBatch, CancelUpdate, Clone, Close, Delete, GetRows, Move, MoveFirst, MoveLast, MoveNext, MovePrevious, NextRecordset, Open, Requery, Resync, Supports, Update, UpdateBatch
    51Testing软件测试网3Tjq7U2h/Q

    51Testing软件测试网)Jn&p e,J:{M

    51Testing软件测试网+^2Nyu"jqX`

    51Testing软件测试网n)Zx0Dp5D

    2、 属性51Testing软件测试网-ASD/\]5A
    AbsolutePage,AbsolutePosition,ActiveConnection,BOF,Bookmark, CacheSize, CursorLocation, CursorType, EditMode, EOF, Filter, LockType, MarshalOptions, MaxRecords, PageCount, PageSize, RecordCount, Source, State, Status
    51Testing软件测试网t cA?qw^4C)Ykl

    :@c)l [ eO EU1387113、 集合
    v2yn'J `138711Fields,Properties51Testing软件测试网4AN4i%x.]i$Eo

    (C#aH#\nB138711

    F`)u+~yc\!tz;d138711实例一:分页显示及导航:
    ? kiLZ138711
      为什么我要再提分页的这个问题呢?因为这是一个最基本的问题,虽然有很多关于分页的文章,但我觉得他们的方法偏于复杂。其实RecordSet的AbsolutePage就可以轻松的实现分页,当你指定了PageSize属性后,对AbsolutePage指定值就可以翻转到指定的页面。但是如果你想使用AbsolutePage的话,你必须在打开RecordSet对象之前将它的CursorLocation值设为adUseClient,这个属性是继承Connection对象的一个相同属性的。你也可以在打开Connection对象之前来设定它。下面是源代码,为了方便,我将导航栏独立成了一个子程序方便大家使用。51Testing软件测试网-CFJ)b;d
    $#@60;%51Testing软件测试网4i7yC J,aQ+k@(gp
    sub navigator(PageNo,Target)51Testing软件测试网;\8B'Dd6^?/r'j
    Response.Write "$#@60;table border=0$#@62;"
    ovJL*M&Y"X"G2G138711Response.Write "$#@60;tr$#@62;"
    C;g+Ry+a;x138711Response.Write "$#@60;td$#@62;"
    i%[-p1g:Y%GCLb0d138711if PageNo$#@62;1 then
    |tj7tXq(?a138711Response.write "$#@60;a href="&chr(34)&Target&"?Page=1"&chr(34)&"$#@62;┃第一页$#@60;/a$#@62;"
    9g:l,ZOH138711else
    ${,W{8N7~&?138711Response.Write "┃第一页"51Testing软件测试网7W!H'S(M[ X#L1Mb'w
    end if51Testing软件测试网5|;](v!o;q S-`1`
    Response.Write "$#@60;/td$#@62;"51Testing软件测试网*l*h e}%O
    Response.Write "$#@60;td$#@62;"51Testing软件测试网Dc+j5F8al6@)Z
    if PageNo$#@60;rs.PageCount then
    y]e:a ip138711Response.write"$#@60;a href="&chr(34)&Target&"?Page="&PageNo+1&chr(34)&"$#@62;┃下一页$#@60;/a$#@62;"51Testing软件测试网^bZf },Ry ? N
    else51Testing软件测试网xY"Q-DCB8k
    Response.Write "┃下一页"
    W+qU\%?,Z/r138711end if51Testing软件测试网5X!e3JwPwVc
    Response.Write "$#@60;/td$#@62;"51Testing软件测试网x y8N/?Q+h/m(?
    Response.Write "$#@60;td$#@62;"
    :m [;iG3w|iV_ ~138711if PageNo$#@62;1 then
    B"zg8O+o"K138711Response.write "$#@60;a href="&chr(34)&Target&"?Page="&PageNo-1&chr(34)&"$#@62;┃前一页$#@60;/a$#@62;"51Testing软件测试网u*wPzBH7oJxx eX
    else
    -Ix$~-hJL$C138711Response.Write "┃前一页"
    $R~0Wb }138711end if
    8KC}`#nh4F:yu?138711Response.Write "$#@60;/td$#@62;"51Testing软件测试网 n6a4y#H[Y
    Response.Write "$#@60;td$#@62;"51Testing软件测试网~0RJ7dU)x1AN
    if PageNo$#@60;rs.PageCount then
    m{,c;i\t r138711Response.write "$#@60;a href="&chr(34)&Target&"?Page="&rs.PageCount&chr(34)&"$#@62;┃最后一页$#@60;/a$#@62;"51Testing软件测试网2~#wRt(h
    else51Testing软件测试网*r3`:t+A-Bat-w
    Response.Write "┃最后一页"51Testing软件测试网J-Uf(kH a!I2m
    end if
    4\`2A*Q2R l138711Response.Write "$#@60;/td$#@62;"
    )C+g8IKx/W [4oz @B6t138711Response.Write "$#@60;td$#@62;"
    {K[E0qK138711Response.Write "┃页次:"&PageNo&"/"&rs.PageCount&"页┃"&rs.PageSize&"条记录/页┃"51Testing软件测试网#U)NO(e5h9w6\&Z9O
    Response.Write "$#@60;/td$#@62;"51Testing软件测试网)]D X.qSU uC2| M!H h
    Response.Write "$#@60;td valign="middle"$#@62;"51Testing软件测试网Oa5e;D i{w
    Response.Write "$#@60;form. action="&chr(34)&Target&chr(34)&" method="&chr(34)&"POST"&chr(34)&"$#@62;"
    6U)[&zTh G138711Response.Write "$#@60;input type="text"size=3 maxlength=4 name="Page"$#@62;"51Testing软件测试网+T;DB4}$Z{)a ~ s
    Response.Write " $#@60;input type="submit"value="转到"$#@62;"51Testing软件测试网`D Cl(Le
    Response.Write "$#@60;/form$#@62;"51Testing软件测试网6r OS/B@Su_o
    Response.Write "$#@60;/td$#@62;"
    dyED/`:LW138711Response.Write "$#@60;/tr$#@62;"
    U.U/A7B t^/z,Z138711Response.Write "$#@60;/table$#@62;"51Testing软件测试网^h rR5kH'h5c
    end sub
    R9D`"Bl,j138711%$#@62;
    51Testing软件测试网*v5XTJ^:X*^

    q"i6i G [@9Q.Rn]13871151Testing软件测试网&Bv_][*lfH

    51Testing软件测试网I&r PPs Z"?

    $#@60;%
    yGe3Z,e y4f138711const adCmdText=&H0001
    F9w&M(Lt138711const adVarChar=200
    "jcBx(C0\)Gw138711const adInteger=3
    3C ]!dXX138711const adParamInput=&H000151Testing软件测试网&WoS(P fW X"HTE
    const adCmdTable=&H0002
    .`&?x9O$v~7[+NQ138711const adUseClient=351Testing软件测试网o#t"nPZ"H[H0{xJ
    const adDate=7
    oC Mo9]Y138711const adLongVarChar=20151Testing软件测试网0g3mD9TJ
    set conn=Server.CreateObject("ADODB.Connection")51Testing软件测试网a/| \1Ov:?8`'m
    conn.ConnectionString="Driver={Microsoft Access Driver (*.mdb)};DBQ="& _
    CL3KG6EcQ138711Server.Mappath("/source_asp")&"/process/process.mdb;"
    &GtF@$B*L/|Q H;z138711conn.Open
    Eoy5L l`(g-xtW138711%$#@62;

    d9J l3q$i wf?13871151Testing软件测试网~m;vdqn'L X {

    $#@60;%51Testing软件测试网^!X:a$w%Nb$W
    const MaxPageSize=5
    ![Ms1r*\q5[138711%$#@62;51Testing软件测试网 QO-uIxPp
    $#@60;html$#@62;51Testing软件测试网p0B8O}Xc.Hp1G
    $#@60;head$#@62;
    @{ B7r@,dOi138711$#@60;title$#@62; See Book $#@60;/title$#@62;
    h*NQ&klU)E138711$#@60;/head$#@62;
    oPPm&Cc138711$#@60;body$#@62;51Testing软件测试网@%fR2iU v+MH
    $#@60;%51Testing软件测试网Nrt |$Yvy
    dim i,j,PageNo
    tj(n*KTt138711set rs=Server.CreateObject("ADODB.RecordSet")51Testing软件测试网,w.F kk B#~o
    rs.ActiveConnection=conn
    M,DD'O#M%@7L138711rs.CursorLocation=adUseClient
    ,`1zG4kxuU138711rs.Open "Select * From books",,,adCmdText
    6[(o3_/wzK+ew138711if rs.BOF then51Testing软件测试网SE&o,P c0Y
    Response.Write "欢迎使用图书,资料管理程序!"51Testing软件测试网9n.UTP;W!rt
    else51Testing软件测试网J6`3w h,D"dI
    rs.PageSize=MaxPageSize
    D2G+kF%i138711if isempty(Request.QueryString("Page")) then51Testing软件测试网dz[&S u2y ar7m
    PageNo=151Testing软件测试网:n``4P Tr#JX_
    elseif cInt(Request.QueryString("Page"))$#@60;1 then
    J+z lkK2x138711PageNo=1
    kl` rh-Nj B5^D138711elseif cInt(Request.QueryString("Page"))$#@62;rs.PageCount then
    A5E$w+EjQ P P138711PageNo=rs.PageCount51Testing软件测试网0O7S^4oTJ5y$Q]
    else
    2p n~?P/arw.l138711PageNo=cInt(Request.QueryString("Page"))
    ?%W:rA#X(I3T6bIq138711end if
    4H.P#~7i&V@(l138711if Request.ServerVariables("Request_Method")="POST" and not Isempty(Request.Form("Page")) then
    @ V9N S]N3R138711PageNo=cInt(Request.Form("Page"))
    %Y2C&K?Sp)S"a(n138711end if
    cU'\ O]#T138711rs.AbsolutePage=PageNo
    vD xK:s138711Response.Write "$#@60;table border="0" width="100%"$#@62;"
    1IX'W,M.Xi8R&M138711Response.Write "$#@60;tr$#@62;$#@60;td colspan="&rs.fields.count&"$#@62;"
    v#[U+~!m f8X8k138711Target="books.asp"
    c&hcG*|_ O138711call navigator(PageNo,Target) "调用导航栏
    &vhNp#t,{A EF138711Response.Write "$#@60;/td$#@62;$#@60;/tr$#@62;"51Testing软件测试网r`9[]"u
    Response.Write "$#@60;tr$#@62;"51Testing软件测试网,]%dQw }[ CM_
    for i=0 to rs.fields.count-1
    $_ q#@9Fz138711Response.Write "$#@60;td$#@62;"&rs.fields.item(i).name&"$#@60;/td$#@62;"
    `,^[o_WVF)s#}138711next
    F$\Z/R:bhh138711Response.Write "$#@60;/tr$#@62;"51Testing软件测试网)I4B'Ij8C/a.So!E(Ei
    j=051Testing软件测试网%Uh$zokS
    while (not rs.EOF) and j$#@60;rs.PageSize51Testing软件测试网y1_8Q/^c7epi~4dg]
    Response.Write "$#@60;tr$#@62;"
    S w2]'s-e4`138711for i=0 to rs.fields.count-151Testing软件测试网'b,n.g7l3^@3A
    if i=1 then
    StwN0o/at"DCGB138711Response.Write "$#@60;td$#@62;"&"$#@60;a href="&chr(34)&"status.asp?BookName="& _51Testing软件测试网Y,[)qi|]~/B
    rs.fields.item(i).value&chr(34)&"$#@62;"&rs.fields.item(i).value&"$#@60;/a$#@62;$#@60;/td$#@62;"
    iO${.z9@I3}z'Z? P138711"这里这样写是为了级联式查询而做的。
    T0fjGxj138711else
    uqW%QT M138711Response.Write "$#@60;td$#@62;"&rs.fields.item(i).value&"$#@60;/td$#@62;"51Testing软件测试网G?8V{J
    end if
    Q1ncU5K7g2IO(w9l?138711next
    Dajs(gEL$~138711Response.Write "$#@60;/tr$#@62;"
    :SE[e;x8FW.d:V)z o:m138711rs.MoveNext51Testing软件测试网{X+Up'o sg8u
    j=j+1
    PD;^b8Ru J*e138711wend
    .LL2G!E,u'w/?138711Response.Write "$#@60;/table$#@62;"
    %y/h'T p7{qt }x138711end if
    "REkm.e IjD;_138711%$#@62;

  • (转)用ADO连接数据库的三种方法及其性能比较

    2009-03-30 15:54:56

    ado连接数据库通常有三种方法:system dsn connection,dsn-less connection 和 ole db connection,这是大家都很熟悉的,它们的使用方法如下:

    (注:三种方法的区别在于使用的是哪个关键字 - dsn,driver,data source,provider。uid,pwd 是 odbc 的标记,user id,password 是 oledb 的标记。特别指出的是 data source 在 odbc 标记中表示数据源,等同于 dsn,在 oledb 标记中表示服务器名或数据库名。)

    'system dsn connection

    set cnn = server.createobject("adodb.connection")

    cnn.open "dsn=your_dsn;uid=user_name;pwd=password;"

    '或者用 oledb 标记

    cnn.open "data source=your_dsn;user id=user_name;password=password;"

      

    'dsn-less connection

    '以sql server为例

    set cnn = server.createobject("adodb.connection")

    cnn.open "driver={sql server};server=server_name;uid=user_name;pwd=pwd;database=pubs"

    'ole db connection

    '以sql server为例

    set cnn = server.createobject("adodb.connection")

    cnn.open "provider=sqloledb;data source=server_name;initial catalog=pubs;user id=user_name;password=pwd;"

    下面,我们讨论一下它们各自的性能。

    从本质上说,system dsn 和 dsn-less connection 都是通过 odbc 与数据库进行连接的,它们之间区别不大(事实上也确实如此)。有很多人说 dsn-less connection 要优于 system dsn connection,对这一点我不反对。(是不是前后有些矛盾,刚说它们区别不大,现在又......)我曾经分别对这两种连接测试过,但是失败了。因为我的测试数据没有规律,根本说明不了问题(或许用假设检验能比较两者的性能,不过得算死)。于是我得出了结论:没有结论!后来在网上看到一篇文章 system dsn or dsn-less connection? 算是有了答案。

    结论就是(这是原文):

    these tests showed that dsn-less connection were slightly faster than system dsn connections.the increase in performance was nothing monumental;the greatest performance boost was mere 13% faster with 64 concurrent requests.for one,two,or four concurrent requests,there was virtually no performance improvement.in fact,no noticeable improvement is seen in a dsn-less connection over a system dsn until there are 10 or more concurrent connections.

    为什么?因为 system dsn 在连接时要读注册表。

    现在只有ole db没有说了(打字真累)。ole db 比 odbc 要高效的多。

    根本不用测试,这个结论是显而易见的。如果你还有些怀疑,建议去看看 连接池(connection pooling)介绍 那里有 mdac framework 的图示,从图中可以看出,经 odbc 连接是 ado-->ole db-->odbc provider-->odbc-->driver-->数据库;经 ole db 是 ado-->ole db-->db provider-->数据库。哪个更直接?当然是 ole db!

    ole db 连接数据库比 odbc 快,检索数据比 odbc 快。所以,我建议每一个在网上安家的人:用ole db!

    set cnn = server.createobject("adodb.connection")

    'connection string for sql server

    cnn.open "provider=sqloledb;data source=srvname;initial catalog=dbname;user id=user_id;password=yourpassword;"

    'for access

    cnn.open "provider=microsoft.jet.oledb.4.0;data source=db_path"

    连接数据库就是这么容易!

    Deer 08:47:54
    'for Access
    cnn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=db_path"


    1.
    set dbconnection=Server.CREATEOBJECT("ADODB.CONNECTION")
    DBPath = Server.MapPath("customer.mdb")
    dbconnection.Open "driver={Microsoft Access Driver (*.mdb)};dbq=" & DBPath
    SQL="select * from auth where id="" & user_id &"""
    SET uplist=dbconnection.EXECUTE(SQL)

    2.
    set dbconnection=Server.CreateObject("ADODB.Connection")
    DBPath = Server.MapPath("customer.mdb")
    dbconnection.Open "provider=microsoft.jet.oledb.4.0;data source="&dbpath
    SQL="select * from auth where id="" & user_id &"""
    SET uplist=dbconnection.EXECUTE(SQL)

    3.
    DBPath = Server.MapPath("customer.mdb")
    set session("rs")=Server.CreateObject("ADODB.Recordset")
    " rs=Server.CreateObject("ADODB.Recordset")
    connstr="provider=microsoft.jet.oledb.4.0;data source="&dbpath
    SQL="select * from auth where id="" & user_id &"""
    session("rs").Open sql,connstr,1,3

    4.
    建odbc源xxx
    set conn=server.createobject("Adodb.connection")
    conn.open "DSN=xxx;UID=;PWD=;Database=customer"

  • (转)QTP将错误信息写到数据库中

    2009-03-30 11:45:05

    1、在SQL Server中新建数据库QTP,并新建表Q_Message,字段ID,自动增加,字段Message,varchar255

    2、在管理工具中新建ODBC的数据源

    3、将错误信息存储到数据库

    On   Error   Resume   Next

    Dim a,b,c
    a=0
    b=1
    c=b/a
    ErrorHandle()

    d

    ErrorHandle()

    Public Function ErrorHandle()
            If Err.Number <> 0 Then

            DB("Error Num: " & Err.Number & "; Error Src: " & Err.Source & "; Error Desc: " & Err.Descrīption)

      End If
    End Function

    Public  Function DB (sql)
     Dim cmd,aa
     aa="INSERT INTO Q_Message(Message) VALUES ('"&sql&"')"
     Set cmd=createobject("adodb.command")
     cmd.activeconnection="Driver={SQL Server};Server=TJMDCL-SUNQIANG;Uid=sa;Pwd=sa;DATABASE=QTP;"
     cmd.CommandType = 1
     cmd.CommandText = aa
     cmd.Execute()
     Set cmd.activeconnection=Nothing
     Set cmd=Nothing
    End Function

  • (转)在QTP中将数据库的数据导入到EXCEL

    2009-03-30 11:44:02

    昨天遇到这个问题.自己也有点迷茫,在51上发帖后得到高人指点,在这里我将代码写出来,留个足迹,呵呵,谢谢风过无痕.M,Eo7[0J H K13871151Testing软件测试网9I P-v x5~KB*{7j#L

    ------------------

    .mU!O+_(m4UJ1|138711

    |VX!g1uF138711Set excelObj = CreateObject("Excel.Applicaiton") '创建一个对象51Testing软件测试网}6Ag4yvU:`J? `

    51Testing软件测试网S6wu6A XRo:O

    xlsUrl = "C:\QTP\0110\sql-excel-qtp\data.xls"  '指定一个已经存在的XSL文件路径

    u1j4jZ+G G&yOW:|5K13871151Testing软件测试网+R2CCG'RM6[h

    excelObj.workbooks.open(xlsUrl)    '打开EXCEL

    |;^6d/zN4x"Q/A13871151Testing软件测试网N5e%Z7e*T7d"p9w

    Set sheetNew = excelObj.sheets.item(2)  '设置将数据放在EXCEL中的那一页上(索引从1开始)51Testing软件测试网-Q*P bj R5I{!|edz

    /^+dv+|$y138711'相关的数据库操作

    M@MQf5d9]13871151Testing软件测试网%T/]A o$Y

    Set conn = CreateObject("adodb.connection") set rs = createobject("adodb.recordset") conn.open "Provider=SQLOLEDB.1;Password=qaqc;Persist Security Info=True;User ID=test;Initial Catalog=test;Data Source=192.168.0.53" sql="select * from test" rs.open sql,conn

    &`"Ic~9h`X13871151Testing软件测试网.G+Mf Y9a)^4[

    Dim i while not rs.eof

    U+Mpr R138711

    ]2uhO Hd[138711    user_id = rs("user_id").value51Testing软件测试网!yq"d"[qc Gx

    51Testing软件测试网1v%CoZ;Do Q

        user_name = rs("user_name").value51Testing软件测试网TI:UU&f$] S

    +l.I7v%DA)G9`:|I138711    sheetNew.cells(i+1,1).value = user_id  '列付值51Testing软件测试网 i%k5n@&`)i*L

    N6]8H)l!Oi:n138711    sheetNew.cells(i+1,2).value = user_name  '列付值51Testing软件测试网4o _ F0Mlc4ya0r9k

    6N/cv\Re7j3V138711i = i + 1

    { J%A6q8c13871151Testing软件测试网 YM)t7sD{?x.d%p

        rs.movenext

    sx[q-}4`&k T4W.V138711

    Ws6eF[0d\Zl4R&CHx138711wend

    9m ~r0`vC Fy13871151Testing软件测试网 X.w1v}&a

    excelObj.activeworkbook.saveas "C:\QTP\0110\sql-excel-qtp\data.xls"  '保存数据51Testing软件测试网iy$y {5o,Dx4v H(|D

    ] oBNT138711excelObj.quit    '关闭对象

    !tuy"` ~5^138711

    6iW!Rns5D Y6k138711set excelObj = nothing  '清空对象

    .Ij1UQW1\6["?c13871151Testing软件测试网cMN:E4~5_ G)[

    rs.close    '关闭数据库连接操作51Testing软件测试网*he3|-lu:|T

    %IM9bT,@ _ w138711set rs=nothing

    4K2g6b"m1M8p,c5Z13871151Testing软件测试网K `$aa`8D,p+y

    conn.close51Testing软件测试网r)~_ `JF

    51Testing软件测试网E$MI1ZgC*e

    set conn = nothing

    b'A e2mJb\i138711

    8f(Q9Yse8r f;])X138711 

    @TCWm;uUa138711

    H.lD'm3j)@%~x8?138711------------这就是导出到EXCEL的全部过程:),后面如果要用到这些数据的话,直接导入进来就可以

  • (转)QTP访问数据库(推荐)

    2009-03-30 10:45:53

    一 、先给一个访问数据库的vbs脚本:

    使用的时候只需要调用下面标记为红色的三个函数基本就可以了

    '@Description获取检索到数据集
    '@Documentation<selectCommandText>查询语句
    Public Function FillDataTable(ByRef selectCommandText)
     Dim conn

     Set conn = getOleDbConnection()

     Dim cmd

     Set cmd = getOleDbCommandInstance()
     
     cmd.CommandText = selectCommandText
     cmd.Connection = conn
     Dim adapter
     Set adapter = getOleDbDataAdapterInstance()
     
     adapter.SelectCommand = cmd
     Dim data
     Set data = getDataTableInstance()

     adapter.Fill(data)

     conn.Close

     Set FillDataTable = data
    End Function

    '@Description执行一条无返回结果集的Sql语句
    '例如Update 、Insert、delete语句
    '@Documentation<selectCommandText>查询语句
    Public Function ExecuteNoQuery(ByRef selectCommandText)

     Dim conn

     Set conn = getOleDbConnection()

     Dim cmd

     Set cmd = getOleDbCommandInstance()
     
     cmd.CommandText = selectCommandText
     cmd.Connection = conn
     '返回影响的行数
     Dim resultCount
     resultCount =cmd.ExecuteNonQuery()

     conn.Close
     Set ExecuteNoQuery = resultCount
     
    End Function

    '@Description执行查询,并返回查询所返回的结果集中第一行的第一列。忽略额外的列或行
    '例如Select count(*) from student
    '@Documentation<selectCommandText>查询语句
    Public Function ExecuteScalar(ByRef selectCommandText)

     Dim conn

     Set conn = getOleDbConnection()

     Dim cmd

     Set cmd = getOleDbCommandInstance()
     
     cmd.CommandText = selectCommandText
     cmd.Connection = conn
     Dim resualtObject
     resualtObject = cmd.ExecuteScalar()

     conn.Close
     ExecuteScalar = resualtObject
     
    End Function

    '@Description获取OleDbConnection对象
    Private Function getOleDbConnection()

     Set conn = DotNetFactory.CreateInstance("System.Data.OleDb.OleDbConnection")
      conn.ConnectionString =Environment.Value("ConnectionString")'我的数据库连接字符串在环境变量里面保存,原型如下:
      'Provider=SQLOLEDB;server=127.0.0.1;database=Northwind;uid=sa;pwd=sa
      conn.Open()

     Set getOleDbConnection = conn
    End Function

    '------------------------------------------------------------------------------------------------------------

    '@Description获取OleDbCommand的对象实例
    Private Function  getOleDbCommandInstance()
     Dim cmd

     Set cmd = DotNetFactory.CreateInstance("System.Data.OleDb.OleDbCommand")
     Set getOleDbCommandInstance = cmd
    End Function

    '@Description获取OleDbDataAdapter的对象实例
    Private Function  getOleDbDataAdapterInstance()

     Dim adapter
     Set adapter = DotNetFactory.CreateInstance("System.Data.OleDb.OleDbDataAdapter")
     Set getOleDbDataAdapterInstance = adapter
     
    End Function

    '@Description获取DataTable的对象实例
    Private Function  getDataTableInstance()
     Dim data
     Set data = DotNetFactory.CreateInstance("System.Data.DataTable")
     Set getDataTableInstance = data
    End Function

    '@Description获取DataSet的对象实例
    Private Function  getDataSetInstance()
     Dim data
     Set data = DotNetFactory.CreateInstance("System.Data.DataSet")
     Set getDataTableInstance = data
    End Function

    我写的这个访问数据库的底层代码主要是用于访问SQLServer数据库和Access数据库,很容易扩展写成专门访问SQLServer数据库或者Oracle数据库的代码,如果搞不明白,可以直接发邮件给我!

    二 、再给一个如何调用上述代码的实例:

    以SQLServer自带的NorthWind数据库为例,直接在QTP的专家视图里面写的代码,如下:

    Dim rowcount

    '获取Products表的记录数,这个返回值不是一个对象,所以不能这样写:Set rowcount = ExecuteScalar("Select Count(*) From Products")
    rowcount = ExecuteScalar("Select Count(*) From Products")
    msgbox rowcount

    Dim dtdata
    '获取Products中的所有数据,放到dtdata对象中
    Set dtdata = FillDataTable("Select * from Products")

    rowcount = dtdata.Rows.Count
    Dim i
    For i = 0 to rowcount -1

    'dtdata.Rows.get_Item(i)("ProductName")   获取第i行字段名称为ProductName的内容,
    '也可以这样写dtdata.Rows.get_Item(i)(1) 即可以是字段名也可以字段编号
    Reporter.ReportEvent micPass,"第"&i&"条记录","ProductName:"&dtdata.Rows.get_Item(Cint(i))("ProductName")&",QuantityPerUnit:"&dtdata.Rows.get_Item(Cint(i))("QuantityPerUnit")
    Next

     

    下面一个截图是通过QTP提供的Add Watch的功能学习如何使用DataTable中更多的属性和方法!很有用的哦!!

    如果发现有什么问题,欢迎指正,共同进步!!!

    调试DataTable对象抓图,很有帮助的哦!
     

    调试DataTable对象抓图,很有帮助的哦!

  • (转)QTP通过.NET组件访问多种数据库的方法

    2009-03-30 10:43:32

    在编辑QTP脚本中经常需要访问数据库或者Excel,针对数据库或者文件的访问,大家最常用的应该是使用ADO的一系列对象,例如获取数据库连接对象:Set connObj = CreateObject("ADODB.Connection");获取记录集获取对象:Set rdsObj = CreateObject("ADODB.Recordset"),获取Excel文件访问对象:Set excelObj = CreateObject("Excel.Application")等等。不知道大家使用过程中有何感受,我感觉最不爽的地方就是读取记录集中的数据,必须要和数据库保持连接状态,并且还要使用循环来读取数据,不能一下子定位到我想要的数据(可能是自己还不太会用吧,抱歉O(∩_∩)O哈哈~)。曾经用C#写过几年的程序,感觉使用ADO.NET的系列对象来访问数据库、操作数据是相当的方便,所以一想到访问数据库和XML格式的数据就想到ADO.NET的数据库访问对象,DataSet、DataTable对数据的访问还是比较方便。最令人兴奋的是QTP可以通过创建数据库访问对象的方式使用ADO.NET,并且操作的方式和流程与在C#下编程思路没有多大区别。废话少说,言归正传。

    首先教给大家一个小知识,如何获取各种数据库连接字符串:

    新建一个文本文件,把它的扩展名修改成udl,名字可以任意起,如:db.udl,双击该文件按照操作提示即可获取,赶快试一下吧,很不错的。

    OK,开始我们的旅行吧!

     

      首先先附上一个通过.NET从SqlServer数据库读取数据的C#源代码(如果需要访问Access数据库,可以将访问对象修改成System.Data.OleDb下的相关对象,如果需要访问foxpro数据库,可以将访问对象修改成System.Data.Odbc下的相关对象,并且是通用的,Odbc基本可以访问大部分关系型数据库)

     public System.Data.DataTable GetAccessData(string selectCmdText)
     {

          string str = "server=.;database=StudentDB;uid=sa;pwd=sa";
          System.Data.SqlClient.SqlConnection conn = new SqlConnection();
          conn.ConnectionString = str;
          conn.Open();
          System.Data.SqlClient.SqlCommand cmd =new System.Data.SqlClient.SqlCommand();
          cmd.CommandText = selectCmdText;
          cmd.Connection = conn;
          System.Data.SqlClient.SqlDataAdapter adapter=new System.Data.SqlClient.SqlDataAdapter();
          adapter.SelectCommand = cmd;
          System.Data.DataTable dtdata = new DataTable();
          adapter.Fill(dtdata);
          conn.Close();
          return dtdata;
      }

    以上代码对应到QTP的vb脚本中如下所示:

    Dim conn
    Set conn = DotNetFactory.CreateInstance("System.Data.SqlClient.SqlConnection")
    conn.ConnectionString = "server=.;database=StudentDB;uid=sa;pwd=sa"
    conn.Open()

    Dim cmd

    Set cmd = DotNetFactory.CreateInstance("System.Data.SqlClient.SqlCommand")

    cmd.CommandText="select * from student"
    cmd.Connection = conn
    Dim adapter
    Set adapter = DotNetFactory.CreateInstance("System.Data.SqlClient.SqlDataAdapter")

    adapter.SelectCommand = cmd
    Dim dtdata

    Set dtdata= DotNetFactory.CreateInstance("System.Data.DataTable")
    dtdata.TableName="qtptest"
    adapter.Fill(dtdata)
    conn.Close

    msgbox dtdata.Rows.Count  '显示获取的数据条数

    今天事情真多,先写到这里吧,下次把通过DataSet对象对xml数据的操作给大家贡献出来,相信你会放弃使用通过ADO的对象访问xml数据的,只是个人见解,多提宝贵意见!!

  • (转)QTP中DataTable操作大全

    2009-03-30 10:40:36

     序曲

       假设现在有一个Excel文件:D:\data.xls,里面的具体内容如下:有两个Sheet,第一个叫Login,第二个叫InsertOrder;

       当前QTP的Test中有两个Action:LoginAction和InsertAction。当然该Test中对应的DataTable应该有三个:Global、LoginAction和InsertAction;

    下面就详细的说一下DataTable是如何操作这些数据的:

    正文

    DataTable.Import "D:\data.xls" '将data.xls中第一个叫Login表单内容导入到Test的Global表单中,将InsertOrder表单的内容导入到Test的LoginAction表单中,依次类推;感觉怪怪的,所以这个方法比较适合只导入Excel中第一个表单的内容

    DataTable.ImportSheet "D:\data.xls","Login","LoginAction"'将data.xls文件中的Login表单内容导入到当前Test的LoginAction表单中

    DataTable.GetSheet("Global").SetNextRow'设置下一行,红色表示要操作的表单名字
    columnCount = DataTable.GetSheet("Global").GetParametercount'取得Global表单中的总列数
    DataTable.GetSheet("Global").DeleteParameter ("列名")'运行时向Global表单中删除列

    DataTable.GetSheet("Global").SetPrevRow'设置上一行
    cellValue = DataTable.GetSheet("Global").GetParameter("列名")'取得Global表单中某列的值,可以这样写:DataTable.Value("列名","表单名字"),我喜欢这种写法

    rowCount = DataTable.GetSheet("Global").GetRowCount'取得Global表单中的总行数
    DataTable.GetSheet("Global").SetCurrentRow(3)'设置当前行为第3行
    DataTable.Value ("列名", "表单名字")="twf"'运行时设置某列值,例如DataTable.Value ("username", "LoginAction")="twf"

    DataTable.Export "D:\result.xls"'将当前Test的所有表单(LoginAction和InsertOrderAction、Global)中的所有内容全部导出到result.xls中

    DataTable.ExportSheet "D:\result.xls","LoginAction"'将当前Test的LoginAction表单中的内容导出到D:\result.xls文件中

    有问题多多指教,共同进步!您的关注会使俺快乐!!!

  • (转)我的QTP的学习方法及总结(3)

    2009-03-29 13:49:49

    写脚本的时候,当系统发生页面跳转或是当前操作有返回结果需要等待的时候,需要对是否到达预期页面或预期结果是否返现进行验证,否则很容易出现脚本运行失败的情况。

    @4imHVJ|u138711

    以下是几种常用check方法。51Testing软件测试网2LD8R U r t

     51Testing软件测试网+AE[ Ak8q

    1.      QTP自带Sync方法51Testing软件测试网;U!o9KhN

    SystemUtil.Run "iexplore.exe", "http://www.google.com"51Testing软件测试网1g,^]3y5[.E:Q/f R xXl

    Browser("Google").Page("Google").Sync

    R1^_9T1im(V138711

    与这种方式有关的设置如图。

    m3a%i,n K*p1q*Z9eGq138711

    :]Bn_6f138711

    D+\/m%XsI(t9g-C"Od138711

     51Testing软件测试网%N(Da#y%t/`f;m W!`

    2.      WaitProperty方法51Testing软件测试网%@"IG;m K

    这个也是支持的一种方法,等待指定对象属性获得指定值或超出指定超时后再继续下一步。原型object.WaitProperty(PropertyName,PropertyValue, [lTimeOut])帮助文档对各个参数有详细说明。TimeOut如果不指定也会使用上图中的设置。

    rZ$Gqsi7}138711

    If Browser("百度一下,你就知道").Page("百度一下,你就知道").WaitProperty("title","百度一下,你就知道",1000) Then

    m"w"Oksg#YF138711

       '后续操作51Testing软件测试网.hr%k:||PYd!k _

    End If51Testing软件测试网D}P cw:JtN

     51Testing软件测试网gCw+ty@#M

    3.      利用DomRegExp检索51Testing软件测试网ywd3h.R D:[ B

    这种方法利用DomcreateTextRange方法获得页面文本,再结合正则表达式进行检索,判断页面是否有预期的结果。

    +A"Dn-p5O&N138711

    set a=Browser("百度一下,你就知道").Page("百度一下,你就知道").Object.body.createTextRange()51Testing软件测试网P1p0zK&A"q\2oiZ

    c=Check (a,"")51Testing软件测试网^m8@p y/x

    msgbox c

    A8xjdd138711

     51Testing软件测试网Zd~ L0q^!Q+YC

    '检索函数

    8x"?)Szq?138711

    'Obj 检索的对象51Testing软件测试网%jr?v|Q9^

    'checkStr 检索的字符串51Testing软件测试网 l9D;n*F"x@vF

    Public Function Check(ByRef Obj, ByRef checkStr)51Testing软件测试网p7mcFj7Rj

                b=Obj.text51Testing软件测试网px2P7XT1F5[\

                Set regEx=new RegExp51Testing软件测试网6|nx3D2JMe"~;h

                regEx.Pattern=checkStr  '设置需要查找的字符串

    pi3r#@E~a? ~138711

                regEx.IgnoreCase=true

    9W1eT;F S138711

                regEx.Global=true51Testing软件测试网z,p3R2z2IOT0e q+c

                Check = regEx.Test(b)   '在页面的文本中检索预期值,返回布尔值

    &i0@{BZ)msw138711

    End Function51Testing软件测试网 T6k5x"_F _$X_7L

    正则表达式可以参考QTP安装目录help下的VBScript56.CHM文档。

    $Q/| x;M3V138711

     

    &_d c;m/x4MH y2P138711

    4.      利用Dom本身的查找

    5kb0QP N JO4F138711

    DomcreateTextRange也提供了查找的相应方法。如下代码。51Testing软件测试网w6w/~?Lj6e'I

    set a=Browser("网易电子邮箱-极速3.0正式版").Page("网易电子邮箱-极速3.0正式版").Frame("index").Object.body.createTextRange

    2Z/D:GE*R138711

    msgbox Check (a,"草稿箱")

    )~An/o d R!f138711

     

    G;Rh,K3bw138711

    Public Function Check(ByRef Obj, ByRef checkStr)

    j9QK {ZT0l y{"^138711

    found = Obj.findText(checkStr)51Testing软件测试网`k,f \*Lavv

    Obj.select

    cO6YX.`-L t138711

    Check=found

    PWz;e{n138711

    End Function

    "Xx7D ]v$i138711

    以上代码是登陆163邮箱后检索页面是否有“草稿箱”文本并选中文本。51Testing软件测试网BFF}{J0D

     

    :e ^9E*ksSy5s138711

    5.      利用readyState判断页面当前所处状态51Testing软件测试网 d;|qxJE&mF

    利用页面的readyState属性判断当前页面所处状态。

    a^f Lv138711

    SystemUtil.Run "iexplore.exe", "http://www.sina.com.cn/"

    tb!|;x$TfQC138711

    msgbox Browser("新浪首页").Page("新浪首页").Object.readyState51Testing软件测试网:_K_0_.JKn3}3T

    51Testing软件测试网1j"V-y,w"x @1v

    I m i*C#l,k4H4z:Yk.|7x138711

    上图是打开sina首页,正在打开的状态及QTP输出的readySta值。如果首页已完全打开返回的值应为Complete51Testing软件测试网5^"v-E^-K

    可以通过readyState返回的状态值,判断进行后续操作。readyState的可能值如下(中英):51Testing软件测试网 q[O X7`.D

    There are five possible values for readyState:51Testing软件测试网n/z*UW^q

    0 (Uninitialized): The object has been created but the open() method hasn’t been called.

    ic:B9R%rsuD138711

    1 (Loading): The open() method has been called but the request hasn’t been sent.51Testing软件测试网+u v"R3Y!^n

    2 (Loaded): The request has been sent.51Testing软件测试网:AZ x#YB5?3? M_!h

    3 (Interactive). A partial response has been received.51Testing软件测试网T.{h@AC|*`

    4 (Complete): All data has been received and the connection has been closed.

    O?j'by138711

     51Testing软件测试网e+dx'c6SRS3O

    readyState有五种可能的值:51Testing软件测试网Lm{mn[iG'|

    0 (未初始化)(xml(标准化越来越近了)HttpRequest)对象已经创建,但还没有调用open()方法。

    "~b9c{ P9|0b138711

    1 (载入):已经调用open()方法,但尚未发送请求。

    &]@?6]&GU+f4]138711

    2 (载入完成)请求已经发送完成。51Testing软件测试网 tm:Tka

    3 (交互):可以接收到部分响应数据。51Testing软件测试网._L(o Ya)k \#L

    4 (完成):已经接收到了全部数据,并且连接已经关闭。

    -fy;Bn#}N'i138711

     

    a*ET [u1aj&j138711

    6.      利用QTP自带的检查点

    F/CTgUWe,gI^z\138711

    这种方式就是在脚本中插入Checkpoint进行相应检查,包括文本、图片、对象属性等,在录制过程或是录制完毕选择Insert—Checkpoint按提示操作即可,QTP会自动生成代码。由于QTP可以自动生成代码,在此不再贴出示例。

  • (转)我的QTP的学习方法及总结—参数化(2)

    2009-03-29 11:47:53

    关于QTP中的参数化51Testing软件测试网A F N-Y@9l.uf|s

    方法一、DataTable方法51Testing软件测试网^o^+d'MQ

    这是QTP提供的一种方法,也是最容易实现参数化的一种方式。QTP针对DataTable对象提供了很多方法,可以对DataTable进行灵活的操作。DataTable分为GlobalLocal两种,Global所有的Action都可以用,而Local就是只能Action自己用。

    zm,B.]&o-a!t138711

    通过DataTable做参数化最直接的方法就是在Keyword View视图下通过选项进行,这样即方便又减少出错的几率。单击要参数化项目的value列,选择出现的箭头弹出Value Configuration Option对话框,在这里可以很方便的进行参数化。

    6q.?|0s#Q4a138711

    51Testing软件测试网 Q6Ha@s]fWcE

    Zf;nzAz uc#G138711

    Parameters选择数据来源类型。DataTable是从数据表中取值,Environment是从环境变量中取值,Random Number是选择随机值。下拉列表选择DataTable后,选择所要使用的数据表Global还是local,最后选择name,参数取自哪列,点击确定后即可完成参数化过程。51Testing软件测试网.Av f|cw.u

    Dialog("Login").WinEdit("Agent Name:").Set DataTable("UserName", dtGlobalSheet)51Testing软件测试网Ja:|Mf-FU ^6b(G

    这是最简单最直接的方式。用这种方式需要注意,在File---Seting---Run需要做相应设置,否则运行结果很容易出错,使实际取到的参数值和预期的不一样或是循环不正确的错误。最好的方式是通过写语句来控制迭代过程中的取值。在脚本开发过程中,这种方式是最常用的。类似如下代码:51Testing软件测试网4J6} ~'Z:x/i4f

    For i=0 to DataTable.GetCurrentRow

    }IBvF*J5a:Fx138711

    Dialog("Login").WinEdit("Agent Name:").Set DataTable("UserName", dtGlobalSheet)51Testing软件测试网1oo@ Z/PU0J:b'[

    DataTable.SetNextRow51Testing软件测试网 X*q*^ h"cU+Rw0{i!e

    Next51Testing软件测试网/Pw*h{M

    51Testing软件测试网G_1J5eW"X1K rz$u

    Vv%RXQ`4IoY138711

    DataTable提供了很多相关的方法和属性,具体参考帮助文档。帮助目录下的Utility.chm文档中有关于DataTable对象的详细介绍。

    )^ d w`U E+if;^138711

    方法二、环境变量实现参数化

    ^1Ys m(~Z(z138711

    Environment对象提供对环境变量的访问。环境变量的来源有两种方式:内部环境变量和用户定义的环境变量,其中后者支持从外部导入,格式为XML文件。用环境变量做参数化有一定的局限性,因为环境变量对数据的操作没有方法一灵活,所以环境变量用的最多还是数据的共享。在此暂作为一种方式来学习,灵活运用就好。

    vi~|F3vMl!O138711

    首先说内部环境变量。它是QTP默认定义的一组变量,包括一些系统信息、项目信息等。目前用到最多的是TestDir,利用这个可以实现一个相对目录的目的。具体应用,在做一个数据驱动的脚本时,将数据文件放到脚本文件夹中,然后利用Environment("TestDir")+DataName导入数据文件。这样可以很方便的移植,而不需要考虑将数据文件放到具体目录下。

    2S:f9rn SR7[Q138711

    用户定义的环境变量,需要自己定义变量名和值。定义好后就可以用这些变量去参数化脚本中的常量。51Testing软件测试网+u{)yOH]_1i

    Dialog("Login").WinEdit("Agent Name:").Set Environment("test1")

    ;}E8s"x#\138711

    51Testing软件测试网D4pBXlx

    y"U"C0A C"p.v138711

    这样做参数时,每个参数值都需要指定,而且不能批量的生成。所以它有一定的应用场景:当一个Test中的不同Action需要同样一个参数,用环境变量去参数化常量是很好的一种方式;其次就是不同的Test需要用到同样的参数时,用环境变量可以很好的解决这个问题。

    9^1m\2B/stb.i138711

    方法三、外部数据源实现参数化51Testing软件测试网 }Tl K z

    利用外部数据驱动脚本的运行,这是经常用到的方法,这样可以很方便的组织测试数据。相对前两种方法,这种方式数据的读取、控制稍有些麻烦。下面以常见的几种方式进行说明。(以下代码并不复杂,没做注释)

    II B0}K/h.?[138711

    1.      数据文件以Excel组织

    c:c#X l]%m'W138711

    Excel组织测试数据是最常用的了。此种驱动可以采用两种方式,将数据ImportDataTab中或是利用com来操纵Excel文件。下面给出这两种方式的示例代码。(输入flight用户名和密码)51Testing软件测试网:{,x_ qwYI.FIt V;a

    方式一、导入到DataTable

    .C;p"LKI*?138711

          '获得数据文件路径,并将数据文件导入到DataTable运行表中51Testing软件测试网d4L+i.e`:A*c Ss7Cw+nE

          DataStr= Environment("TestDir")&"\data.xls"51Testing软件测试网L_.@/bbh R

          DataTable.AddSheet("TestData")

    -WT q tY138711

          DataTable.ImportSheet DataStr,"Sheet1","TestData"

    JQi pj&[&E'o138711

          '输入用户名和密码

    |#k}n*hF138711

          For i=1 to DataTable.GetSheet("TestData").GetRowCount

    5Y!B ?t*hPA'mV!K*P138711

                 DataTable.SetCurrentRow i

    +[ u-l+_0w(G$G-O138711

                 UserName=DataTable.Value("UserName","TestData")51Testing软件测试网 [|z&` ]G{ ^5I

                 PassWord=DataTable.Value("PassWord","TestData")

    nM|)S3qaba138711

                 Dialog("Login").WinEdit("Agent Name:").Set UserName51Testing软件测试网 C5LmIN)s r1D

                 Dialog("Login").WinEdit("Password:").SetSecure PassWord51Testing软件测试网'S;v!C2N5ZiQ

          Next

    ;u/}arn+e138711

    Wv-n[_(B~"V138711

    QrS{.ktXh0E138711

    方式二、利用com操纵Excel51Testing软件测试网1z S.X(b }-? J:]

          DataStr= Environment("TestDir")&"\data.xls"51Testing软件测试网!cb8lN"ZH@"o;n

          Set ExlObj=CreateObject("Excel.Application")51Testing软件测试网7U8D?$~:e:@

          ExlObj.Visible = True

    RB`&_~6d ZZX.cP138711

          ExlObj.DisplayAlerts = FALSE

    (vC'u T%F7b#{138711

          Set book=ExlObj.Workbooks.Open(DataStr)

    Gjz,it-n)T:c8r138711

          Set sheet=book.Worksheets("Sheet1")51Testing软件测试网 Z\.G3Ii#c:X5?$S[s

          For i=2 to sheet.usedrange.rows.count

    $Uf:m,e[4J138711

                 UserName=ExlObj.WorkSheets("Sheet1").Cells(i,1)51Testing软件测试网9v ^w@/I t^'E\

                 PassWord=ExlObj.WorkSheets("Sheet1").Cells(i,2)

    R1k/o;tzfL138711

                 Dialog("Login").WinEdit("Agent Name:").Set UserName51Testing软件测试网n UBS6c5B ? a

                 Dialog("Login").WinEdit("Password:").SetSecure PassWord

    7An\ w)nn6s'Au138711

          Next

    lM0M/d7{0b4b138711

          ExlObj.Quit51Testing软件测试网Z9x3nc A1["wF {

          Set ExlObj = nothing

    e:|^G}V X\0Kj!`138711

     51Testing软件测试网1B5[2oj&|

    2.      数据文件以txt组织51Testing软件测试网%?m.R}{ VgU{

    不多说,直接附上代码。

    3WVuQ+P9|138711

    Const ForReading=1

    I f Z}d138711

    TFilePath= Environment("TestDir")&"\data.txt"

    Ds9?S+Q ?R9KNj138711

    Set Fso3 = CreateObject("Scripting.FileSystemObject")51Testing软件测试网 \$f(b qI,bw8L

    Set DataFile= Fso3.OpenTextFile(TFilePath,ForReading,False)

    7TbwS~7T138711

    DataFile.SkipLine51Testing软件测试网3J4\jtT

    Do while DataFile.AtEndOfLine<>true51Testing软件测试网*KhM9e%haG$S"x

          ReadString = DataFile.ReadLine51Testing软件测试网lr'ml6J%s;{"b_

          DataStr=split(ReadString,",")

    5N`7Da{138711

          Dialog("Login").WinEdit("Agent Name:").Set DataStr(0)51Testing软件测试网:i(PW| E"R

          Dialog("Login").WinEdit("Password:").SetSecure DataStr(1)51Testing软件测试网q;xB5^ CZ d

    loop51Testing软件测试网:Z"}d VCt

    DataFile.close

    9D}rF-FV138711

    Set Fso3=Nothing51Testing软件测试网] o7dv)c

    +TC0q,N4RqH1l138711

    }Z5|KL1d;X138711

    3.      数据文件以数据库组织

    @,zv l"rMz|138711

    下面代码是用Access做的,其他类型数据库类似。不多说继续贴出代码。

    bkF~EN0[4g138711

    strDB="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Documents and Settings\zilingold\桌面\Testdata.mdb;Persist Security Info=False"51Testing软件测试网!q/ik7u3t"V]y^:R

    strTableName="data"

    @~+R-_ Rjh138711

    SetConn=createobject("adodb.connection")

    #zu3CfI`4\ N8p138711

    Set Rst=createobject("adodb.recordset")

    d}E}7g!T138711

    Conn.open strDB51Testing软件测试网4S6a4ph)p

    Rst.open "select * from "+strTableName,Conn,2,251Testing软件测试网3[$gTct/S:JN

    Dim strTest(1)51Testing软件测试网4VTddi'\*UD0Lp

    Rst.MoveFirst51Testing软件测试网E,R(r&B8o%X$Jd?(F

    Do while not Rst.eof51Testing软件测试网EJH6ks'g

          strTest(0)=trim(cstr(Rst.fields(0)))51Testing软件测试网!g's,PU-yFf h

          strTest(1)=trim(cstr(Rst.fields(1)))

    x&XN1E-l(As138711

          Dialog("Login").WinEdit("Agent Name:").Set strTest(0)51Testing软件测试网(w1`4_{fe:L

          Dialog("Login").WinEdit("Password:").SetSecure strTest(1)51Testing软件测试网2clBd#|1{7?,b

          Rst.MoveNext

    H,f;t VQV3{t138711

    Loop

    ?A x,d Fp?138711

    Rst.close

    yxy.zdw138711

    SetConn=nothing51Testing软件测试网],t Hy p/c,y

    $I,IJ!mb`y138711

    51Testing软件测试网-J0cb9i^T

    4.      数据文件以XML组织

    r-{$vL oeN&W9{138711

    XML也是会经常用到的一种方式。继续贴代码。51Testing软件测试网-Z{ X!qYL z {`G

    Dim xmlDoc 'As DOMDocument需要引用xml对象51Testing软件测试网A7ROp:J'bs

    set xmldoc=CreateObject("microsoft.xmldom")

    ,w5q j;a$@138711

    xmldoc.load(Environment("TestDir")&"\testdata.xml")51Testing软件测试网?O2j9G@9w%d9X

    Set Root=xmldoc.documentElement

    kCp|Rm"m138711

    For i = 0 To Root.childNodes.Length-151Testing软件测试网-UC!g9P8hTCEY

                 Set TestCases = Root.childNodes.Item(i)51Testing软件测试网WJ2TUod mK

                        For j = 0 To TestCases.childNodes.Length-1

    |G#Sk0Ecl138711

                               Set TestCase = TestCases.childNodes.Item(j)51Testing软件测试网8D,Hb9J7[-p E

                                      If cstr(TestCase.nodeName)="UserName" Then51Testing软件测试网_!p-@_*N9jNy

                                             Dialog("Login").WinEdit("Agent Name:").Set TestCase.text      51Testing软件测试网 G*C%X4F{

                                      end if

    Df%ws8GI:oDV-T.A138711

                                      If cstr(TestCase.nodeName)="PassWord" Then51Testing软件测试网R^*zb(N

                                             Dialog("Login").WinEdit("Password:").SetSecure TestCase.text                                                             End If                         51Testing软件测试网2[HQ xT

       &nbs

    Next51Testing软件测试网.tp ~\/Zx.[

          Next51Testing软件测试网Q/F"\:y\9@A

    Set root=nothing

    B tV!^ du3_;i#^7u138711

    Set xml=nothing51Testing软件测试网[|'WI^b2_

  • (转)我的QTP的学习方法及总结(1)

    2009-03-29 11:41:34

    上一部分说了QTP识别对象的原理,运行机制问题。接下来自然就是正确识别对象以后,如何操作这些对象。换句话说就是我们用QTP对界面上的元素都能干些什么。在测试过程中,我们要尽量模拟出用户的操作场景,验证系统在这些场景下的响应。QTP的脚本,就是让程序去实现这些操作,如单击、选择数据、输入数据等操作。

    8]4SLCXvkr+o.FH138711

     51Testing软件测试网#{)kEK J`%c-N]mq G

    QTP正对每一种对象,均提供了一套方法。写脚本时,在对象后输入英文“.”则会自动感知,列出该对象所有支持的方法。如图51Testing软件测试网%]M~ U)X"yq/]

     51Testing软件测试网!_mv7lgWi ma

    W1q y$~"Ip J3w-\[138711

    51Testing软件测试网&H(A(k%vBOV

     

    6}Eh0G[CP$?S138711  学习、掌握这些方法的用法是很重的一环。这也是QTP很基础的一些应用。学习这些方法最好的方法就是挨个的自己去验证,并结合帮助文档把每个用法的要点、应用场景、作用搞明白。有些方法网上的朋友也做过详细的分析、比较,可以参考加深理解。所以在这个阶段就尽情的按“F1”吧。
    N-K2v1E;B-m }u13871151Testing软件测试网&g2O4J5X]#Q.Eo
      附中文帮助地址:http://bbs.ltesting.net/thread-57752-1-1.html51Testing软件测试网3j~"^ B&r)c

    2\#} }$UT No$?138711  经常有朋友问我这么多对象,这么多方法,怎么能记的住呢。其实只要安下心,慢慢钻研1到2个小时,就会发现其中的规律。很多方法对很多对象都是通用的,而且方法都是相通的,所以只要把一个对象下边的方法掌握了,
    其他对象的方法掌握起来也就很简单了。有一些方法一点要牢记,做到就像吃饭前要拿筷子一样得心应手。如Click,Select,WaitProperty,Set,ColumnCount,GetCellData,RowCount等这种常用的方法。还有一些很相似的用法的区别要搞清楚,如:GetROProperty,GetTOProperties,GetTOProperty,GetTOProperty。这几个很相近,但从名字上很容易区分开,他们的介绍网络上已经介绍的很清楚,这里不再累述。51Testing软件测试网MH1n1T-Pf jL

    "` \h*@)UEDH{{138711  Browser对象一个很有用的表示符creationTime,这个属性在写
    web系统的脚本时可以发挥很大作用。它是根据Browser的打开顺去去识别对象,而不会根据具体的属性。这样可以避免由于属性改变造成对象不识别的麻烦。Browser("creationTime:=1")识别得失第二个打开的浏览器。creationTime是Browser对象特有,其他对象类似属性时index和Location。
    !O4x Gf#c |138711
    d`+?S8Ak138711  WebTable对象,有时系统里存在多个表,但表面看是一个表而且这些表的属性都一样。但只有一个表里有数据,其他都是空表。我曾经遇到脚本不报错,但取的值一直为空就是因为这个原因。解决办法就是在属性里加上index去识别表。51Testing软件测试网M"^b;? \6p
    51Testing软件测试网R"e*O$LE;@|"K[
      通过对象的Object属性可以访问对象的内部方法和属性,这样可以使脚本更灵活,有时可以解决大问题。通过spy可以知道对象都有哪些内部属性和方法。如图,在Run-time列出了内部方法。

     51Testing软件测试网N9z(o5s3oNl

    51Testing软件测试网 g0fbc'U2w l

     51Testing软件测试网~ `%|\ xSi}

    51Testing软件测试网|;g1N+uC7w]Z6TtM}

    代码1

    |m{J~5jX^138711

    SerchText("")51Testing软件测试网antah(S

    Sub SerchText(testStr)51Testing软件测试网.m?u;dz

          set a=Browser("name:=百度一下,你就知道").Page("title:=百度一下,你就知道").Object.body.createTextRange()51Testing软件测试网)c)O^zMS:F

          b=a.text51Testing软件测试网%jfV5f?

          Set regEx=new RegExp

    Bv&R\-S5r4x138711

          regEx.Pattern=testStr51Testing软件测试网h)hC#dgp1^

          regEx.IgnoreCase=true

    FL"g3rL$C5KX138711

          regEx.Global=true

    ,n,yd4`#Y:q138711

          Set Matches=regEx.Execute(b)

    f[g;M*d138711

           For Each Match in Matches     'Matches集合进行迭代。

    $D;KU9E ~DV|c138711

                 RetStr = Match.Value

    C3T+ARL'~*g;r WN"k138711

                 msgbox RetStr51Testing软件测试网j ^7VdH/e

           Next51Testing软件测试网Rb&rv,fMx?4[

    End Sub51Testing软件测试网ySXh`iy.WZ)L)l9T^

    以上代码实现通过Object和正则表达式在页面上查找字符串功能。51Testing软件测试网/[P ~"gP

     

    Z7i'\h'MB138711

    代码251Testing软件测试网D,pT i N+}1{

    Browser("百度一下,你就知道").Page("百度一下,你就知道").WebButton("百度一下").Object.setAttribute "value","我的搜索"51Testing软件测试网8i @+@)H0?1s\g9X

        这句代码通过ObjectsetAttribute修改运行时按钮的value值。运行一下看看效果。运用场景:输入框需要单击激活输入状态,通过QTP脚本不能激活,此时可以通过修改运行对象的属性将其激活。


     

  • (转)web_custom_request应用示例

    2009-03-26 17:18:38

    LoadRunner提供的web_custom_request函数可以用于实现参数的动态生成。在LoadRunner中,web_reg_save_param和custom_request都常于处理参数的动态生成。

    web_reg_save_param函数是大家都已经熟悉的了,它的主要作用是从一个response中获得后续的request需要使用的数据,然后将其作为一个参数保存下来,供后续步骤使用。该方法在LoadRunner中被称为Correlation(关联)。

    而web_custom_request函数则可以用于完全自定义向服务端发送的request。

    接下来我们用一个实际的例子说明一下web_custom_request的具体应用:

    以Mercury自带的MercuryWebTours例子为例,假设我们希望在登录进入后将用户的前两条记录删除,我们来看看用web_custom_request如何实现这个目标。

    首先,我们尝试用HTML方式对该操作进行录制。录制后的脚本中与删除相关的部分大致如下:

    web_url("welcome.pl",
        
    "URL=http://localhost/MercuryWebTours/welcome.pl?page=itinerary",
            
    "Resource=0",
            
    "RecContentType=text/html",
        
    "Referer=http://localhost/MercuryWebTours/nav.pl?page=menu&in=home",
        
    "Snapshot=t3.inf",
        
    "Mode=HTML",
        EXTRARES,
        
    "URL=images/in_itinerary.gif""Referer=http://localhost/MercuryWebTours/nav.pl?page=menu&in=itinerary", ENDITEM,
        
    "URL=images/home.gif""Referer=http://localhost/MercuryWebTours/nav.pl?page=menu&in=itinerary", ENDITEM,
            LAST);
    lr_think_time(
    2);

    web_submit_form(
    "itinerary.pl",
        
    "Snapshot=t4.inf",
        ITEMDATA,
        
    "Name=1""Value=on", ENDITEM,
        
    "Name=2""Value=on", ENDITEM,        "Name=removeFlights.x""Value=116", ENDITEM,
        
    "Name=removeFlights.y""Value=8", ENDITEM,
        LAST);

    我们通过树型模式查看一下在submit form的时候实际向服务器发出的请求的内容:

    从请求内容中可以看到,我们通过POST方法发出了请求,请求发送的目的URL是/MercuryWebTours/itinerary.pl,发送的内容是:
    "1=on&flightID=384-798-JM&2=on&flightID=3026-1592-JM&3=on&flightID=1194-2326-JM&.cgifields=1&.c"
    "gifields=2&.cgifields=3&removeFlights.x=116&removeFlights.y=8"

    从发送的内容中可以很明显的分析得出,1=on表示第一个checkbox是被选中的,flightID=384-798-JM表示的是第一条记录所对应的flightID。因此,如果我们需要自己组成这个发送的request的话,必须首先通过关联的方式获得前两条记录的flightID,然后再组成request的内容。

    web_custom_request方法的原型是:
    int web_custom_request (const char *RequestName, <List of Attributes>,[EXTRARES, <List of Resource Attributes>,] LAST );

    其中List of Attributes的主要项目是Method,URL和BODY等。对这个例子来说,我们可以很容易构造出我们需要的request的BODY内容。
    ……
     strcpy(creq, "Body=1=on&flightID=");
     strcat(creq, lr_eval_string("{fID1}"));
     strcat(creq, "&2=on&flightID=");
     strcat(creq, lr_eval_string("{fID2}"));
     strcat(creq, "&.cgifields=1&.cgifields=2");
     strcat(creq, "&removeFlights.x=116&removeFlights.y=8");
    ……

    其中{fID1}、{fID2}等都是通过关联获得的flightID的数据。

    因此,我们可以根据图中的数据编写custom_request语句:

    web_custom_request("itinerary.pl",
    "Method=POST"
        
    "URL=http://localhost/MercuryWebTours/itinerary.pl",
        
    "RecContentType=text/xml",
        creq,
        
    "Snapshot=t4.inf",
        LAST);

    较为完整的代码如下:
    Action()
    {
        
    char creq[500];

        web_reg_save_param(
    "fID1""LB=INPUT TYPE=\"hidden\" NAME=\"flightID\" VALUE=\"""RB=\"""ORD=1"
            
    "SEARCH=BODY", LAST);
        web_reg_save_param(
    "fID2""LB=INPUT TYPE=\"hidden\" NAME=\"flightID\" VALUE=\"""RB=\"""ORD=2"
            
    "SEARCH=BODY", LAST);
        web_url(
    "welcome.pl",
            
    "URL=http://localhost/MercuryWebTours/welcome.pl?page=itinerary",
            
    "Resource=0",
            
    "RecContentType=text/html",
            
    "Referer=http://localhost/MercuryWebTours/nav.pl?page=menu&in=home",
            
    "Snapshot=t3.inf",
            
    "Mode=HTML",
            EXTRARES,
            
    "URL=images/in_itinerary.gif""Referer=http://localhost/MercuryWebTours/nav.pl?page=menu&in=itinerary", ENDITEM,
            
    "URL=images/home.gif""Referer=http://localhost/MercuryWebTours/nav.pl?page=menu&in=itinerary", ENDITEM,
            LAST);
        lr_think_time(
    2);

        strcpy(creq, 
    "Body=1=on&flightID=");
        strcat(creq, lr_eval_string(
    "{fID1}"));
        strcat(creq, 
    "&2=on&flightID=");
        strcat(creq, lr_eval_string(
    "{fID2}"));
        strcat(creq, 
    "&.cgifields=1&.cgifields=2");
        strcat(creq, 
    "&removeFlights.x=116&removeFlights.y=8");

        lr_output_message(creq);

        web_custom_request(
    "itinerary.pl",
    "Method=POST"
            
    "URL=http://localhost/MercuryWebTours/itinerary.pl",
            
    "RecContentType=text/xml",
            creq,
            
    "Snapshot=t4.inf",
            LAST);

        
    return 0;
    }
Open Toolbar