51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

查看: 6574|回复: 11
打印 上一主题 下一主题

[原创] loadrunner9.0动态访问oracl数据库

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2009-7-9 15:27:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
最近在公司搞loadrunner脚本,需要访问数据库取一个动态值,在网上看到的一个是通过loadrunner的parameters自动生成一个表格,但这个东西是静态的,不会随着脚本的运行而变化,还有就是大神kernzhang流传的getdata.dll,但是执行sql无法获得结果,他的个人主页也打不开了-_-!!!无法得到源码,根本不知道咋用
       最后通过lrd系列的函数解决了这个问题,现在跟大家分享一下!!!它是基于odbc访问数据库的原理,主要的东西除了在帮助中,还有就是看看lrd.h中的定义说明
#include<lrd.h>
static LRD_INIT_INFO InitInfo={LRD_INIT_INFO_EYECAT};
static LRD_DEFAULT_DB_VERSION DBTypeVersion[]={{LRD_DBTYPE_NONE,LRD_DBVERSION_NONE}};

//这里的LRD_VAR_DESC数据结构声明是很重要的,他是用来存储sql结果数据集的结构体,第一个参数头文件中就是这么写的,第二个参数是最大行数,第三个参数是每一行的最大长度,如果获得的查询结果比定义的长,运行时就会报错,提示列被截断,最后一个参数是查询结果的类型,可以再帮助中的索引输入data types, database,列出的表格中是各种变量类型的名称
static LRD_VAR_DESC NUM ={LRD_VAR_DESC_EYECAT, 10, 32, LRD_DBTYPE_ORACLE, {1, 1, 0},DT_LONG_VARCHAR};

//下面这些句柄等变量的申请都可以照着帮助中的例子写
static void FAR * OraEnv1;
static void FAR * OraSvc1;
static void FAR * OraSrv1;
static void FAR * OraSes1;
static void FAR * OraStm1;
static void FAR * OraDef1;
unsigned long rownum;

vuser_init()
{
//初始化数据库   
lrd_init(&InitInfo,DBTypeVersion);
lrd_initialize_db(LRD_DBTYPE_ORACLE,3,0);
lrd_env_init(LRD_DBTYPE_ORACLE,&OraEnv1,0,0);
lrd_ora8_handle_alloc(OraEnv1,SVCCTX,&OraSvc1,0);
lrd_ora8_handle_alloc(OraEnv1,SERVER,&OraSrv1,0);
lrd_ora8_handle_alloc(OraEnv1,SESSION,&OraSes1,0);

//设置数据库名称,我的是oracle,odbc中连接数据库名称就是这个
lrd_server_attach(OraSrv1,"db_192.168.0.101",-1,0,0);
lrd_ora8_attr_set_from_handle(OraSvc1,SERVER,OraSrv1,0,0);

//用户名和密码
lrd_ora8_attr_set(OraSes1,USERNAME,"eeim2",-1,0);
lrd_ora8_attr_set(OraSes1,PASSWORD,"eeim2",-1,0);
lrd_ora8_attr_set_from_handle(OraSvc1,SESSION,OraSes1,0,0);
lrd_session_begin(OraSvc1,OraSes1,1,0,0);
lrd_ora8_handle_alloc(OraEnv1,STMT,&OraStm1,0);
return 0;
}

Action()
{
//这里写上你的sql语句(我主要是需要查询的结果,如果你是插入或修改记录就不用往后看了)
lrd_ora8_stmt(OraStm1,"select R_V from ce_receviablecharge where user_no = 2009070901",1,0,0);

//执行定义的sql,并且将结果行数返回到rownum中
lrd_ora8_exec(OraSvc1,OraStm1,0,0,&rownum,0,0,0,0,1);

//绑定该列
lrd_ora8_bind_col(OraStm1,&OraDef1,1,&NUM,0,0);

//设定保存列中的某个数据到row中,第二个参数为第几列,第三个参数为第几行(只能保存一个值),最后一个参数就是你想要保存到的parameter名称
lrd_ora8_save_col(OraStm1, 1, 1, 0, "result");

//这个遍历刚才查询的结果,第二个参数0表示就1行,负号表示遍历所有结果,绝对值表示实际有多少行,第三个参数表示一次遍历最大进行多少行(不能大于LRD_VAR_DESC中定义的第二个参数,即最大行数)
lrd_ora8_fetch(OraStm1, -2 2 &rownum, 0, 2, 0, 0);

//这里我用error是为了看得醒目,不要认为是出错了
lr_error_message("sql result: %s", lr_eval_string("{result}"));
return 0;
}

vuser_end()
{
lrd_session_end(OraSvc1, OraSes1, 0, 0);
lrd_server_detach(OraSrv1, 0, 0);
lrd_handle_free(&OraEnv1, 0);
return 0;
}
到此就结束了,但是这个东西目前我只是支持取出一个结果放到parameter中,还搞不懂如和将所有数据放入parameter中,来作为自动化时多用户使用的参数。在此抛砖引玉,希望有达人能够解决!!!
另外要注意的是,如果你是录制了一个http协议的脚本,那么编译时无法通过的,需要创建一个odbc和http协议的混合脚本写入这些代码,然后再创建一个http脚本进行录制,然后将http中录制的脚本内容拷贝过来。俺也不知道为什么,如果我先录制脚本再插入这些代码总是提示lrd_init()未知错误:
vuser_init.c(19): Error: C interpreter run time error: vuser_init.c (19):  Error -- Unresolved symbol : lrdfnc_init.
vuser_init.c(19): Notify: CCI trace: Compiled_code(0): vuser_init()

这个东西后来我将sql语句进行了参数化,这样可以保证每个模拟的用户得到不同的值(别忘了在参数中选择Unique)。关联也可以取得这些参数,但是我那个录制的脚本中无法自动关联,手动关联只有调出所有日志,才能找到服务器发送的参数,一次20分钟。。。。。。而且长时间运行有时候会偶尔出现找不到参数信息,怀疑是由于发送消息超时的原因。
使用数据库会造成数据库服务器的负荷,如果进行数据库测试,建议使用关联,否则可能影响服务器性能

[ 本帖最后由 圣炬骑士 于 2009-7-28 10:09 编辑 ]
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1
回复

使用道具 举报

  • TA的每日心情
    奋斗
    2015-6-25 18:04
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]测试小兵

    2#
    发表于 2009-7-10 09:48:51 | 只看该作者
    看看,学习,谢谢楼上。
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    3#
    发表于 2009-7-10 14:00:41 | 只看该作者
    学习了  可以通过个小工具生成数据  然后导入lr中 运行脚本  这样不是很简单吗  是不是我理解错误了
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    4#
    发表于 2009-7-16 17:12:10 | 只看该作者
    楼上的理解简单了。

    谢谢楼主的奉献
    需要试验下
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    5#
    发表于 2009-7-16 17:38:19 | 只看该作者
    刚验证了,楼主的脚本是可以运行的。。。。

    有个小问题  lrd_ora8_fetch(OraStm1, -2, 2 ,&rownum, 0, 2, 0, 0);
    楼主的参数里,缺了几个逗号,加上就可以了。。


    再次感谢楼主的奉献,
    之前也是因为从Oracle数据库动态取值做脚本,着实为难了一阵,
    我们是通过动态库,从数据库取值的,
    不过后来在场景里多并发时,报错。。。
    我试试楼主的方法。。。,看看会不会还有问题。。。
    应该不会有问题了。


    当时怎么没想到这个方法呢。。。。
    就想着用动态库了。。
    也研究过类似的脚本
    但是和动态取值,没联系起来

    go go go
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    6#
    发表于 2009-8-19 15:33:42 | 只看该作者
    恩,这个中方法我已经思考几天了,可无从下手,今天看到楼主的程序,豁然明白了!谢谢楼主的分享!
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    7#
    发表于 2009-8-19 15:36:50 | 只看该作者
    还有问下楼主,能告诉我你是参考那些资料的吗?十分感谢!
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    8#
    发表于 2009-8-31 17:04:44 | 只看该作者

    回复 7# 的帖子

    很久没上了,今天上网查资料才发现这个帖子很多地方进行了转载,窃喜 。当时就是看的loadrunner的帮助文档,英文啊,头疼死了!!照着里面的例子一点点实验呗,loadrunner没有单步调试功能,十分不爽。。。。
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    9#
    发表于 2009-9-7 09:37:59 | 只看该作者
    这次有点明白了
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    10#
    发表于 2009-9-7 12:21:49 | 只看该作者
    此贴甚好,要顶。不过我在使用的过程中,碰到一个问题,就是如果查询结果存在多条记录,只能查询第一列,第一行,就算绑定其他的列或者行都不行,不知道要修改哪些地方。。高手指点哈
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    11#
    发表于 2013-11-4 16:21:28 | 只看该作者
    时隔多年,请问还有人回答吗?
    问题如下,编译报错:
    vuser_init.c (9): syntax error; found `InitInfo' expecting `;'
    vuser_init.c (9): undeclared identifier `LRD_INIT_INFO_EYECAT'
    vuser_init.c (9): initializer must be constant
    vuser_init.c (10): syntax error; found `DBTypeVersion' expecting `;'
    vuser_init.c (10): undeclared identifier `LRD_DBTYPE_NONE'
    vuser_init.c (10): syntax error; found `,' expecting `}'
    vuser_init.c (10): skipping `,' `LRD_DBVERSION_NONE'
    vuser_init.c (10): initializer must be constant

    脚本如下:
    #include "lrs.h"

    static LRD_INIT_INFO InitInfo={LRD_INIT_INFO_EYECAT};
    static LRD_DEFAULT_DB_VERSION DBTypeVersion[]={{LRD_DBTYPE_NONE,LRD_DBVERSION_NONE}};


    static LRD_VAR_DESC NUM ={LRD_VAR_DESC_EYECAT, 10, 32, LRD_DBTYPE_ORACLE, {1, 1, 0},DT_LONG_VARCHAR};



    static void FAR * OraEnv1;
    static void FAR * OraSvc1;
    static void FAR * OraSrv1;
    static void FAR * OraSes1;
    static void FAR * OraStm1;
    static void FAR * OraDef1;
    unsigned long rownum;

    vuser_init()
    {

    //初始化数据库   
    lrd_init(&InitInfo,DBTypeVersion);
    lrd_initialize_db(LRD_DBTYPE_ORACLE,3,0);
    lrd_env_init(LRD_DBTYPE_ORACLE,&OraEnv1,0,0);
    lrd_ora8_handle_alloc(OraEnv1,SVCCTX,&OraSvc1,0);
    lrd_ora8_handle_alloc(OraEnv1,SERVER,&OraSrv1,0);
    lrd_ora8_handle_alloc(OraEnv1,SESSION,&OraSes1,0);

    //设置数据库名称,我的是oracle,odbc中连接数据库名称就是这个
    lrd_server_attach(OraSrv1,"SCPRD",-1,0,0);
    lrd_ora8_attr_set_from_handle(OraSvc1,SERVER,OraSrv1,0,0);

    //用户名和密码
    lrd_ora8_attr_set(OraSes1,USERNAME,"ORACLE",-1,0);
    lrd_ora8_attr_set(OraSes1,PASSWORD,"ORACLE123456",-1,0);
    lrd_ora8_attr_set_from_handle(OraSvc1,SESSION,OraSes1,0,0);
    lrd_session_begin(OraSvc1,OraSes1,1,0,0);
    lrd_ora8_handle_alloc(OraEnv1,STMT,&OraStm1,0);
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    12#
    发表于 2017-4-25 10:31:16 | 只看该作者
    //下面这些句柄等变量的申请都可以照着帮助中的例子写
    static void FAR * OraEnv1;
    static void FAR * OraSvc1;
    static void FAR * OraSrv1;
    static void FAR * OraSes1;
    static void FAR * OraStm1;
    static void FAR * OraDef1;
    unsigned long rownum;


    咨询下大家,这些变量在此声明了,后续脚本中也在直接使用,但是没看出来是在哪里对这些变量赋值的,烦请知情人告知下,万分感激。
    回复 支持 反对

    使用道具 举报

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条

    小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

    GMT+8, 2024-4-30 18:24 , Processed in 0.081812 second(s), 26 queries .

    Powered by Discuz! X3.2

    © 2001-2024 Comsenz Inc.

    快速回复 返回顶部 返回列表