wholesale_price, retail_price, copies_available);
};
EXEC SQL CLOSE book_cursor;
}
代码是相当直观。它声明一些宿主变量,在一个BEGIN/END DECLARE SECTION构造中包装声明,打开一个SELECT光标查询,并且然后一行一行地取到宿主变量中,光标然后关闭。
我使用了更旧的, 遭到一致反对的sqlcode变量而不是更现代的sqlstate,因为这种方式更容易检查一个NOT FOUND情形。
把客户带入MySQL的生活
Mysql的C API是相当易用的。核心元素是包含有关数据库连接的信息和其状态的结构,它通过连接MySQL服务器进行初始化。该结构的一根指针必须被传递给所有的 MySQL 客户函数。
查询以字符串提交;这意味着一个人必须处理 C 字符串变换功能,包含空字节(\0) 的数据应该能使用,情况变得更复杂了,因为随后传递了一个计数字符串而不是一个 C字符串。
为了获取查询结果,一个指向MYSQL_RES结构的指针和一个数值变量用适当的 API 函数初始化,然后将一行取进一个MYSQL_ROW变量,它是一个字符串数组,直接将结果放进整数变量,就像Postgresql的ESQL的实现能做的那样,但这是不可能的,结果缓冲区随后被释放。只要你能理解,语义几乎与在ESQL使用光标相同。
list_books(void)
{
int count;
MYSQL_RES *result;
mysql_query(&bookstore, "SELECT ARTICLE_NO, AUTHOR_FIRST_NAMES,AUTHOR_LAST_NAMES, TITLE, ISBN, WHOLESALE_PRICE, RETAIL_PRICE,COPIES_AVAILABLE FROM BOOK");
result = mysql_store_result(&bookstore);
for(count = mysql_num_rows(result); count > 0; count--)
{
MYSQL_ROW record;
record = mysql_fetch_row(result);
printf("\nArticle no. %s\n", record[0]);
printf("%s, %s:\n", record[2], record[1]);
printf(" %s (%s)\n", record[3], record[4]);
printf("Bought at %s; selling at %s; %s copies available\n\n",
record[5], record[6], record[7]);
};
mysql_free_result(result);
}
mysql_free_result ( 结果 );
}
API函数简明扼要,但足够了, Texinfo格式的文档作为Mysql文档的主要来源。
把客户带入mSQL的
mSQL和Mysql C API 之间的差别非常非常小。这样, 甚至可能有一个自动变换器。主要的差别是:
mSQL 不存储连接数据块, 仅存一个数字(int bookstore)
一些 mSQL 函数不拿连接作为一个参数
mSQL 函数名字是Pascal风格(他们使用大写首字符而不是下划线)
方便的MONEY数据类型是一个有2个的十进制位的固定精度小数类型。为了使mSQL正确地在MONEY列中将分币(cent)存入整数数字里,我需要转换他们,强制到float,分离他们并且在add_new_book()函数中的sprintf语句格式化他们。
这是list_books(), 移植到 mSQL :
void
list_books(void)
{
int count;
m_result *result;
msqlQuery(bookstore, "SELECT ARTICLE_NO, AUTHOR_FIRST_NAMES,AUTHOR_LAST_NAMES, TITLE, ISBN, WHOLESALE_PRICE, RETAIL_PRICE,COPIES_AVAILABLE FROM BOOK");
result = msqlStoreResult();
for(count = msqlNumRows(result); count > 0; count--)
{
m_row record;