第一个方法与上面的插入代码一样 — 如果您在一个表上使用 PUT 方法并且该键已存在 (且表不允许单键有相同的数值), PUT 将使用新版本代替旧版本。因此,以下步骤将使用新记录替换 Mickey 的记录,薪水将为 $2,000,000,而不是 $1,000,000。
|
/* Put the value into the employee key. */ ekey = 00010002; /* Initialize an emp_data structure. */ strcpy(edata.lname, "Mouse"); strcpy(edata.fname, "Mickey"); edata.salary = 2000000.00; strcpy(edata.street, "Main Street"); strcpy(edata.city, "Disney Land"); strcpy(edata.state, "CA"); edata.zip = 98765; /* Initialize DBTs */ memset(&key_dbt, 0, sizeof(key_dbt)); memset(&data_dbt, 0, sizeof(data_dbt)); /* Now, assign key and data values to DBTs. */ key->data = &ekey; key->size = sizeof(ekey); data->data = &edata; data->size = sizeof(edata); /* Finally, put the data into the database. */ ASSERT(dbp->put(dbp, NULL, &key_dbt, &data_dbt, DB_AUTO_COMMIT) == 0); |
请注意,该方法较麻烦,为完成它,您需要了解数据库中所有其他域的值。因此,不同于
UPDATE employees SET salary = 2000000 WHERE empid = 000100002
其中,您只需知晓 employee ID,而现在需要知晓所有信息。难道在 Berkeley DB 没有可用方法吗?答是是有。如果确切地知道要替换的数据项字节,您可以使用与等同于更新命令的方法。
要使用此方法,您需要引入游标概念。游标表示表中的某个位置。它让您遍历表并保留当前项的情况,然后再对其操作。
在 Berkeley DB 中创建游标很简单 — 它是数据库句柄的方法:
|
DBC *dbc; DB *dbp; ASSERT(dbp->cursor(dbp, NULL, 0) == 0); |
有游标后,我们需要将其定位于 Mickey 的记录,以便能对其进行更新。这等同于 SQL 语句的 WHERE 部分。
|
DBT key_dbt, data_dbt; emp_data *edata; emp_key ekey; /* We'd like to look up Mickey's key. */ emp_key = 0010002; memset(&key_dbt, 0, sizeof(key_dbt)); key_dbt.data = &emp_key; key_dbt.size = sizeof(emp_key); /* * We want the data returned, so we don't need to initialize the * employee data data structure. */ memset(&data_dbt, 0, sizeof(data_dbt)); /* Now, set the cursor to the record with the key emp_key. */ dbc->c_get(dbc, &key_dbt, &data_dbt, DB_SET); |
接下来我们就可以更改薪水了 (处理子句的“SET salary=2000000”部分)
|
/* Change the salary. */ edata = data_dbt->data; edata.salary = 2000000; |
最后,应用 SQL 语句的 UPDATE 部分:
dbc->c_put(dbc, &key_dbt, &data_dbt, DB_CURRENT);
在本例中,您事先不知道 Mickey 的记录内容,因此需要检索然后再更新。
或者,甚至无需检索记录。DBT 上的 DB_DBT_PARTIAL 标记值指示您在获取/插入记录的一部分,所以 Berkeley DB 可以忽略除该部分外的所有内容。
再试一次:
|
emp_data edata; float salary; /* We'd like to look up Mickey's key. */ emp_key = 0010002; memset(&key_dbt, 0, sizeof(key_dbt)); key_dbt.data = &emp_key; key_dbt.size = sizeof(emp_key); |
不检索整个记录,不检索任何东西 — 即执行 PARTIAL 获取,指定您只需要 0 字节的数据项。
|
/* We don't want the data, we just want to position the cursor. */ memset(&data_dbt, 0, sizeof(data_dbt)); data_dbt->flags = DB_DBT_PARTIAL; data_dbt->dlen = 0; /* Position the cursor on Mickey's record */ dbc->c_get(dbc, &key_dbt, &data_dbt, DB_SET); /* * Now, prepare for a partial put. Note that the DBT has already * been initialized for partial operations. We need to specify * where in the data item we wish to place the new bytes and * how many bytes we'd like to replace. */ salary = 2000000.00; /* The DBT contains just the salary information. */ data_dbt->data = &salary; data_dbt->size = sizeof(salary); /* * dlen and doff tell Berkeley DB where to place this information * in the record. dlen indicates how many bytes we are replacing -- * in this case we're replacing the length of the salary field in * the structure (sizeof(emp_data.salary)). doff indicates where * in the data record we will place these new bytes -- we need to * compute the offset of the salary field. */ data_dbt->dlen = sizeof(emp_data.salary); data_dbt->doff = ((char *)&edata.salary - (char *)&edata); /* Now, put the record back with the new data. */ dbc->c_put(dbc, &key_dbt, &data_dbt, DB_CURRENT); |
数据检索
了解如何向表插入数据后,现在学习如何检索它。让我们从最简单的方法开始:根据其主键查找值。
SELECT * FROM employees WHERE id=0010002
您已经知道如何使用游标来完成此任务:
|
DBT key_dbt, data_dbt; emp_data *edata; emp_key ekey; /* We'd like to look up Mickey's key. */ emp_key = 0010002; memset(&key_dbt, 0, sizeof(key_dbt)); key_dbt.data = &emp_key; key_dbt.size = sizeof(emp_key); /* * We want the data returned, so we don't need to initialize the * employee data data structure. */ memset(&data_dbt, 0, sizeof(data_dbt)); /* Now, set the cursor to the record with the key emp_key. */ dbc->c_get(dbc, &key_dbt, &data_dbt, DB_SET); |