发布新日志

  • 冒泡排序

    2012-05-26 22:45:51

    package xiti;
    import java.applet.*;
    import java.util.Random;
     class ti2 extends Applet {
      ti2()
      {
       int t;
       Bubble test= new Bubble(10);
       test.inserNum(1);
       test.inserNum(0);
       test.inserNum(9);
       test.inserNum(-1);
       test.inserNum(100);
       test.inserNum(3);


       test.dispaly();
       test.order();
       test.dispaly();
      
      
      }

    }
    class Bubble{
     int[] nums;
     int no;
     Bubble(int len)
     {
      nums=new int[len];
      no=0;
     }
     
     void inserNum(int value)
     {
      nums[no]=value;
      no++;
     }
     
     void order()
     {
      int temp;
      for(int i=0; i<no; i++)
      {
       for(int j=0;j<no-i-1;j++)
       {
        if(nums[j]>nums[j+1])
        {
         temp=nums[j+1];
         nums[j+1]=nums[j];
         nums[j]=temp;
       
        }
       }
      }
     }
     
     void dispaly()
     {
      for(int i=0;i<no;i++)
      {
       System.out.println(nums[i]+"-----");
      }
     }
     
     void delete(int value)
     {
      order();
      for(int i=0;i<no;i++)
      {
       if(nums[i]==value)
       {System.out.print("find value");
          for(int j=i;j<no;j++)
          {
           nums[j]=nums[j+i];
          
          }
          no--;
       }
      }
      
     }
    }

  • 在数组,通过二分法插入数据

    2012-05-24 22:15:52

    package xiti;

    class ti3
    {
     int[] arr;  //要排列的数据
     int no;  //存在数据的个数
     ti3(int n)
     {
      arr=new int[n];
      no=0;
     }
     void insert(int value,int lowBound, int upperBound)
     {
      //数据为空的时候插入数据
      if(no==0){arr[0]=value;no++; return ;}
      
      //插入的数据 比最大的数据还大
      if(value>=arr[no-1]){arr[no]=value;no++;return ;}
      
      //插入的数据 比最小的数据还小
      if(value<=arr[0]){
       for (int i=no;i>0;i--)
       {
        arr[i]=arr[i-1];
        
       }
       arr[0]=value;
       no++;
       return ;
       }
      
      
      //插入的数据 鉴于原来数据的最大数值和最小数值之间
      int mid = (upperBound+lowBound)/2;
      if((arr[mid-1]<=value)&& (value<arr[mid])){
       
       for (int i=no;i>mid;i--)
       {
        arr[i]=arr[i-1];
        
       }
       arr[mid]=value;
       
       no++;
       return ;
      }
       
      if(value>=arr[mid])
       insert(value, mid+1,  upperBound);
      else
       insert(value, lowBound,  mid);
       
      
     }
     //显示数据
     void display()
     {
      
      for(int i=0 ;i<=no;i++)
       System.out.print(arr[i]+"\n");
     }
    }

  • java 数组结构 20120521

    2012-05-21 22:36:15

    package xiti;
    import java.applet.*;
     class ti2 extends Applet {
      ti2()
      {
       HighArray muns=new HighArray(20);
       int maxLen=20;
       for(int i=0;i<10;i++)
        muns.insert(i);
       muns.display();
       if(muns.find(9)) System.out.print("OK");
       muns.delete(6);
       muns.delete(8);
       muns.delete(13);
       muns.display();
      
      }

    }
    class HighArray{
     int[] nos;
     int len;
      HighArray(int len)
     {
      nos = new int[len];
      len=0;
     }
     Boolean find(int searchItme)
     {
      int i;
      Boolean temp;
      temp=false;
      for(i=0;i<len;i++)
      {
       if(searchItme==nos[i])
       {
        temp = true;    
       }   
      }
      return temp;  
     }
     void insert(int value){
      nos[len]=value;
      len++;
     }
     Boolean delete(int value)
     {  int i,j;
        Boolean temp=false;
        for (i=0;i<len;i++)
        {
         if(nos[i]==value)
          {
            temp=true;
            break;
          }     
        }
        if(temp){
         for (j=i;j<len;j++)
         {
          nos[j]=nos[j+1];
            
         }
        }
        return temp;
      
     }
     void display()
     {
      for(int i=0;i<len;i++)
      {
       System.out.print(nos[i]+"");
      }
      
     }
    }

  • 转载新手asp编程的基本法则

    2012-05-07 17:00:29

    新手asp编程的基本法则 [新手必看] 2009-6-17 更新
    http://bbs.bccn.net/thread-217539-1-1.html
    一、新手常犯的错误
    在论坛看到很多帖子代码中都有一个共同的基本错误,字段类型错误。
    程序和数据库是紧紧相连的,数据库字段文本型或时间型的都使用单引号
    比如下面这段修改语句:
    conn.execute "update Counts set counts='"&counts&"' where num="&num&" and Atime='"&now()&"'"
    等号左边都是字段名,等号右边是传值过来的变量名,counts 字段是文本型,所以写入时必须前后加单引号,无论是写入还是查询都一样,后面的查寻语句中,num 字段是数字型,所以前后就没有单引号了,Atime 字段是时间型所以前后也要加单引号。
    最重要的是以ID查询,ID字段是唯一的并且数字类型,很明显查询ID号时前后也不能有单引号
    conn.execute "update Counts set counts='"&counts&"' where id='"&id&"'"  '错误写法
    conn.execute "update Counts set counts='"&counts&"' where id="&id  '正确写法

    二、ACCESS 数据库连接
    通常数据库连接有两种方式,新手基本不知道用哪一种方式,或者在什么情况下用哪一种,又或者不知道两者的原理
    ①直接连接数据库文件
    Set conn = Server.CreateObject("ADODB.Connection")
    conn.Open "DRIVER={Microsoft Access Driver (*.mdb)}; DBQ="&Server.MapPath("database/yanhang.mdb")

    ②通过数据源来连接数据库文件
    Set conn = Server.CreateObject("ADODB.Connection")
    conn.Open "Provider=Microsoft.Jet.OLEDB.4.0; Data Source="&Server.MapPath("database/yanhang.mdb")

    那么,两者到底哪一个好呢,当然是第二种,因为第一种其实就是客户端浏览器直接读取数据库的,所以安全方面差很多,第二种通过数据源连接,是以服务器数据源工具连接的,与客户端没关系,所以数据库不会暴露给客户端,安全系数高很多。

    ACCESS 数据库对应程序的应用:①直接连接数据库文件
    conn.Open "DRIVER={Microsoft Access Driver (*.mdb)}; DBQ="&Server.MapPath("database/yanhang.mdb")
    这样的数据库连接方式,添加语句:
    set rs=server.createobject("adodb.recordset")   '(正确写法)
    rs.open "select * from dndj",conn,1,3
    rs.addnew
    rs("bh") = bh
    rs("bm") = bm
    rs("xm") = xm
    rs("xsq") = xsq
    rs.update
    rs.close
    set rs=nothing

    set rs=server.createobject("adodb.recordset")  '(错误写法)
    sql="insert into dndj(bh,bm,xm,xsq) values('bh','bm','xm','xsq')"
    rs.open sql,conn,1,3

    ACCESS 数据库对应程序的应用:②通过数据源来连接数据库文件
    conn.Open "Provider=Microsoft.Jet.OLEDB.4.0; Data Source="&Server.MapPath("database/yanhang.mdb")
    这样的数据库连接方式,添加语句:
    conn.execute "insert into dndj(bh,bm,xm,xsq) values('"&bh&"','"&bm&"','"&xm&"','"&xsq&"')"    '(正确写法)

    set rs=server.createobject("adodb.recordset")  '(错误写法)
    sql="insert into dndj(bh,bm,xm,xsq) values('bh','bm','xm','xsq')"
    rs.open sql,conn,1,3

    三、双引号的应用
    通常我们写超级连接这样 <a href="abc.asp?id=<%=rs("id")%>">超级连接</a>
    但要是把这个超级连接编译进asp里面呢
    response.write "<a href=""abc.asp?id="&rs("id")&""">超级连接</a>"   '(正确写法)
    response.write "<a href='abc.asp?id="&rs("id")&"'>超级连接</a>"       '(正确写法)
    response.write "<a href=abc.asp?id="&rs("id")&">超级连接</a>"        '(正确写法)

    response.write "<a href="abc.asp?id=<%=rs("id")%>">超级连接</a>"  '(错误写法)
    response.write "<a href="abc.asp?id="&rs("id")&"">超级连接</a>"       '(错误写法)

    表单编译进asp里  <input type="text" name="id" value="<%rs("id")%>" />
    response.write "<input type=""text"" name=""id"" value="""&rs("id")&""" />" '(正确写法) 注意:这里有三个双引号
    response.write "<input type='text' name='id' value='"&rs("id")&"' />"       '(正确写法)
    response.write "<input type=text name=id value="&rs("id")&" />"            '(正确写法)

    response.write "<input type="text" name="id" value="<%=rs("id")%>" />"  '(错误写法)
    response.write "<input type="text" name="id" value=""&rs("id")&"" />"       '(错误写法)

    四、防止ACCESS数据库被下载的几个方法
    很多动态站点大量应用了数据库,数据库理所当然成了一个站点的核心文件。一旦数据库被非法下载,极有可能被恶意人士破坏网站。或者窃取资料。

    下面提供的方法分别适用使用虚拟主机空间的用户和有IIS控制权的用户!

       一:购买虚拟主机空间的,适合没有IIS控制权
    1:发挥你的想象力 修改数据库文件名
    这个是最基本的。我想现在也没有多少连数据库文件名都懒得改的人吧? 至于改成什么,你自己看着办,至少要保证文件名复杂,不可猜测性。当然这个时候你的数据库所在目录是不能开放目录浏览权限的!

    2:数据库名后缀改为ASA、ASP等
    这个听说很流行,不过我测试了好多次,发现并不理想,如果真正要起到防止下载的作用,要进行一些二进制字段添加等设置,一句话,繁而复杂(如果你的数据库有很多的话,这个方法实在不是很好)

    3:数据库名前加“#”
    只需要把数据库文件前名加上#、然后修改数据库连接文件(如conn.asp)中的数据库地址。原理是下载的时候只能识别 #号前名的部分,对于后面的自动去掉,比如你要下载:http://bbs.bccn.net/date/#123.mdb (假设存在的话)。无论是IE还是FLASHGET等下到的都是 http://bbs.bccn.net/date/index.htm

    今天来看到57楼的兄弟说前面加“#”根本就是垃圾,后来测试了下
    使用%23的确能下载:http://bbs.bccn.net/date/[color=red]%23
    123.mdb
    后来我研究了下,中间加空格的浏览器自动编译成 %20 也是能够下载的
    最后索性都不用,我就使用#+空格的编译码 %23%20.mdb 作为数据库名字
    http://bbs.bccn.net/date/%23%20.mdb
    经过测试,使用迅雷和普通的下载工具都不能下载[/color]

    4:加密数据库
    用ACCESS将你的数据库以独占方式打开后,在工具-安全-设置数据库密码,加密后要修改数据库连接页, 如:
    conn.open "driver={microsoft access driver (*.mdb)};uid=admin;pwd=数据库密码;dbq=数据库路径"
    这样修改后,数据库即使被人下载了,别人也无法打开(前提是你的数据库连接页中的密码没有被泄露)
    但值得注意的是,由于Access数据库的加密机制比较简单,即使设置了密码,解密也很容易。该数据库系统通过将用户输入的密码与某一固定密钥进行“异或”来形成一个加密串,并将其存储在*.mdb文件从地址“&H42”开始的区域内。所以一个好的程序员可以轻松制作一个几十行的小程序就可以轻松地获得任何Access数据库的密码。因此,只要数据库被下载,其安全依然是个未知数。


      二:有主机控制权 (当然虚拟空间的设置在这里依然可以用)
    5:数据库放在WEB目录外
    如你的WEB目录是e:\webroot,可以把数据库放到e:\data这个文件夹里,在e:\webroot里的数据库连接页中
    修改数据库连接地址为:"../data/#123 456.mdb" 的形式,这样数据库可以正常调用,但是无法下载的,因为它不在WEB目录里!这个方法一般也适合购买虚拟空间的用户。

    6:使用ODBC数据源。
    在ASP等程序设计中,如果有条件,应尽量使用ODBC数据源,不要把数据库名写在程序中,否则,数据库名将随ASP源代码的失密而一同失密
    例如:
    conn.open "driver={Microsoft Access Driver (*.mdb)};dbq="&Server.MapPath("../123/abc/asfadf.mdb")
    可见,即使数据库名字起得再怪异,隐藏的目录再深,ASP源代码失密后,也很容易被下载下来。
    如果使用ODBC数据源,就不会存在这样的问题了:conn.open "ODBC-DSN名" ,不过这样是比较烦的,目录移动的话又要重新设置数据源了!

    7:添加数据库名的如MDB的扩展映射
    这个方法就是通过修改IIS设置来实现,适合有IIS控制权的朋友,不适合购买虚拟主机用户(除非管理员已经设置了)。这个方法我认为是目前最好的。只要修改一处,整个站点的数据库都可以防止被下载。无须修改代码即使暴露目标地址也可以防止下载。

    设置:
    在 IIS属性---主目录---配置---映射---应用程序扩展那里添加.mdb文件的应用解析。注意这里的选择的DLL(或EXE等)似乎也不是任意的,选择不当,这个MDB文件还是可以被下载的,  注意最好不要选择选择asp.dll等。你可以自己多测试下
    这样修改后下载数据库如:http://bbs.bccn.net/data/dvbbs6.mdb。就出现(404或500等错误)

    8:使用.net的优越性
    动网的木鸟就写过一个防非法下载文件的“WBAL 防盗链工具”。记得本论坛曾经也有位牛人也发表过数据库防下载的插件,是.dll的加载到IIS里的。
    不过 那个只实现了防止非本地下载的 ,没有起到真正的防下载数据库的功能。不过这个方法跟第5种差不多
    可以通过修改.NET文件,实现本地也不能下载!

    这几个方法中,只有第7和8个是统一性改的,一次修改配置后,整个站点的数据库都可以防止下载,其他几个就要分别修改数据库名和连接文件,比较麻烦,不过对于虚拟主机的朋友也只能这样了!

    其实第6种方法应该是第5种方法的扩展,可以实现特殊的功能,但对于不支持.net的主机或者怕设置麻烦的话,还是直接用第5种方法了,而且默认情况下第6种方法,依然可以通过复制连接到同主机的论坛或留言本发表,然后就可以点击下载了(因为这样的引用页是来自同主机的)

    这几个方法各有长短,请自己选择性地使用。这些方法也不是绝对的安全,还需要网站管理员平时注意一些系统的安全,以及写ASP代码本身的安全 ,否则依然有可能被人下载或者修改数据库!


    字符串截取的四个函数
    一、如果只截取前几位,使用left
    二、如果只截取后几位,使用right
    三、如果只截取中间几位,使用mid
    四、分隔符截取,使用split

    一、left 截取前3位:得到 ABC
    <%
    dd="ABCDEFGH"
    response.write left(dd,3) '从第1位向后数到第3位
    %>

    二、right 截取后3位,得到 FGH
    <%
    dd="ABCDEFGH"
    response.write right(dd,3) '从最后1位向前数到第3位
    %>

    三、mid 截取中间3位,得到 DEF
    <%
    dd="ABCDEFGH"
    response.write mid(dd,4,3) '从第4位开始向后数到第3位
    %>

    四、split 截取分隔符前后的内容,得到 AB CD EF GH
    <%
    dd="AB|CD|EF|GH"
    response.write split(dd,"|")(0)   '得到内容是 AB
    response.write split(dd,"|")(1)   '得到内容是 CD
    response.write split(dd,"|")(2)   '得到内容是 EF
    response.write split(dd,"|")(3)   '得到内容是 GH

    '可以写成循环语句来将分隔符左右的内容一一显示出来
    for i=0 to 3
        response.write split(dd,"|")(i)&"<br/>"
    next

    '单独调用指定分隔符位置的内容
    dim dm(3)  '定义一个循环变量
    for i=0 to 3
        dm(i)=split(dd,"|")(i)
    next

    response.write dm(0)   '得到内容是 AB
    response.write dm(1)   '得到内容是 CD
    response.write dm(2)   '得到内容是 EF
    response.write dm(3)   '得到内容是 GH

    '如果不确定 dd 里有多少个分隔符,使用循环参数的时候 to 后面的数字就不能直接写了,需要统计分隔符的数量
    for i=0 to UBound(split(dd,"|"))
        dm(i)=split(dd,"|")(i)
    next
    %>

    今天来说说SQL数据库的连接方式:
    ①SQL2000数据库本地连接
    Set conn=Server.CreateObject("ADODB.Connection")
    conn.open "provider=sqloledb;server=(local);database=数据库名;uid=用户名;pwd=密码;"

    ②SQL2000数据库远程连接
    Set conn=Server.CreateObject("ADODB.Connection")
    conn.open "provider=sqloledb;server=200.200.200.200,1433;database=数据库名;uid=用户名;pwd=密码;"

    ③SQL2005数据库本地连接
    Set conn=Server.CreateObject("ADODB.Connection")
    conn.open "provider=SQLNCLI;server=(local);database=数据库名;uid=用户名;pwd=密码;"

    ④SQL2005数据库远程连接
    Set conn=Server.CreateObject("ADODB.Connection")
    conn.open "driver={sql server};server=200.200.200.200,1433;database=数据库名;uid=用户名;pwd=密码;"

    今天来写一下ASP入门与解说
    无论是哪种编程语言不外乎就这几种功能
    1.读取
    2.添加
    3.修改
    4.删除
    5.查询
    6.统计
    只要将这几种功能运用自如,那么,你就已经会这门语言了

    首先我们谈谈数据库:
    一般ASP使用 ACCESS 和 SQL 数据库
    初学者最好先使用 ACCESS 数据库,装个 OFFIEC 就已经自带 ACCESS 数据库了
    ACCESS 版本从 ACCESS98 → ACCESS2000 → ACCESS2003 → ACCESS2007
    安装什么版本的 OFFIEC 就是什么版本的 ACCESS

    SQL数据库是微软的产品,目前一般使用的SQL数据库为 SQL2000 → SQL2005

    ASP读取数据:
    <%
    Set rs=Server.CreateObject("ADODB.Recordset")
    rs.open "select * from 表名 order by id desc",conn,1,1
      'order by用来排序 id为排序字段,desc为倒序,asc为顺序,1,1为只读,1,3为可操作
    do while not rs.eof            '循环开始
       response.write rs("abc")      '显示数据
    rs.movenext            '循环下一条数据
    loop
    rs.close            '关闭rs记录
    set rs=nothing            '清除rs记录集
    %>
    瞧,读取数据就这么简单



    ASP添加新数据
    第一种添加方式代码:
    <%
    Set rs=Server.CreateObject("ADODB.Recordset")
    rs.open "select * from 表名",conn,1,3
       '这里添加新数据就不需要排序了,1,3上面我们已经说了,是可对数据库操作的意思
    rs.addnew            '开始新数据
    rs("字段1")="123456"     '将数据添加到字段1
    rs("字段2")="123456"     '同上
    rs.update        '开始向数据库写入
    rs.close        '关闭rs记录
    set rs=nothing        '清除rs记录集
    %>
    这种添加方式适合ACCESS和SQL数据库的任何方式连接
    下面这个添加语句只适合ACCESS的第②种连接方式,同时也适合SQL数据库任何方式连接
    第二种添加方式代码:
    <%
    conn.execute "insert into 表名(字段1,字段2) values('123456','123456')"
    '两个括号中要一一对应,多个内容添加用逗号隔开
    %>
    上面这段添加语句唯一不支持ACCESS第①种数据库连接方式
    瞧,添加数据我们也学会了



    ASP修改数据:
    ASP修改数据多数用在查询指定的数据然后去修改那条数据
    第一种修改方式代码:
    <%
    Set rs=Server.CreateObject("ADODB.Recordset")
    rs.open "select * from 表名 where id=10",conn,1,3
      'where为查询开始,查询条件为id等于10的那条数据
    rs("字段1")="123456"      '无论字段1中是什么值,我们都把它改成123456这个值
    rs("字段2")="123456"      '同上
    rs.update        '开始向数据库写入
    rs.close        '关闭rs记录
    set rs=nothing        '清除rs记录集
    %>
    瞧,修改与添加不同的是少了个rs.addnew,多了个查询条件,其它完全相同
    第二种修改方式代码:
    <%
    conn.execute "update 表名 set 字段1='123456',字段2='123456' where id=10"
    '多个内容修改用逗号隔开
    %>
    上面这段修改代码和上面的添加一样唯一不支持ACCESS第①种数据库连接方式



    ASP删除数据:
    删除数据也用到查询,如果没有查询,那就是将整个表中的所有内容全部删除了,如果你只需要删除其中一条,那就必须使用查询条件
    <%
    conn.execute "delete 表名 where id=10"
      '查询到id值等于10的那条数据并且删除
    %>
    如果是ACCESS数据库就要加上from,例如:
    <%
    conn.execute "delete
    from 表名 where id=10"
    %>

    瞧,这个删除语句就这么简短,它和上面读取,添加,修改语句有所不同



    如果你的数据库连接使用的是ACCESS第②种方式或者使用的是SQL数据,那么添加,修改,删除用起来就很简单了,像下面这样

    添加:conn.execute "insert into 表名(字段1,字段2) values('123456','123456')"
    修改:conn.execute "update 表名 set 字段1='123456',字段2='123456' where id=10"
    删除:conn.execute "delete 表名 where id=10"

    看起来是不是很清爽



    记住,在读取,添加,修改,删除,这四个功能之中只有添加不能带有查询条件,其他三个根据自己的需要可以带查询条件
    一、查询条件可以多个条件
    例如:conn.execute "delete 表名 where 字段1='123456' and 字段2='123456' and id=10" 之间用and隔开,and前后一定要空格
          意思是这三个条件必须同时满足才能查询出你想要的结果

    二、查询条件可以使用or或者的意思
    例如:conn.execute "delete 表名 where 字段1='123456' or 字段2='123456' or id=10" 之间用or隔开,or前后一定要空格
          意思是只要查询的条件满足其中之一就能查询出你想要的结果

    三、查询条件还可以使用and和or同时使用
    例如:conn.execute "delete 表名 where (字段1='123456' or 字段2='123456') and id=10"
          意思是只要查询条件满足 字段1 或者 字段2 中的一条,并且id等于10的条件,注意:括号要括起来

    以上三种查询条件适合读取,修改,删除三个功能



    统计使用函数sum,recordcount
    统计价格:sum
    <%
    Set rs=Server.CreateObject("ADODB.Recordset")
    rs.open "select sum(价格字段) as price from 表名 order by id desc",conn,1,1
      'as就是将统计出来的结果赋值给临时变量price
       response.write rs("price")      '显示统计出来的总价格

    rs.close
    set rs=nothing
    %>


    统计总数量:recordcount
    <%
    Set rs=Server.CreateObject("ADODB.Recordset")
    rs.open "select * from 表名 order by id desc",conn,1,1
       response.write rs.recordcount
          '显示统计出来的总条数

    rs.close
    set rs=nothing
    %>


    代码是死的,人的大脑是灵活的,就要看你如何去灵活运用吧!

    下面我们来说说字段为空的判断:
    字段为空有两种,一种是默认值设置为字符的比如SQL数据库字段默认值可以填写 N''
    另一种默认值为空的,字段显示内容为 null 的
    平时我们查询判断字段为空的把两种空都写上
    查询所有为空的字段:
    <%
    Set rs=Server.CreateObject("ADODB.Recordset")
    rs.open "Select * from 表名 where abc='' or abc is null",conn,1,1
    %>

    查询所有不为空的字段:
    <%
    Set rs=Server.CreateObject("ADODB.Recordset")
    rs.open "Select * from 表名 where abc<>'' or is abc not null",conn,1,1
    %>


    那么在读取字段的时候判断是否为空的:
    <%
    if isnull(rs(字段名))=true or rs(字段名)="" then
        'true表示为空
    else
        'false表示不为空
    end if

    if rs(字段名) is null or rs(字段名)="" then
        '表示为空
    else
        '表示不为空
    end if

    if not rs(字段名) isnull or rs(字段名)<>"" then
        '表示不为空
    else
        '表示为空
    end if
    %>


    数据库多表连接查询
    学习数据库查询的时候对多表连接查询的有些概念还比较模糊。而连接查询是在数据库查询操作的时候肯定要用到的。对于此概念,我用通俗一些的语言和例子来进行讲解。
    首先我们做两张表:员工信息表和部门信息表,在此,表的建立只为讲述连接的概念,所以字段非常的简单
    eTB(员工信息表):
    eid   ename tid
    0001  张三  01
    0002  李四  01
    0003  王五  02
    0004  赵六  02
    0005  郑七  NULL

    tTB(部门信息表)
    tid tname
    01  技术部
    02  市场部
    03  工程部

    我们现在需要进行连接查询,连接两张表检索数据。分别检索员工信息表的员工编号、员工姓名和部门信息表中的部门名称。
    显然,两个表的连接条件是 员工表的部门编号=部门表的部门编号
    注意:郑七不属于任何部门(新来的员工,还没有分配到任何的部门),而工程部不存在任何的员工(比如是一个新成立的部门,还没有员工)
    1、内连接查询
    我们可以有两种方式,这两种是等效的
    一种是:Select e.eid,e.ename,d.tname from eTB as e,tTB as d where e.tid=d.tid
    二种是:Select e.eid,e.ename,d.tname from eTB as e inner join tTB as d on e.tid=d.tid
    检索的结果都是:
    eid   ename tname
    0001  张三  技术部
    0002  李四  技术部
    0003  王五  市场部
    0004  赵六  市场部

    而“郑七”和“工程部”的信息是不会检索出来。因为采用内连接计算的时候必须要保证连接的条件e.tid=d.tid匹配,结果才会被检索出来。当我们连接两张检索数据的时候,检索的方式是首先逐行扫描“员工信息表”中的记录,然后根据连接条件来决定此记录是否被检索。比如对于张三,这条记录的tid是01(部门编号),它在部门表中能找到和它匹配的编号01,而编号01的部门名称(tname)是“技术部”所以张三这条记录会被检索,最终的结果肯定是:

    0001  张三  技术部

    同样,李四、王五、赵六也能。但是郑七的部门编号是NULL,它在部门信息表中找不到匹配的项(因为部门信息表中不存在部门编号为NULL的部门),所以郑七不会被检索。
    同理,没有任何人员的部门编号为03,所以工程部的记录也不会被检索

    2、左外联结
    但是有些情况下,我们需要知道所有员工的信息,即使他不属于任何部门。这样我们就可以采用外连接,在这里为左外连接,也就是连接中的左表的表中的记录,无论能不能在右表中找到匹配的项,都要检索,如果没有匹配的项目,那么右表中的字段值为NULL(空),在这里就代表,此员工不属于任何部门。
    检索语句为:Select e.eid,e.ename,d.tname from eTB as e left outer join tTB as d on e.tid=d.tid
    检索的结果都是:
    eid   ename tname
    0001  张三  技术部
    0002  李四  技术部
    0003  王五  市场部
    0004  赵六  市场部
    0005  郑七  NULL

    但是在这里,工程部同样不会被检索,因为,tname是在连接的右边的表中,“工程部”在左表中不存在任何的记录,所以不会被检索。这里关注的是“连接中的左边的表”


    3、右外连接
    有时,我们需要知道,全部部门的信息,即使它没有任何的员工。在我们的查询中部门表在连接的右边,如果我们想知道右边表中的所有记录信息,那么就可以采用右外连接,如果此记录在左边的表中找不到匹配项,则相应字段(eid,ename)为NULL
    检索语句为:Select e.eid,e.ename,d.tname from eTB as e right outer join tTB as d on e.tid=d.tid
    检索的结果都是:
    eid   ename tname
    0001  张三  技术部
    0002  李四  技术部
    0003  王五  市场部
    0004  赵六  市场部
    NULL  NULL  工程部

    但在这里,郑七是不会被检索了,因为它在右表中找不到匹配项,这里关注的是“连接中的右边的表”

    4、完全外连接
    如果我们想知道所有的记录呢?无论员工有没有部门,部门有没有员工,我们都需要检索。这里就可以使用完全外连接。关注连接中的两部分。如果没有部门,部门为空,没有员工,员工信息为空。
    检索语句为:Select e.eid,e.ename,d.tname from eTB as e full outer join tTB as d on e.tid=d.tid
    检索的结果都是:
    eid   ename tname
    0001  张三  技术部
    0002  李四  技术部
    0003  王五  市场部
    0004  赵六  市场部
    0005  郑七  NULL
    NULL  NULL  工程部

    经常看到有新手来问如何接收传送的值
    下面我来详细的说一下接收传送值的多种方式
    获取传送值通常使用三种方式来获取
    id=Request("id") '可以是post或get方式传送的值
    id=Request.Form("id") '只能post方式传送的值
    id=Request.Querystring("id") '只能get方式传送的值

    从表单提交的方式传送的通常使用post方式传送
    例如:
    <form. action="abc.asp" method="post">
    <input type="text" name="Uname" />
    <input type="text" name="Pass" />
    <input type="submit" name="submit" value="提交" />
    </form>
    表单形式的提交通常 method属性值为post的,当然我们也可以改成 method="get",这样提交过去会自动在地址栏显示传送的值了,例如:http://bbs.bccn.net/abc.asp?Uname=hmhz&Pass=123456
    多个参数传送用 & 符号分隔,格式如上

    从地址栏传送的都为get方式传送
    get传送形式上面已经写了,但get方式不一定非得使用表单来传送,我们可以使用超连接,或用JS传送均可以
    例如:
    <a href="abc.asp?id=<%=rs("id")%>">删除</a>
    <a href="javascript.:location.href='abc.asp?id=<%=rs("id")%>'>删除</a>
    <a href="javascript.:void(0);" nclick="location.href='abc.asp?id=<%=rs("id")%>'">删除</a>

    如果一个页面很有可能会post方式提交来的参数,也有可能以get方式传送的,那我们可以使用第一种接收方式
    id=Request("id")
    就行了,如果这个值只有一种方式传送的,那最好使用对应的接收方式,因为这样接收效率才会提高,也在安全上加了道门槛

  • asp onclick必须是服务端的函数

    2012-05-07 16:56:49

    asp的onclick 必须是<script></script>的函数不可以是<%%>的函数
     
    如:http://127.0.0.1/index.asp?firsttype=a&secondtype=b
    这样可以传递两个参数
    接收的时候就:
    request("firsttype")
    request("secondtype")
  • asp中调用.vbs文件

    2012-05-02 10:44:37

    <HTML>
    <HEAD>
    调用vbs
    </HEAD>
    <BODY>
    <script. language="VBScript" type="text/VBScript" src="testf.vbs"></script>
    </BODY>
    </HTML>
  • QTP连接oracle并操作数据库的方法(转载)

    2012-04-28 13:55:05

    QTP连接oracle并操作数据库的方法这里以oracle  9i为例子,其他的数据库连接方法是相通的。

    a.首先要在本机建议ODBC数据源,这个属于基本操作,这里不讲,跳过;
    b.获取oracle的连接串的方法,在本地新建一个.txt文件,修改扩展名名*.udl,双击*.udl文件,打开数据库链接属性,定位到“提供程序”选显卡,选中 oracle的连接  oracle provider for OLE DB,点击下一步,输入数据源,数据库用户名以及密码,点击测试连接,然后用UE或记事本打开*.udl文件,oracle的连接串已经生成了,例如
    Provider=OraOLEDB.Oracle.1;Persist Security Info=False;User ID=test;Data Source=192.168.13.19

    以上就是udl文件生成的oracle连接串
    现在我们需要手动添加一个oracle连接串的密码字段Password,插入到User ID后面,中间用分号隔开;
    即 Provider=OraOLEDB.Oracle.1;Persist Security Info=False;User ID=test;;Password=test;Data Source=192.168.13.19

    c.在qtp中来连接数据库

    Dim Cnn  '定义一个数据库连接串
    Set Cnn = CreateObject("ADODB.Connection")
    Cnn.ConnectionString ="Provider=OraOLEDB.Oracle.1;Persist Security Info=False;User ID=test;Password=test;Data Source=192.168.13.19 "

    Cnn.Open   '打开数据库连接
    If Cnn.State = 0 Then      '判断数据库连接是否成功
         Reporter.ReportEvent micFail, "testing", "连接数据库失败"
    else
         Reporter.ReportEvent micPass, "testing",   "连接数据库成功"
    End If

     
    if Cnn.State<> 0  then
      
        Set Rs=CreateObject("ADODB.Recordset")    '生成记录集对象
     strsql ="Select    from t_sys_user"   '从数据库中查询t_sys_user的所有记录
            Rs.Open strsql ,Cnn,1,3   '执行sql语句,记录可以自由移动,单数记录处于只读模式
            ydl=Rs("USER_ID")         '取得字段为USER_ID的记录,游标定义在第一行,所以取得的是该字段所在行的第一行数据
     msgbox  ydl
            dim a
            a="1188"  '该a的数据库可以从外部获取,可以是某个页面的某个值,拿来跟数据库中的值做比较
       for  i=1  to  Rs.Recordcount   '开始遍历数据库中所有的行数,Rs.Recordcount表示统计数据库表的总记录数
            if    Rs("USER_ID")=a   then   '将数据库中USER_ID字段的值与变量a进行挨个比较,
               msgbox "a在数据库中存在"  
               exit for                        '如果找到记录a,则推出for循环      
               else
               Rs.MoveNext                      '如果数据库中的值与a不相等的话,那么在数据库中将游标移到下一行
            end  if
       
       next

     
    end if


    RS.close      '关闭记录集
    Set RS=nothing        '释放对象
    Cnn.Close   '关闭数据连接
    Set Cnn=nothing '释放对象


    另外,如果要判断游标是否到最好一行,则用
    For   i=1  to   Rs.Recordcount

     If     Rst.EOF  Then

          msgbox  "已经达到数据库最后一行记录"
     Exit   for
     else
     Rst.MoveNext

     End If

    Next


    、RecordSet对象的详细用法


    RecordSet对象(代表来自基本表或命令执行结果的记录的全集。)
    为了更精确地跟踪数据,要用RecordSet组件创建包含数据的游标,游标就是储存在内存中的数据:

      rs = Server.CreateObject("ADODB.RecordSet")

      rs.Open(sqlStr,conn,1,A)

    RS.OPEN SQL,CONN,A,B

    A:

    ADOPENFORWARDONLY(=0)
    只读,且当前数据记录只能向下移动

    ADOPENKEYSET(=1)
    只读,当前数据记录可自由移动

    ADOPENDYNAMIC(=2)
    可读写,当前数据记录可自由移动

    ADOPENSTATIC(=3)
    可读写,当前数据记录可自由移动,可看到新增记录

    B:

    ADLOCKREADONLY(=1)
    缺省锁定类型,记录集是只读的,不能修改记录

    ADLOCKPESSIMISTIC(=2)
    悲观锁定,当修改记录时,数据提供者将尝试锁定记录以确保成功地编辑记录。只要编辑一开始,则立即锁住记录。

    ADLOCKOPTIMISTIC(=3)
    乐观锁定 ,直到用Update方法提交更新记录时才锁定记录。

    ADLOCKBATCHOPTIMISTIC(=4)
    批量乐观锁定,允许修改多个记录,只有调用UpdateBatch方法后才锁定记录。

    当不需要改动任何记录时,应该使用只读的记录集,这样提供者不用做任何检测。
    对于一般的使用,乐观的锁定可能是最好的选择,因为记录只被锁定一小段时间,
    数据在这段时间被更新。这减少了资源的使用。

      在RecordSet组件中,常用的属性和方法有:

      rs.Fields.Count:RecordSet对象字段数。

      rs(i).Name:第i个字段的名称,i为0至rs.Fields.Count-1

      rs(i):第i个字段的数据,i为0至rs.Fields.Count-1

      rs("字段名"):指定字段的数据。

      rs.RecordCount:数据记录总数。

      rs.EOF:是否最后一条记录。

      rs.MoveFirst:指向第一条记录。

      rs.MoveLast:指向最后一条记录。

      rs.MovePrev:指向上一条记录。

      rs.MoveNext:指向下一条记录。

      rs.GetRows:将数据放入数组中。

      rs.Properties.Count:ADO的ResultSet或Connection的属性个数。

      rs.Properties(item).Name:ADO的ResultSet或Connection的名称。

      rs.Properties:ADO的ResultSet或Connection的值。

      rs.close():关闭连接。

    Recordset 对象的属性
    1、CursorType 属性
    AdOpenForwardOnly:仅向前游标,默认值。除了只能在记录中向前滚动外,与静态游标相同。当只需要在记录集中单向移动时,使用它可提

    高性能。(顾名思义,这种游标只能向前移动。然而,由于这种游标功能有限,将它用于系统资源时是非常有效的。)
    AdOpenKeyset:键集游标。尽管从您的记录集不能访问其他用户删除的记录,但除无法查看其他用户添加的记录外,键集游标与动态游标相似

    。仍然可以看见其他用户更改的数据。(KeySet游标允许你看见自它创建起其他用户所做的修改,然而你却不能看到其他用户增加或删除的记

    录。)
    AdOpenDynamic :动态游标。可以看见其他用户所作的添加、更改和删除。允许在记录集中进行所有类型的移动,但不包括提供者不支持的书

    签操作。(此类型的游标功能强大同时也是耗费系统资源最多的游标。Dynamic游标可以看到他们保存记录集合的所有变化。使用Dynamic游标

    的用户可以看到其他用户所做的编辑、增加、删除。如果数据提供者允许这种类型的游标,那么它是通过每隔一段时间从数据源重取数据来支

    持这种可视性的。毫无疑问这会需要很多的资源。 )
    AdOpenStatic:静态游标。可以用来查找数据或生成报告的记录集合的静态副本。另外,对其他用户所作的添加、更改或删除不可见。

    (Static类游标只是数据的一幅快照。这就是说,它无法看到自它创建以后其他用户对RecordSet所做的修改。采用这类游标你可以向前和向后

    航行。由于其功能简单,资源的需求比Dynamic要小! )
    需要注意的是:一旦打开RecordSet,你就无法改变CursorType属性。但是,如果你首先关闭RecordSet,改变CursorType属性,然后重新打开

    RecordSet,那么你仍可以有效地改变游标的类型!

    2、LockType 属性
    在任何同时可被多用户修改的数据库应用程序中,你必须处理可能发生的多个用户同时对同一条记录进行操作时的情况。当这种情况出现时,

    数据的完整性就会受到威胁,这是因为一个用户可能会在不自觉地在保存自己所做的修改时覆盖他人的修改。到时候你会觉得自己好象是没有

    做事。为了处理这种情况。ADO允许你在对RecordSet对象进行更新时决定并发事件控制的类型,当一个用户编辑时,如何由他对记录进行锁定

    。这就是由LockType属性所决定的。这个属性有四个值:
    adLockReadonly:默认值,只读。无法更改数据。(这是RecodSet的默认值,如果你把锁定的方式设为该值,那么你将不能更新 Recordset。


    adLockPessimistic:保守式记录锁定(逐条)。提供者执行必要的操作确保成功编辑记录,通常采用编辑时立即锁定数据源的记录的方式。(

    如果设置为此类锁定,记录被锁定,且只有在编辑开始到将记录更新的提交给数据提供者这段时间内进行编辑的用户才可以访问! )
    adLockOptimistic:开放式记录锁定(逐条)。提供者使用开放式锁定,只在调用 Update 方法时锁定记录。(只有在将数据提交给数据提供

    者的那一瞬间才把记录锁定。)
    adlockBatchOptimistic:开放式批更新。用于与立即更新模式相反的批更新模式。(设定为这种类型的锁定制式将被称为批量更新模式的

    RecordSet。 可以加快更新RecordSet修改数据的速度,但因为同时更新多个记录,它也会恶化与并发访问相关的问题!)

    3、AbsolutePage 属性
    AbsolutePage属性设定当前记录的位置是位于哪一页的页数编号;使用PageSize属性将Recordset对象分割为逻辑上的页数,每一页的记录数为

    PageSize(除了最后一页可能会有少于PageSize的记录数)。这里必须注意并不是所有的数据提供者都支持此项属性,因此使用时要小心。
    与AbsolutePosition属性相同,AbsolutePage属性是以1为起始的,若当前记录为Recordset的第一行记录,AbsolutePage为1。可以设定

    AbsolutePage属性,以移动到一个指定页的第一行记录位置。
    4、AbsolutePosition属性
    若您需要确定目前指标在RecordSet中的位置,您可以用AbsolutePosition属性。
    AbsolutePosition属性的数值为目前指标相对於第一笔的位置,由1算起,即第一笔的AbsolutePosition为1。
    注意,在存取RecordSet时,无法保证RecordSet每次都以同样的顺序出现。
    若要启用AbsolutePosition,必须先设定为使用用户端cursor(指针):rs.CursorLocation=3

    5、PageCount属性
    使用PageCount属性,决定Recordset对象包括多少“页”的数据。这里的“页”是数据记录的集合,大小等于PageSize属性的设定,即使最后

    一页的记录数比PageSize的值少,最后一页也算是PageCount的一页。必须注意也并不是所有的数据提供者都支持此项属性。

    6、PageSize属性
    PageSize属性是决定ADO存取数据库时如何分页显示的关键,使用它就可以决定多少记录组成一个逻辑上的“一页”。设定并建立一个页的大小

    ,从而允许使用AbsolutePage属性移到其它逻辑页的第一条记录。PageSize属性能随时被设定。

    7、RecordCount属性
    这也是一个非常常用和重要的属性,我们常用RecordCount属性来找出一个Recordset对象包括多少条记录。使用 RecordCount 属性可确定

    Recordset 对象中记录的数目。ADO 无法确定记录数时,或者如果提供者或游标类型不支持 RecordCount,则该属性返回 –1。读已关闭的

    Recordset 上的 RecordCount 属性将产生错误。Recordset 对象的游标类型会影响是否能够确定记录的数目。对仅向前游标,RecordCount 属

    性将返回 -1,对静态或键集游标返回实际计数,对动态游标取决于数据源返回 -1 或实际计数。

    8、BOF与EOF属性
    通常我们在ASP程序中编写代码来检验BOF与EOF属性,从而得知目前指标所指向的RecordSet的位置,使用BOF与EOF属性,可以得知一个

    Recordset对象是否包含有记录或者得知移动记录行是否已经超出该Recordset对象的范围。
    若当前记录的位置是在一个Recordset对象第一行记录之前时,BOF属性返回true,反之则返回false。
    若当前记录的位置是在一个Recordset对象最后一行记录之后时,EOF属性返回true,反之则返回false。
    (BOF与EOF都为True表示在RecordSet里没有任何记录。)

    9、Filter 属性
    为 Recordset 中的数据指定筛选条件,使用 Filter 属性可选择性地屏蔽 Recordset 对象中的记录,已筛选的 Recordset 将成为当前游标。
    这将影响基于当前游标返回值的其他属性,如 AbsolutePosition、AbsolutePage、RecordCount 和 PageCount,因为将 Filter 属性设置为特
    定值可将当前记录移动到满足新值的第一个记录。
    这属性我认为相当有用处,有的时候我们打开了Recordset进行了某些判断以后我们还想过滤记录也就是重新调整 sql 语句,难道我们关闭

    Recordset再用新的SQL语句打开?不是,我们用Filter属性进行过滤,比如说
    rs.open exec,conn,1,1
    if .... then rs.filter="name='xxx'"
    而不是
    rs.open exec,conn,1,1
    if ... then
    rs.close
    exec=exec&" where name='xxx'"
    rs.open exec,conn,1,1
    end if
    实际上再很多地方不得不用到Filter,在以后的ASP技巧中会说到,大家也可以想一下。
    明天继续说Recordset对象的方法。

    Recordset对象的方法
    1、AddNew 方法
    创建可更新 Recordset 对象的新记录。
    recordset.AddNew FieldList, Values
    FieldList   可选。新记录中字段的单个名称、一组名称或序号位置。
    Values   可选。新记录中字段的单个或一组值。如果 Fields 是数组,那么 Values 也必须是有相同成员数的数组,否则将发生错误。字段名

    称的次序必须与每个数组中的字段值的次序相匹配。
    我们一般是
    rs.addnew
    rs("xx")=xx
    rs("xx")=xx
    rs.update
    需要注意的是在立即更新模式(调用 Update 方法时提供者会立即将更改写入基本数据源)下,调用不带参数的 AddNew 方法可将 EditMode

    属性设置为 adEditAdd。提供者将任何字段值的更改缓存在本地。调用 Update 方法可将新记录传递到数据库并将 EditMode 属性重置为

    adEditNone。如果传送了 Fields 和 Values 参数,ADO 则立即将新记录传递到数据库(无须调用 Update),且 EditMode 属性值没有改变

    (adEditNone)。
    可能大家会问在ASP中使用ADO的AddNew方法和直接使用“Insert into...”语句有和不同?那种方式更好?答:ADO的AddNew方法只是将

    “Insert into ”语句封装了起来,所以,当对大量数据进行操作的时候,直接使用SQL语句将会大大加快存取数据的速度,因为他减少了ADO

    的“翻译”时间。

    2、Delete 方法
    删除当前记录或记录组。
    recordset.Delete AffectRecords
    AffectRecords   AffectEnum 值,确定 Delete 方法所影响的记录数目,该值可以是下列常量之一。
    AdAffectCurrent 默认。仅删除当前记录。
    AdAffectGroup 删除满足当前 Filter 属性设置的记录。要使用该选项,必须将 Filter 属性设置为有效的预定义常量之一。
    adAffectAll 删除所有记录。
    adAffectAllChapters 删除所有子集记录。
    使用立即更新模式将在数据库中进行立即删除,否则记录将标记为从缓存删除,实际的删除将在调用 Update 方法时进行。
    3、Update 方法
    保存对 Recordset 对象的当前记录所做的所有更改
    recordset.Update Fields, Values
    Fields   可选。变体型,代表单个名称;或变体型数组,代表需要修改的字段(一个或多个)名称及序号位置。
    Values   可选。变体型,代表单个值;或变体型数组,代表新记录中字段(单个或多个)值。
    如果希望取消对当前记录所做的任何更改或者放弃新添加的记录,则必须调用 CancelUpdate 方法。
    4、CancelUpdate 方法
    recordset.CancelUpdate
    使用 CancelUpdate 方法可取消对当前记录所作的任何更改或放弃新添加的记录。在调用 Update 方法后将无法撤消对当前记录或新记录所做

    的更改,如果在调用 CancelUpdate 方法时添加新记录,则调用 AddNew 之前的当前记录将再次成为当前记录。如果尚未更改当前记录或添加

    新记录,调用 CancelUpdate 方法将产生错误。
    5、Find 方法
    搜索 Recordset 中满足指定标准的记录。如果满足标准,则记录集位置设置在找到的记录上,否则位置将设置在记录集的末尾。
    Find (criteria, SkipRows, searchDirection, start)
    criteria   字符串,包含指定用于搜索的列名、比较操作符和值的语句。
    SkipRows    可选,长整型值,其默认值为零,它指定当前行或 start 书签的位移以开始搜索。
    searchDirection    可选的 SearchDirectionEnum 值,指定搜索应从当前行还是下一个有效行开始。其值可为 adSearchForward 或
    adSearchBackward。搜索是在记录集的开始还是末尾结束由 searchDirection 值决定。
    start    可选,变体型书签,用作搜索的开始位置。
    criteria “比较操作符”可以是“>”(大于)、“<”(小于)、“=”(等于)、“>=”(大于或等于)、“<=”(小于或等于)、“<>”
    (不等于)或“like”(模式匹配)。 criteria 中的值可以是字符串、浮点数或者日期。字符串值以单引号分界(如“state = 'WA'”)。
    日期值以“#”(数字记号)分界(如“start_date > #7/22/97#”)。
    需要注意的是find是不支持多字段。但是可以用filter实现。"name='abc'"AND "city='sh'" 是不允许的
    6、Move 方法
    移动 Recordset 对象中当前记录的位置
    recordset.Move NumRecords, Start
    NumRecords    带符号长整型表达式,指定当前记录位置移动的记录数。
    Start    可选,字符串或变体型,用于计算书签。也可为下列值之一:
    AdBookmarkCurrent 默认。从当前记录开始。
    AdBookmarkFirst 从首记录开始。
    AdBookmarkLast 从尾记录开始。
    需要注意的是:
    (1)如果 NumRecords 参数大于零,则当前记录位置将向前移动(向记录集的末尾)。如果 NumRecords 小于零,则当前记录位置向后移动(

    向记录集的开始)。
    (2)从空的 Recordset 对象调用 Move 方法将产生错误。
    (3)如果 Move 调用将当前记录位置移动到首记录之前,则 ADO 将当前记录放置在记录集(BOF 为 True)的首记录之前。在 BOF 属性已经

    为 True 时试图向后移动将产生错误;如果 Move 调用将当前记录位置移动到尾记录之后,则 ADO 将当前记录放置在记录集(EOF 为 True)

    的尾记录之后。在 EOF 属性已经为 True 时试图向前移动将产生错误。
    7、MoveFirst、MoveLast、MoveNext 和 MovePrevious 方法
    在指定 Recordset 对象中移动到第一个、最后一个、下一个或前一个记录并使该记录成为当前记录。
    recordset.{MoveFirst | MoveLast | MoveNext | MovePrevious}
    需要注意的是:
    (1)使用 MoveNext 方法将当前记录向前移动一个记录(向 Recordset 的底部)。如果最后一个记录是当前记录并且调用 MoveNext 方法,

    则 ADO 将当前记录设置到 Recordset (EOF 为 True)的尾记录之后。当 EOF 属性已经为 True 时试图向前移动将产生错误。
    (2)使用 MovePrevious 方法将当前记录位置向后移动一个记录(向记录集的顶部)。Recordset 对象必须支持向后游标移动;否则方法调用

    将产生错误。如果首记录是当前记录并且调用 MovePrevious 方法,则 ADO 将当前记录设置在 Recordset (BOF 为 True)的首记录之前。而

    BOF 属性为 True 时向后移动将产生错误。
    8、Clone 方法
    创建与现有 Recordset 对象相同的复制 Recordset 对象。可选择指定该副本为只读。
    Set rstDuplicate = rstOriginal.Clone
    rstDuplicate   对象变量,标识正在创建的复制 Recordset 对象。
    rstOriginal   对象变量,标识要被复制的 Recordset 对象。
    使用 Clone 方法可创建多个 Recordset 对象副本,这对于希望在给定的记录组中保留多个当前记录十分有用。使用 Clone 方法比使用与初始

    定义相同的定义创建和打开新 Recordset 对象要有效得多。
    也就是说
    rs.open exec,conn,1,1
    rs2.open exec,conn,1,1
    应该这么改写
    rs.open exec,conn,1,1
    rs2=rs.clone
    需要注意的是:
    (1)新创建副本的当前记录将设置为首记录。
    (2)关闭原始 Recordset 时并不关闭它的副本,而关闭某个副本也将不关闭原始 Recordset 或任何其他副本。
    9、Close 方法
    关闭打开的对象及任何相关对象。
    object.Close
    需要注意的是:
    (1)使用 Close 方法可关闭Recordset 对象以便释放所有关联的系统资源。关闭对象并非将它从内存中删除,可以更改它的属性设置并且在
    此后再次打开。要将对象从内存中完全删除,可将对象变量设置为 Nothing。
    (2)如果正在立即更新模式下进行编辑,调用 Close 方法将产生错误,应首先调用 Update 或 CancelUpdate 方法。

    10、Open 方法,为什么最后说这个,因为前面的各项属性方法没有弄清楚,我们是不会理解CursorType参数的
    recordset.Open Source, ActiveConnection, CursorType, LockType, Options
    Recordset对象可以通过Source属性来连接Command对象。Source参数可以是一个Command对象名称、一段SQL命令、一个指定的数据表名称或是

    一个Stored Procedure。假如省略这个参数,系统则采用Recordset对象的Source属性。ActiveConnection
    Recordset对象可以通过ActiveConnection属性来连接Connection对象。这里的ActiveConnection可以是一个Connection对象或是一串包含数据
    库连接信息(ConnectionString)的字符串参数。CursorType
    Recordset对象Open方法的CursorType参数表示将以什么样的游标类型启动数据,包括adOpenForwardOnly、adOpenKeyset、adOpenDynamic及ad
    OpenStatic,分述如下:
    --------------------------------------------------------------
    常数 常数值 说明
    -------------------------------------------------------------
    adOpenForwardOnly 0 缺省值,启动一个只能向前移动的游标(Forward Only)。
    adOpenKeyset 1 启动一个Keyset类型的游标。
    adOpenDynamic 2 启动一个Dynamic类型的游标。
    adOpenStatic 3 启动一个Static类型的游标。
    -------------------------------------------------------------
    以上几个游标类型将直接影响到Recordset对象所有的属性和方法,以下列表说明他们之间的区别。
    Recordset属性 adOpenForwardOnly adOpenKeyset adOpenDynamic adOpenStatic

    AbsolutePage 不支持 不支持 可读写 可读写
    AbsolutePosition 不支持 不支持 可读写 可读写
    BOF 只读 只读 只读 只读
    CursorType 可读写 可读写 可读写 可读写
    EOF 只读 只读 只读 只读
    Filter 可读写 可读写 可读写 可读写
    LockType 可读写 可读写 可读写 可读写
    PageCount 不支持 不支持 只读 只读
    PageSize 可读写 可读写 可读写 可读写
    RecordCount 不支持 不支持 只读 只读
    AddNew 支持 支持 支持 支持
    CancelBatch 支持 支持 支持 支持
    CancelUpdate 支持 支持 支持 支持
    Close 支持 支持 支持 支持
    Delete 支持 支持 支持 支持
    Move 不支持 支持 支持 支持
    MoveFirst 支持 支持 支持 支持
    MoveLast 不支持 支持 支持 支持
    MoveNext 支持 支持 支持 支持
    MovePrevious 不支持 支持 支持 支持
    Open 支持 支持 支持 支持
    Update 支持 支持 支持 支持
    UpdateBatch 支持 支持 支持 支持
    --------------------------------------------------------------
    Recordset对象Open方法的LockType参数表示要采用的Lock类型,如果忽略这个参数,那么系统会以Recordset对象的LockType属性为预设值。

    LockType参数包含adLockReadOnly、adLockPrssimistic、adLockOptimistic及adLockBatchOptimistic等,分述如下:
    常数 常数值 说明
    --------------------------------------------------------------
    adLockReadOnly 1 缺省值,Recordset对象以只读方式启动,无法运行AddNew、Update及Delete等方法
    adLockPrssimistic 2 当数据源正在更新时,系统会暂时锁住其他用户的动作,以保持数据一致性。
    adLockOptimistic 3 当数据源正在更新时,系统并不会锁住其他用户的动作,其他用户可以对数据进行增、删、改的操作。
    adLockBatchOptimistic 4 当数据源正在更新时,其他用户必须将CursorLocation属性改为adUdeClientBatch才能对数据进行增、删、改的操

    作。
    需要注意的是:
    如果数据源没有返回记录,那么提供者将 BOF 和 EOF 属性同时设置为 True,并且不定义当前记录位置。如果游标类型允许,仍然可以将新数

    据添加到该空 Recordset 对象。

  • QuickTest Professional连接oracle10g数据库(转载)

    2012-04-28 13:46:42

    keyword:QTP QuickTest Professional oracle10g 数据库连接 

    以下VBS代码

    Dim conn'定义数据库连接对象
    Dim str'定义数据库连接字符串

    Set conn=CreateObject("ADODB.Connection")
    str="Provider=MSDAORA.1;Data Source=ORCL;Password=123456;User ID=zxf;Persist Security Info=True"
    conn.Open str

    '以上为连接数据库

    If conn.State=0 Then
            reporter.ReportEvent micFail,"oracle数据库连接测试","失败"
    else
            reporter.ReportEvent micPass,"oracle数据库连接测试","通过"
    End If

    conn.Close

    详解:本例以windows操作系统为例

    1.首先安装oracle10g

    2.安装完成后,建立一个普通oracle用户

    3.配置本地数据源ODBC,注意TNS的配置

    4.str连接字符串解释:Provider数据提供者,QTP中只能使用 MSDAORA.1,其他都将报错“程序未安装”。Data Sourse要求设置为TNS名。

    -------------------------------------------------我是不同内容的分割线-------------------------------------------

    对oracle进行数据操作,取出一个字段值与预期字段值比较以达到测试目的

    Dim conn'定义数据库连接对象
    Dim str'定义数据库连接字符串
    Dim sql'定义数据查询字符串

    Dim rt'定义数据库查询结果集对象
    Dim result'定义数据库字段实际值

    Set conn=CreateObject("ADODB.Connection")
    str="Provider=MSDAORA.1;Data Source=ORCL;Password=123456;User ID=zxf;Persist Security Info=True"
    conn.open str

    '以上为连接数据库

    Set rt=CreateObject("ADODB.Recordset")
    sql="select id from Test"
    rt.open sql,str,1,3

    result=rt("id")

    '以上为获取结果集中id字段的值,说明:Test表中只有一条记录

    If result!=“01” Then
            reporter.ReportEvent micFail,"oracle数据库检查点测试","失败"
    else
            reporter.ReportEvent micPass,"oracle数据库检查点测试","通过"
    End If

    '以上为将数据库中实际字段的值与预期值“01”比较

    conn.Close

    ---------------------------------------------其他数据库连接字符串------------------------------------------------

    mysql:server为服务器地址,database是数据库名

    "DRIVER={MySQL ODBC 3.51 Driver};SERVER=localhost;DATABASE=test;USER=tester;password=3652359;Option=3"

    sqlserver:Data Source是服务器地址,Database是数据库名

    "Provider=SQLOLEDB.1;User ID=sa;password=sa;Data Source=localhost;DATABASE=Student"

  • asp部署以及iis的安装

    2012-04-26 15:15:28

    一、安装iis
    二、部署:依次单击“开始”->“控制面版”->“管理工具”->Internet 信息服务”,出现IIS管理器窗口。

    选中“Internet 信息服务”窗口左侧“默认网站”,右键依次选择“新建” > “虚拟目录”。

    2. 在出现“虚拟目录向导”窗口的“别名”对话框中填写你想要的名称(请记住这个名称)。单击“下一步”,在“输入内容所在的目录路径”中单击“浏览”按钮找到网站文件的目录。

    3.勾选“写入”选项,单击“下一步”->“完成”。

    5.您也可以在“默认网站”上右键“新建” > “属性”。在出现的“网站属性”中更改“网站”、“主目录”、“文档”等设置。 

    6.       IE浏览器中输入”http://localhost/(虚拟目录别名)/index.asp”按回车键,如下图所示界面:****系统安装步骤

    安装IIS->下载并解压到根目录下。在IE地址栏中输入http://127.0.0.1/你的文件夹名/index.asp即可打开并进行配置。详细步骤见后面。

    途中遇到的问题

    1、浏览网页:显示网页无法打开, 原因:发现ie被卸载,重新安装ie

    2、The server has encountered an error while loading an application during the processing of your reque

    分类: Asp.Net IIS 921人阅读 评论(1) 收藏 举报
    访问站点时出现server application error错误,详细信息是:
    server application error
    The server has encountered an error while loading an application during the processing of your request. Please refer to the event log for more detail information. Please contact the server administrator for assistance.
    失望的时用事件查看器看出错日志时,居然只能看到标题,查看详细信息时弹不出显示信息的对话框,后来发现不要先查看应用程序日志,就可以查看系统日志,否则都看不了。于是开始搜索解决办法。找到好几种办法,最多的是说IWAM账号的密码不同步所致,于是开始同步,方法如下:
    IWAM账户密码存在三个地方:本地用户中的IWAM用户、IIS内置数据库、组件服务中的IIS组件
    更改方法:
    1、停止IIS服务
    2、修改本地用户中的用户:IWAM_机器名和IUSER_机器名(个人认为不需要修改IUSER_机器名用户的密码,微软相关资料也只提到修改IWAM)的密码。很简单,不用说了。
    3、修改IIS内置数据库中的密码,稍为麻烦,但是也很容易
    运行CMD
    进入脚本目录: cd C:\inetpub\adminscripts
    获取 IWAM 帐户密码命令: cscript.exe adsutil.vbs get w3svc/wamuserpass
    获取 IUSR 帐户密码命令: cscript.exe adsutil.vbs get w3svc/anonymoususerpass
    输入以上命令,按回车可分别查看IWAM和IUSR的密码。
    这里注意:在WIN2000中,查看到的密码为星号,若要不为星号,必须要先修改adsutil.vbs文件。
    修改方法:
    a.到c盘 inetpub\adminscripts 找到adsutil.vbs (根据装系统时设定的不同,有的路径可能不一样)
    b.右键单击,用记事本打开
    c.查找 IsSecureProperty = True  注意=前后各有一个空格
    d.将 IsSecureProperty = True 改为 IsSecureProperty = False
    e.保存,关闭,OK。
    修改密码命令:
    修改 IWAM 帐户密码 cscript.exe adsutil.vbs set w3svc/wamuserpass "这里输入在本地用户中修改的密码" 
    修改 IUSR 帐户密码 cscript.exe adsutil.vbs set w3svc/anonymoususerpass "这里输入在本地用户中修改的密码"
    4、同步组件密码
    同样在CMD中输入:cscript.exe synciwam.vbs -v
    5、重启IIS,运行iisreset
    做到这,本以后问题解决,谁知故障依旧,又做了几遍,仍是如此。想到能不能重装IIS,于是在添加删除程序里卸载掉IIS,再重新安装IIS,谁知故障仍然很顽固,没办法,应该是其他原因,如果不是密码问题,那就是权限问题,继续寻找答案。
    检查IUSER和IWAM两个账号,发现重装IIS后,这两个账号居然不属于任何组了,于是加进它们本该属于的GUESTS组,再次重启IIS,还是同样错误,我无语了,真有甩手不干,但是不干靠啥子养老婆呢,只好继续。
    继续查找资料......
    有说重新注册两个脚本DLL
    regsvr32 jscript.dll
    regsvr32 vbscript.dll
    照做,重启IIS,仍无效
    有说检查DTC服务(全名:Distributed Transaction Coordinator)是否可以正常启动,如果正常的话请你跳过此步骤;如果出错,无法正常启动,请在开始菜单的运行中 运行:msdtc -resetlog 以创建日志文件。重起机器,检查IIS是否可以正常使用,若不行继续。在CMD下执行以下命令:
    cd %windir%\system32\inetsrv
    rundll32 wamreg.dll, CreateIISPackage
    regsvr32 asptxn.dll
    仍旧照做,仍无效,唉,这匹死马难道硬是医不活了吗???
    部分使用者在修复 IIS 500 问题时.
    regsvr32 asptxn.dll 失败 错误代码:0x8004e00f
    在CMD下執行以下命令:
    cd %windir%\system32\inetsrv

    rundll32 wamreg.dll, CreateIISPackage

    regsvr32 asptxn.dll

    但部分使用者在进行 regsvr32 asptxn.dll 会产生错误代码 0x8004e00f

    其原因是系统中并未安裝 MSDTC

    安裝方法如下:

    msdtc -install

    msdtc -resetlog
    这时候又想到了日志,干脆清空日志,把日志大小扩到1M,再访问站点,这时日志正常了,打开检查,最多的是“...没有在限定的时间内用 DCOM 注册”,ID号3D14228D-FBE1-11D0-995D-00C04FD919C1,



    而“组件服务”->“计算机”->“我的电脑”->“COM+应用程序”中,有一个IIS Out-Of-Process Pooled Applications该应用程序的ID号即为{3D14228D-FBE1-11D0-995D-00C04FD919C1},很多系统报错找不到应用程序{3D14228D-FBE1-11D0-995D-00 C04FD919C1}之类的错误,就是因为该应用程序未能启动。打开该应用程序的属性,检查标识为IWAM用户,看来是与IWAM的权限有关,但是还有什么权限呢?有资料说把IIS运行的账号改成管理员就OK了,于是测试:
    “组件服务”->“计算机”->“我的电脑”->“COM+应用程序”中,有一个“IIS Out-Of-Process Pooled”鼠标右键“属性”--“标识”--把“此用户”调整为“交互式用户--目前已登录的用户”。然后“确定”,再重启IIS!
    访问站点,ASP文件又能正常解析了,站点又正常了,我的神啊!!!痛哭!!!
    但是,用管理账号运行IIS,可能会出现安全隐患,谁知道呢?再得努力,继续查找资料,翻了N久,又找到新的办法,有人提到除了保证IWAM用户只在GUEST组内外,还要在“本地用户和组”->“组”里面,右键点击Users组属性,添加进NT AUTHORITY\Authenticated Users和NT AUTHORITY\Interactive两个用户成员,我于是添加进去,再把IIS Out-Of-Process Pooled组件的运行用户改回IWAM,这时还要输入IWAM用户的密码哦,如果查看它的密码就不再重复了。
    做了这一步,重启IIS,访问站点,
    总结:
    注意IWAM的权限问题
    日志是否有问题(有资料说日志也会引志IIS异常,而这次我也是处理过日志的哦)
    IWAM密码有时会不同步
    JS和VBS重新注册DLL
    检查DTS服务
    Server Application Error解决


    在浏览器中:

    HTTP 500 - Internal Server Error
    - 或 -

    Server Application Error
    The server has encountered an error while loading an application during the processing of

    your request.Please refer to the event log for more detail information.Please contact the

    server administrator for assistance.
    在系统事件日志中:

    Source:DCOM
    Error:DCOM got error "Logon Failure:unknown username or bad password" Unable to logon

    .\IWAM_SERVERNAME in order to run the server.
    - 和 -

    Source:W3SVC
    Error:"The server failed to load application '/LM/W3SVC/1/Root/op.'The error was 'The server

    process could not be started because the configured identity is incorrect.Check the username

    and password.
    - 或 -

    Source:W3SVC Error:"The server failed to load application '/LM/W3SVC/4/Root'.The error was

    'c000003b'."
    - 和 -

    Source:W3SVC Error:"The COM Application '{3D14228D-FBE1-11d0-995D-00C04FD919C1}' at

    '/LM/W3SVC/4/Root' failed to activate out of process."


    比较简单的解决办法:

    在计算机用户管理中删除启动iis及来宾账号,重装一次IIS即可
    按我的方法,前提是一,系统是XP,其它系统不敢包.二,你没有做过其它设置.
    主要是帐户权限问题.

    打开“管理工具”->“组件服务”->“计算机”->“我的电脑”->“COM+应用程序”,(看A) 然后在右边框中,右击“IIS Out-Of-Process Pooled Applications”,(看B)选择属性,点“标识”选项卡,选择“系统帐户”,然后确定,在“服务”(不是刚才那个,打开管理工具-服务)中重启IIS即可。

    A.如打开“COM+应用程序”时出现错误,错误代码:“8004E00F-COM+无法与Microsoft分布式事务协调程序 ”
    解决办法:在"开始"-“运行“窗口中输入,msdtc -resetlog (注意-前面有一空格)即可。

    B.在“COM+应用程序”右框的组件中“IIS Out-Of-Process Pooled Applications”找不到解决办法:
    开始菜单->运行->cmd打开命令提示窗口。
    输入cd %windir%/system32/inetsrv切换到了system32下inetsrv目录。
    再输入rundll32 wamreg.dll, CreateIISPackage。
    注意:必须准确键入“CreateIISPackage”,它区分大小写。
    再输入regsvr32 asptxn.dll。
    关闭"组件服务"并重新打开"组件服务"。
    重启IIS:"管理工具"-"服务"找到IIS Admin右击选择"重新启动".
    最后打开“管理工具”->“internet信息服务”找到“默认网站”然后右击它,
    选择属性,在“TCP地址”处选择本机的IP地址。再打开“目录安全性”->“编辑
    ”弹出“身份验证方法对话框”
    这里比较麻烦点。下面说起来有点难,如果上面都对,那100%是下面的问题,如
    果这里设置不到,打开网页时,将弹出一个对话框确认后出现“未登陆,无权访
    问”,又或者显示那一行出现错误等。
    点击“浏览”->“高级”->“立即查找”在下框选择一个能用的用户(如当前用户
    ),然后确定。
    在“匿名访问”处打勾,“允许IIS控制密码”不打勾,密码(你刚才选择的用户
    的密码,无密码为空,确定密码也为空)。"基本....."不打勾,"集成....."处打
    勾。然后在刚才“匿名访问”处打过勾的现在又不打勾了。

    确定后,先按“应用”会出现一条信息“localstart.asp”(其它文件不要选),
    用鼠标“点击选择它”(记住,其实就是这里没有选择),再确定。
    从新进入刚才的“身份验证方法对话框”,在“匿名访问”处重新打勾再“应用
    ”,如出现之前我说的那条信息再点击选择它,再确定,即可完成了
    在Windows Server 2003中默认情况下是没有启动父路径的,所以当我们在ASP程序中引用包含文件时用到“..”,就会出现错误提示:“Active Server Pages 错误 'ASP 0131'解决方法”。其实我们只要启用父路径即可,这是 Windows Server 2003 IIS中的基本配置,请大家要牢记,不然很多ASP站点都将无法运行哦。
  • DOM属性和方法 转载

    2012-04-17 20:49:22

    DOM属性和方法:

    document、element、node方法document方法:

    getElementById(id)                            返回指定结点的引用
    getElementsByTagName(name)       返回文档中所有匹配的元素的集合
    createElement(name)                         创建指定类型的新结点
    createTextNode(text)                         创建一个纯文本结点

    element方法:

    getAttribute(id)                                   返回指定属性的值
    setAttribute(id,value)                         给属性赋值
    removeAttribute(id)                           移除指定属性和它的值
    getElementsByTagName(name)       返回结点内所有匹配的元素的集合

    node方法:

    appendChild(child)                             给指定结点添加一个新的子结点
    removeChild(child)                             移除指定结点的子结点
    replaceChild(newChild,oldChild)       替换指定结点的子结点
    insertBefore(newChild,refChild)       在同一层级的结点前面插入新结点
    hasChildNodes()                                 如果结点有子结点则返回true

    node属性:

    nodeName                                         以字符串的格式存放结点的名称
    nodeType                                           以整型数据格式存放结点的类型
    nodeValue                                          以可用的格式存放结点的值
    parentNode                                        指向结点的父结点的引用
    childNodes                                         指向子结点的引用的集合
    firstChild                                            指向子结点结合中的第一个子结点的引用
    lastChild                                             指向子结点结合中的最后一个子结点的引用
    nextSibling                                         获取对此对象的下一个兄弟对象的引用
    previousSibling                                    获取对此对象的上一个兄弟对象的引用



    document.title //设置文档标题等价于HTML的title标签
    document.bgColor //设置页面背景色
    document.fgColor //设置前景色(文本颜色)
    document.linkColor //未点击过的链接颜色
    document.alinkColor //激活链接(焦点在此链接上)的颜色
    document.vlinkColor //已点击过的链接颜色
    document.URL //设置URL属性从而在同一窗口打开另一网页
    document.fileCreatedDate //文件建立日期,只读属性
    document.fileModifiedDate //文件修改日期,只读属性
    document.charset //设置字符集 简体中文:gb2312
    document.fileSize //文件大小,只读属性
    document.cookie //设置和读出cookie

    ———————————————————————
    常用对象方法

    document.write() //动态向页面写入内容
    document.createElement(Tag) //创建一个html标签对象
    document.getElementById(ID) //获得指定ID值的对象
    document.getElementsByName(Name) //获得指定Name值的对象
    document.body.appendChild(oTag)
    ———————————————————————

    body-主体子对象

    document.body //指定文档主体的开始和结束等价于body>/body>
    document.body.bgColor //设置或获取对象后面的背景颜色
    document.body.link //未点击过的链接颜色
    document.body.alink //激活链接(焦点在此链接上)的颜色
    document.body.vlink //已点击过的链接颜色
    document.body.text //文本色
    document.body.innerText //设置body>…/body>之间的文本
    document.body.innerHTML //设置body>…/body>之间的HTML代码
    document.body.topMargin //页面上边距
    document.body.leftMargin //页面左边距
    document.body.rightMargin //页面右边距
    document.body.bottomMargin //页面下边距
    document.body.background //背景图片
    document.body.appendChild(oTag) //动态生成一个HTML对象

    常用对象事件

    document.body.onclick=”func()” //鼠标指针单击对象是触发
    document.body.onmouseover=”func()” //鼠标指针移到对象时触发
    document.body.onmouseout=”func()” //鼠标指针移出对象时触发
    ———————————————————————
    location-位置子对象

    document.location.hash // #号后的部分
    document.location.host // 域名+端口号//好像返回的是主机名localhost,没有返回端口号
    document.location.hostname // 域名
    document.location.href // 完整URL
    document.location.pathname // 目录部分
    document.location.port // 端口号
    document.location.protocol // 网络协议(http:)
    document.location.search // ?号后的部分
    documeny.location.reload() //刷新网页
    document.location.reload(URL) //打开新的网页
    document.location.assign(URL) //打开新的网页
    document.location.replace(URL) //打开新的网页
    ———————————————————————
    selection-选区子对象
    document.selection

    例如:

    <div>请选中这里的部分文字。</div>
    <div><input type="button" value="请选中部分文字,然后点击这里执行 empty" nclick="javascript:Foo();"

    /></div>
    <script type="text/javascript" language="javascript">
    <!--
    function Foo()
    {
    document.selection.empty();
    }
    -->
    </script>


    selection的createRange方法

    document.selection.createRange() 根据当前文字选择返回 TextRange 对象,或根据控件选择返回 ControlRange 对象。

    配合 execCommand,在 HTML 编辑器中很有用,比如:文字加粗、斜体、复制、粘贴、创建超链接等。

    这些好像都是只有在IE下才能实现。。

    ———————————————————————

    images集合(页面中的图象)

    a) 通过集合引用
    document.images //对应页面上的img标签
    document.images.length //对应页面上img标签的个数
    document.images[0] //第1个img标签
    document.images[i] //第i-1个img标签

    b)通过name属性直接引用
    img name=”oImage”
    document.images.oImage //document.images.name属性

    c)引用图片的src属性
    document.images.oImage.src //document.images.name属性.src

    d)创建一个图象
    var oImage
    oImage = new Image()
    document.images.oImage.src=”1.jpg”
    同时在页面上建立一个img /标签与之对应就可以显示

    ———————————————————————-

    forms集合(页面中的表单)

    a) 通过集合引用
    document.forms //对应页面上的form标签
    document.forms.length //对应页面上/formform标签的个数
    document.forms[0] //第1个/formform标签
    document.forms[i] //第i-1个/formform标签
    document.forms[i].length //第i-1个/formform中的控件数
    document.forms[i].elements[j] //第i-1个/formform中第j-1个控件

    b)通过标签name属性直接引用
    /formform. name=”Myform”>input name=”myctrl”/>/form
    document.Myform.myctrl //document.表单名.控件名

    c)访问表单的属性
    document.forms[i].name //对应form. name>属性
    document.forms[i].action //对应/formform. action>属性
    document.forms[i].encoding //对应/formform. enctype>属性
    document.forms[i].target //对应/formform. target>属性

    document.forms[i].appendChild(oTag) //动态插入一个控件
    document.all.oDiv //引用图层oDiv
    document.all.oDiv.style.display=”" //图层设置为可视
    document.all.oDiv.style.display=”none” //图层设置为隐藏
    document.getElementId(”oDiv”) //通过getElementId引用对象
    document.getElementId(”oDiv”).style=”"
    document.getElementId(”oDiv”).display=”none”
    /*document.all表示document中所有对象的集合
    只有ie支持此属性,因此也用来判断浏览器的种类*/


    图层对象的4个属性
    document.getElementById(”ID”).innerText //动态输出文本
    document.getElementById(”ID”).innerHTML //动态输出HTML
    document.getElementById(”ID”).outerText //同innerText
    document.getElementById(”ID”).outerHTML //同innerHTML

  • 如何禁掉qtp的报告

    2012-03-28 09:55:48

    在Tool->option->run 下有个选项为“运行完脚本后,显示结果”,不选这个选项,就可以了
  • QTP完全卸载

    2012-03-02 09:34:34

    转载http://blog.sina.com.cn/s/blog_4a7318860100gwnr.html

    装了QTP10.0  卸载后,再装9.2,安装失败,网上看了一些资料,大致是这样解决的:

    在添加/删除程序中卸载
    用QTPCleanUninstallerV2.10工具删除注册表
    C:\Documents and Settings\用户名\下搜索Mercury Interactive
    C:\Progam Files\Common Files\Mercury Interactive\License Manager
    搜索注册表,删除所有QuickTest Pro有关项
    HKEY_LOCAL_MACHINE_SOFTWARE_Mercury Interactive
    HKEY_CURRENT_USER_Software_Mercury Interactive


    卸载QTP9.2后再次安装,报错:应用变换时的错误.请验证指定的变换路径是否有效!
    解决办法:安装Windows Installer Clean Up
    清理一下残留的项目之后再装
    或者手动去注册表找
    HKEY_CLASSES_ROOT\Installer\Products\
    下面的"子目录"
    直到找到与你程序相关的,并且删除他的根项

  • 远程访问qtp

    2012-02-27 12:59:39

    通过mgn-mqt82.exe破解的qtp, 不能通过远程访问qtp, 可以通过DameWare访问远程,不会出问题
  • 在windows server 2003的虚拟机上安装qtp10

    2012-02-27 11:06:10

    在操作系统为windows server 2003的虚拟机上安装qtp10
    1、安装qtp10
    2、打补丁QTP_00644
    3、破解
  • 心情日志 [2011年09月19日]

    2011-09-19 10:21:40

  • 工作总结

    2011-07-22 16:33:30

    好久没有日志了,今天我实在控制不住了,开始写工作总结
    1、项目发版不过过频,不然导致开发改bug的质量下降,测试做重复的工作,测试质量无法保证, 最好是每轮测试可以把功能列表的每个功能测试一遍,开发把当期的bug改完, 如果发现严重的bug多的话, 在不影响发版的进度的情况下,开发可以打补丁,这样测试可以针对bug修复而测试
     
    2、在测试中重要: 风险, 进度、质量
     
    3、新人要有基础的培训
  • 转成为QTP高手必经的四个过程

    2011-03-23 09:54:31

    QTP要学精,个人认为必须要经历从无到有,从有到懂,从懂到熟,从熟到精这四个过程。


    从无到有 - 初级篇
            这个过程主要是熟悉QTP的界面设置,以及一些基本的用法,包括最基础的录制回放,低级录制,参数化,OUTPUT输出,验证点,等等,也可以在51testing论坛里找到些新手的资料,推荐大家可以去这里:http://bbs.51testing.com/thread-78399-1-2.html 下载QTP_Tutorial.chm ,这一步是最最初级的东西,一定要全部看完并且能够通过实际的例子去尝试独立完成它。总体来说这个阶段还是属于一个入门,比较容易能够接受,也是大多数测试人员能够达到的层次水平。

    从有到懂 - 中级篇
            这个过程中我们已经有了一些基础知识,这个时候我们不可以把自己再停留在录制回放了,而是需要在专家视图进行自行编写测试脚本,我们需要熟悉QTP的各种内置保留对象,需要熟悉QTP对象库的原理,描述性编程以及GETRO,GETTO,SETTO的用法,DATATABLE的方法应用,自定义REPORT,能够熟练的使用F7脚本生成器来编写脚本,随后我们需要对VBS有一定的了解,可以先学习一下VBS的一些基础知识,并能够熟练的运用它,推荐大家可以去下载VBScript. 脚本语言教程(51Testing官方教材):http://bbs.51testing.com/thread-123064-1-1.html
    尝试着全手工去写脚本,并对脚本进行优化,这样就能够使我们的脚本更加强大,更加的灵活。

    从懂到熟 - 高级篇
            在这个过程中我们已经有能力可以熟练的在专家视图中进行编写脚本,以及可以使用简单的VBS对脚本进行修改以及优化,到了这一步我们就需要学习一些QTP的相对高级用法,
    √   熟悉com组件包括fso,wsh,eom,aom,ado中的一些方法和属性
    √  学会使用DOM,DLL,DOTNETFACTORY,WIN32 API
    √  特殊情况处理,比如鼠标事件,WEBTABLE中WebCheck处理,有时可以通过借助自己写的小工具来解决
    √  异常情况处理,通过VBS判断来把异常情况包括进去,包括VBS中的错误处理,QTP中的场景恢复
    √  完成以上过程后就可以进入最后一个过程。
           

    从熟到精 - 精通篇
            到了这个过程,其实已经可以说是一个半高手了,可以独立解决各种测试中碰到的难题,接下来可以尝试去读高手写的一些代码,比如REPORTMANAGER,saffron等,精通的话不是人人都可以达到的,这个过程还需要学会框架的设计,保留对象的扩展,插件的扩展开发,等等以及各方面的综合扩展能力,对于最新的一些技术也要实时了解,达到这个层次之后你已经可以说对QTP了如指掌了,貌似我离这个层次还有很大一段距离。


    这里顺便推荐几个非常好的QTP学习网站:

    √    陈能技的博客:http://blog.csdn.net/testing_is_believing
    相信很多朋友都应该认识他,曾经出过一本《QTP自动化测试实践》,他对QTP有一定的研究,博客内容不错,有抛砖引玉的作用

    √    一位叫zzxxbb112的博客:http://blog.csdn.net/zzxxbb112
    如果最近一直逛51的朋友应该看到过,他写的文章详细易懂对QTP的研究颇深,技术含量也比较高,在他的博客中学习到了不少先进技术,比较欣赏他

    √    如果英文好的朋友可以去最著名的SQAFORMS论坛逛逛:http://www.sqaforums.com
    这个网站上有很多国外的QTP高手,也有许多非常值得我们借鉴的帖子,推荐,还有ADVANCEDQTP也不错


  • 自动化测试的数据框架

    2011-03-14 22:46:23

    http://blog.csdn.net/samsunge808/archive/2009/08/01/4397625.aspx

    测试 自动化的架构定义了如何存储、引用、分组、共享以及重用测试脚本和测试数据。

      脚本的执行通常都由工具所支持,通常被称作测试自动化框架。框架是一个基础的结构,我们相互独立的测试自动化工具中的脚本和数据整合到这个框架中。

      由脚本的开发者来决定如何组织测试数据,以及脚本如何读取这些测试数据。另一方面,测试数据的操作和维护的易用性也是框架可行性的关键方面。

       全局和局部测试数据

      相关联的测试脚本通常放到一组,称为测试集( test sets),用于覆盖被测试应用程序的特定功能区。

      测试集定义了一系列的脚本,这些脚本由测试自动化框架按一定的顺序以批处理的方式执行。

      常见的测试集包括冒烟测试集(smoke test set)和回归测试集(regression test set)等。

      一个脚本可以从属于多个测试集,并且用不同的测试数据来运行。

      自动化框架从脚本库中选取脚本(以及相关的数据文件)在各分布式的主机上以测试集所定义的顺序运。

      测试数据可以按范围来进行分类。

      全局(Global)测试集数据对于测试集中的所有脚本都是可见的、可共享的,而局部(local)数据只对其所创建的脚本是可见的。

      全局测试数据通常是那些可配置的参数,例如服务器名、启动页面的URL地址等,它们是所有脚本的基础数据。图1展示了这些测试集的数据组织情况。

     

    图1

      设计规则

      在行业最佳实践的基础上,我定出了6个普遍适用的设计规则,实践证明对于在框架中组织测试数据是非常有效的。这些规则应该被视为开发内部测试自动化框架的功能需求,或者用于评估商业框架之用。

      下面列出这些规则以及给测试自动化框架用户带来的好处:

      规则1:测试数据必须与测试脚本分离

      这是代码设计的最基本原则,对于测试脚本设计一样适用。但是我曾经无数次看到这个规则被违反。由此带来的后果是代码需要被重写,导致进度延误。一旦程序通过调试并发布后,就应该避免代码的修改,除非万不得已。任何代码的修改都容易引入错误。

      如果数据写死在代码中,则可能导致你修改了一个地方,但是忘记修改其他 地方。

      另外一个原因是代码的国际化问题;所有代码中的可读的字符串都应该用变量表示,并且存储在单独的资源文件中。这样一旦需要改变区域设置,你只需要修改配置引用新的区域设置对应的目录的文件,不需要做任何的代码修改。

      这个规则对于测试自动化的主要好处是:对于测试一个产品的不同功能,相同的代码可以被重用而不需要修改,仅需要修改对应的测试数据即可。把脚本和数据分离还可以显著地减少需要维护的脚本的代码行。

      规则2:测试数据应该以表格的形式出现

      以表格形式展现数据有利于数据驱动测试的设计。数据驱动测试(data-driven test)是一种自动化测试 技术 ,它允许一个自动化脚本可以通过循环读取数据表格的每一行的数据来驱动测试,从而实现多个测试用例。

      规则3:数据表格应该以外部文件的形式提供,并且应该容易访问和修改。

      我把测试脚本的用户分成两大类:测试自动化工程师(test automation engineer)和领域专家(subject matter expert)。

      后者通常不具备编程技巧,但是他们在被测试程序所涉及到业务领域具有很深的理解。他们知道用哪些数据来验证应用程序的功能细节。如果一个脚本被恰当地设计,则领域专家应该可以很容易地执行,而不需要看懂脚本代码。他们只需要修改测试数据。如果在数十个子文件夹中寻找数据文件很困难的话,则证明测试自动化框架是效率低下的、不可用的。

      规则4:对于测试集的所有脚本普遍适应的全局数据应该与局部数据分离开来。

      如果在一个大的测试集的脚本数据文件既包含全局数据又包含局部数据,则需要更多的时间来修改所有数据文件中的相同数据。

      这个过程是低效率的,并且容易出错。如果我们有一个统一的库来存储全局数据,则只需要每个测试集做一次修改,然后就能自动同步到所有脚本中。

      每个人只要通过修改全局的设置,然后就可以在他的环境中执行测试集,而对于那些仍然有效的局部数据,则可以直接重用而不需要修改。

      规则5:局部测试数据应该与测试脚本以及包含测试脚本的测试集唯一地关联起来。

      与测试集的关联,对于在多个测试集运行相同的脚本,但是以不同的数据运行来说是必要的。

      就像图1一样,我把测试数据分为两套,一套是为测试脚本运行的,另外一套是为测试集运行的。

      规则6:为每个测试集准备的局部数据应该分离开来,但是共存于同一数据文件中。

      在运行脚本时,测试自动化框架从脚本库中读取脚本开发者提供的数据文件。

      为了后续测试集的数据修改,你需要重写原来的数据文件。这将导致数据冲突。一个可行的解决办法是:一个脚本和多个数据文件对应到每个测试集。这样的方法对数据文件的维护和动态映射正确的数据文件到脚本来说会产生一定的工作 量。但是如果对于每个测试集,我们仅有一个数据文件,局部数据共存于文件中,则会简化数据列表以及搜索的难度。而且数据共存也能避免数据冲突和重写。

      下面是一个例子,是一个测试数据组织的灵活、有效的架构,其遵循了上述的设计规则。这个解决方案是针对Window平台的,但是对于其他平台同样适用,那些数据设计规则是平台无关的。

      数据组织

      在这个应用的例子中,每个脚本只与一个数据文件关联。遵循规则2,它使用一个Excel表单来存储测试 数据。根据规则3,这些数据文件应该很容易被领域专家访问到。这提出了另外一个很基本的问题:如何有效地将脚本和数据文件分组存储。

      当一个工程师开始一个测试自动化项目,面对的第一个工作 任务就是如何组织测试脚本和数据。

      为了完成这个任务,我提出一个实践:创建应用程序的功能分解模型,把所有功能都分解到有层次关系的功能区域和子区域。然后把这个结构映射到一个目录树,在目录树中存储测试用例和脚本,这些用例和脚本对应到功能区域的目录。领域专家不需要查看那些脚本,但是他们需要知道那些脚本是做什么的,它们对应的数据存储在什么地方。

      通过在Excel中使用“分组和大纲”(Group and Outline)功能创建脚本和数据目录,如图2所示。针对每一个脚本记录,都能链接到相对应的数据文件,可以直接在表单中打开、修改和保存。

     

      图2

      每个数据文件都有多个工作表单,其中一个是默认的工作表单(如图3所示)。这个工作表单包含由脚本开发者提供的原始测试数据。  

     

    图3

      所有工作表单都有相同的结构:第一行包含标题头(参数名),而所有其他 行包含测试数据的值。拥有多行数据则表示这是个数据驱动的测试。如果要修改原始的局部测试数据,你应该创建一个以该测试集命名的工作表单,并在该表单中输入测试数据(如图4)。这样,不同测试集的局部数据可以与测试集的名字关联起来(规则5),并且可以共存于一个数据文件中(规则6)。

     

    图4

      我们使用以下简单的算法来访问局部测试数据。

      每个脚本根据测试集名称从工作表单中读取关联的属于脚本的数据。

      如果没有这样的工作表单,则自动读取“Default”表单中的默认数据。

      如果领域专家希望修改原始的测试数据,他们只需要根据测试集名称在Excel数据文件中创建一个工作表单。

      全局数据的实现

      让我们来看一种典型的情况。你组合了一个包含100个脚本的测试集合,这些脚本都是由其他人开发的。

      你继承了这些脚本的测试数据文件。每个测试集中的脚本都使用Server_Name来作为输入参数。

      但是问题是你的测试环境中的服务器名与原始的数据文件中定义的不一致。

      那么你如何避免因为修改100个数据文件中的服务器名而引入的错误呢?解决办法是使用全局数据(规则4)。

      对于在什么地方存储全局数据,有3种选择:Windows 注册表、环境变量、文件。其中一种方便的方式是通过环境变量,因为可以在Windos控制面板中通过系统工具方便地查看和编辑这些环境变量。每个测试集通过一个设置脚本(Setup scrīpt)来为所有全局数据创建环境变量。全局变量值是在名为Setup的Excel数据文件中的。

      测试集的名称是其中一种全局变量,它的值可以被每个脚本用于判断哪个工作表单包含脚本的局部数据(见图4所示的例子)。在某些测试自动化框架,例如HP的 Quality Center,脚本可以使用框架API来获取其所属的测试集的名称。这是个适用于所有框架的简单的解决方案。这个算法可以很容易地扩展成更为复杂的情况。

      不像其他脚本数据,Setup数据文件只有一个工作表单,列名以全局变量命名。其中两列是必须的,包括“Order”和“Test_Set”。

        Order列用于描述测试集由测试自动化框架组织执行的顺序。

       Test_Set列包含测试集的名称。工作表单中的每一行都代表一个测试集的全局变量值(见图5)。

     

       图5

      为了运行一系列的测试集,我们还需要定义一个环境变量TS_CURRENT,并且手工为其赋一个初始的值为1。

      在图5所示的测试集Smoke中,Setup脚本读取TS_CURRENT,并且创建环境变量,它们的值从Order数等于TS_CURRENT的数据行中读取。

      现在,测试集中的所有脚本在Setup访问了全局数据后都得以执行。由于Test_Set变量定义后,每个脚本也就知道了从哪个工作表单读取它们的局部数据。

      我们以一个Reset脚本来终止每个测试集,Reset脚本删除当前测试集的所有环境变量并且把TS_CURRENT的值累加1,以便执行下一个测试集。当回归测试集开始执行时,TS_CURRENT就变成了2。

      因此,在我们的实现过程中,每个测试集都包含表格1所示的脚本。

     

    表格1

      通过使用这个测试数据架构(你可在自己的测试环境中略作修改),你就可更加高效地管理你的测试数据,让其更标准、可重用性更强。以我的经验来看,以这种方式管理数据-使用测试自动化框架-让我的测试生活 变得轻松和有趣。

     

  • Object Repository(转)

    2011-03-10 16:16:38

    Types of Object in QTP:

     

    There are four types of object available in QTP.

     

    1. Run time objects
    2. Test objects
    3. Utility objects
    4. Automation objects/User defined objects.
  • 测试流程

    2011-02-25 11:20:36

1952/10<12345678910>
Open Toolbar