免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 5342 | 回复: 11
打印 上一主题 下一主题

[C] 请教Berkeley DB的游标操作 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-08-29 21:34 |只看该作者 |倒序浏览
网上翻了下,没有找到完整的测试代码,即使有c的api相关介绍也是列了一下流程,贴了少许代码,测试下不行。郁闷啊,请大家帮我看看。

版本是libdb4.6-dev

测试代码如下:
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <db.h>

  5. #define DBNAME "test.db"

  6. typedef struct emp {
  7.         int empid;
  8.         char lastname[50];
  9.         char firstname[50];
  10.         float salary;
  11. } emp_t;

  12. DB *openDB(const char *dbFile)
  13. {
  14.         DB *dbp = NULL;
  15.         int ret = 0;

  16.         ret = db_create(&dbp, NULL, 0);
  17.         if (ret != 0) {
  18.                 printf("ERROR: %s\n",db_strerror(ret));
  19.                 return NULL;
  20.         }
  21.         ret = dbp->open(dbp, NULL, dbFile, NULL, DB_BTREE, DB_CREATE, 0);
  22.         if (ret != 0) {
  23.                 printf("ERROR: %s\n",db_strerror(ret));
  24.                 return NULL;
  25.         }
  26.         return dbp;
  27. }

  28. int main(int argc, char* argv[])
  29. {
  30.         DB *dbp;
  31.         DBC *cursor;
  32.         int ret = 0;
  33.     DBT key, data;
  34.         emp_t emp;
  35.         if ((dbp = openDB(DBNAME)) == NULL) {
  36.                 printf("open failed\n");
  37.                 return 1;
  38.         }

  39.         /* insert */
  40.         while (1) {
  41.                 printf("Enter Employee ID: ");
  42.                 scanf("%d", &emp.empid);
  43.                 if (emp.empid == 0)
  44.                         break;
  45.                 printf("Enter Last name: ");
  46.                 scanf("%s", emp.lastname);
  47.                 printf("Enter first name: ");
  48.                 scanf("%s", emp.firstname);
  49.                 printf("Enter Salary: ");
  50.                 scanf("%f", &emp.salary);

  51.                 memset(&key, 0, sizeof(DBT));
  52.                 memset(&data, 0, sizeof(DBT));

  53.                 key.data = &(emp.empid);
  54.                 key.size = sizeof(emp.empid);
  55.                 data.data = &emp;
  56.                 data.size = sizeof(emp_t);

  57.                 ret = dbp->put(dbp, NULL, &key, &data, DB_NOOVERWRITE);
  58.                 if (ret != 0) {
  59.                         printf("Employee ID exists\n");
  60.                         continue;
  61.                 }
  62.         }

  63.         /* search */
  64.         while (1) {
  65.                 printf("Enter Employee ID you wana search: ");
  66.                 scanf("%d", &emp.empid);
  67.                 if (emp.empid == 0)
  68.                         break;
  69.                 memset(&key, 0, sizeof(DBT));
  70.                 memset(&data, 0, sizeof(DBT));

  71.                 key.data = &(emp.empid);
  72.                 key.size = sizeof(emp.empid);
  73.                 data.data = &emp;
  74.                 data.ulen = sizeof(emp_t);
  75.                 data.flags = DB_DBT_USERMEM;
  76.                 ret = dbp->get(dbp, NULL, &key, &data, 0);
  77.                 if (ret != 0) {
  78.                         printf("Employee ID doesn't exist\n");
  79.                 } else {
  80.                         printf("  Employee: %d - %s, %s\n  Salary: $%.2lf\n", emp.empid, emp.lastname, emp.firstname, emp.salary);
  81.                 }
  82.         }

  83.         /* delete */
  84.         while (1) {
  85.                 printf("Enter Employee ID you wana delete: ");
  86.                 scanf("%d", &emp.empid);
  87.                 if (emp.empid == 0)
  88.                         break;
  89.                 memset(&key, 0, sizeof(DBT));
  90.                 memset(&data, 0, sizeof(DBT));

  91.                 key.data = &(emp.empid);
  92.                 key.size = sizeof(emp.empid);

  93.                 ret = dbp->del(dbp, NULL, &key, 0);
  94.                 if (ret != 0) {
  95.                         if (ret == DB_NOTFOUND)
  96.                                 printf("Employee ID doesn't exist\n");
  97.                 } else {
  98.                         printf("  Employee %d deleted.\n", emp.empid);
  99.                 }

  100.         }

  101.         /* cursor */
  102.         ret = dbp->cursor(dbp, NULL, &cursor, 0);
  103.         if (ret != 0) {
  104.                 printf("ERROR: %s\n",db_strerror(ret));
  105.                 return 1;
  106.         }
  107.         memset(&key, 0, sizeof(DBT));
  108.         memset(&data, 0, sizeof(DBT));
  109.         data.data = &emp;
  110.         data.size = sizeof(emp);
  111.         /* data.flags = DB_DBT_USERMEM; */

  112.         while ((ret = cursor->get(cursor, &key, &data, DB_NEXT)) == 0) {
  113.                 printf("ret = %d\n", ret);
  114.                 printf("%d - %s, %s    $%.2lf\n", emp.empid, emp.lastname, emp.firstname, emp.salary);
  115.                 memset(&key, 0, sizeof(DBT));
  116.                 memset(&data, 0, sizeof(DBT));
  117.         }
  118.         if (ret < 0) {
  119.                 printf("ERROR: %s\n",db_strerror(ret));
  120.         }
  121.         cursor->close(cursor);

  122.         dbp->close(dbp, 0);

  123.         return 0;
  124. }
复制代码
gcc -Wall test.c -ldb即可
首先提示你输入一些数据,id, 用户名,薪水。然后是测试查找,删除,这些都是没有问题。输入0可以退出一个测试项目
关键是下面的游标,加上DB_DBT_USERMEM,还报“ERROR: DB_BUFFER_SMALL: User memory too small for return value”
游标还不能打出数据,请教到底何处写错了?

论坛徽章:
0
2 [报告]
发表于 2010-08-29 23:15 |只看该作者
memset(&key, 0, sizeof(DBT));
memset(&data, 0, sizeof(DBT));

是不是循环里面,这两行的缘故?还有,key在外面也是初始化为0,为啥?

论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
3 [报告]
发表于 2010-08-30 11:05 |只看该作者
网上翻了下,没有找到完整的测试代码,即使有c的api相关介绍也是列了一下流程,贴了少许代码,测试下不行。 ...
bsdc 发表于 2010-08-29 21:34



很喜欢berkekeyDB的这种用法,最近把ORACLE也弄成这样了,直接用结构读写数据库。
没用过这个,有一个问题,cursor是需要定义数据访问语句的,或定义一个数据范围,你为何用NULL定义?应该定义成什么?

论坛徽章:
0
4 [报告]
发表于 2010-08-30 12:45 |只看该作者
回复 1# bsdc
我用你的代码在新版本的bdb上运行是没有问题的。


http://www.oracle.com/technetwor ... ownloads/index.html

论坛徽章:
0
5 [报告]
发表于 2010-08-30 12:50 |只看该作者
回复 3# yulihua49
他那个null是txn参数。 bdb的cursor在调用get的时候可以指定一范围参数。请参考:
http://download.oracle.com/docs/ ... g.html#cursorsearch

论坛徽章:
0
6 [报告]
发表于 2010-08-30 15:15 |只看该作者
哇,见识了。这个数据库操起来真简单。

论坛徽章:
0
7 [报告]
发表于 2010-08-30 15:17 |只看该作者
同意2楼,感觉132这两行有问题
        data.data = &emp;
        data.size = sizeof(emp);
        /* data.flags = DB_DBT_USERMEM; */
是不是要放循环里,或者就不用DB_DBT_USERMEM ,直接用db的内存地址

论坛徽章:
0
8 [报告]
发表于 2010-08-30 19:26 |只看该作者
125行,没有对
key.data
key.size
进行赋值,设置吧

论坛徽章:
0
9 [报告]
发表于 2010-08-30 21:56 |只看该作者
已经从老外的dba网站上看到原因了,没有设置data的ulen成员大小,ulen我猜想是user memory的大小,具体可以参考手册,有空看看,
重新贴出coursor部分代码
/* cursor */
        ret = dbp->cursor(dbp, NULL, &cursor, 0);
        if (ret != 0) {
                printf("ERROR: %s\n",db_strerror(ret));
                return 1;
        }
        memset(&key, 0, sizeof(DBT));
        memset(&data, 0, sizeof(DBT));
        data.data = &emp;
        data.ulen = sizeof(emp);
        data.flags = DB_DBT_USERMEM;

        while ((ret = cursor->get(cursor, &key, &data, DB_NEXT)) == 0) {
                printf("%d - %-8s,%8s    $%.2lf\n", emp.empid, emp.lastname, emp.firstname, emp.salary);
        }
        cursor->close(cursor);

论坛徽章:
0
10 [报告]
发表于 2010-08-30 21:58 |只看该作者
另外,我是参考<<  Professional Linux programming>>里的,那里的代码真不敢恭维,难道是翻译版给整错了?代码写出好多毛病啊,而且还不对。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP