数据库

位置:IT落伍者 >> 数据库 >> 浏览文章

在MySQL数据库中使用C执行SQL语句


发布日期:2018年11月27日
 
在MySQL数据库中使用C执行SQL语句

与PostgreSQL相似可使用许多不同的语言来访问MySQL包括CC++Java和Perl从Professional Linux Programming中第章有关MySQL的下列章节中Neil Matthew和Richard Stones使用详尽的MySQL C接口向我们介绍了如何在MySQL数据库中执行SQL语句他们将讨论返回数据的语句例如INSERT以及不返回数据的语句例如UPDATE和DELETE然后他们将编写从数据库检索数据的简单程序

执行SQL语句

现在我们已经有了一个连接并且知道如何处理错误是时候讨论使用我们的数据库来作一些实际工作了执行所有类型的SQL的主关键字是mysql_query

int mysql_query(MYSQL *connection const char *query)

正如您所见它非常简单它取一个指向连接结构的指针和包含要执行的SQL的文本字符串与命令行工具不同将不使用结束分号成功之后返回在需要包含二进制数据的特殊情况下可以使用相关的函数mysql_real_query虽然出于本章的目的我们仅需要讨论mysql_query

不返回数据的SQL语句

我们将先讨论UPDATEDELETE和INSERT语句因为它们不返回数据所以更易于使用

这里我们将介绍的另一个重要函数是检查受影响的行数的函数

my_ulonglong mysql_affected_rows(MYSQL *connection);

可能关于这一函数的最显而易见的事就是其非同寻常的返回结果由于可移植性原因这是一个特殊的无符号类型为了在printf中使用建议将其强制转换成使用%lu格式规范的无符号长整数这个函数返回受以前的UPDATEINSERT或DELETE查询影响的行数这些查询是使用mysql_query执行的

通常对于mysql_函数返回码表示没有行受影响正数表示实际结果通常是受影响的行数

如前所述当使用mysql_affected_rows时可能出现未期望的结果让我们先讨论受INSERT语句影响的行数它将按预期进行操作将下列代码添加到程序 connectc 中并且称其为insertc

#include

#include

#include mysqlh

int main(int argc char *argv[]) {

MYSQL my_connection;

int res;

mysql_init(&my_connection);

if (mysql_real_connect(&my_connection localhost

rick bar rick NULL )) {

printf(Connection success\n);

res = mysql_query(&my_connection

INSERT INTO children(fnameage)

VALUES(Ann));

if (!res) {

printf(Inserted %lu rows\n

(unsigned long)mysql_affected_rows(&my_connection));

} else {

fprintf(stderr Insert error %d: s\nmysql_errno

(&my_connection)

mysql_error(&my_connection));

}

mysql_close(&my_connection);

} else {

fprintf(stderr Connection failed\n);

if (mysql_errno(&my_connection)) {

fprintf(stderr Connection error %d: %s\n

mysql_errno(&my_connection)

mysql_error(&my_connection));

}

}

return EXIT_SUCCESS;

}

正如预期插入的行数为

现在我们更改代码所以 insert 部分被替换成

mysql_errno(&my_connection) mysql_error(&my_connection));

}

}

res = mysql_query(&my_connection UPDATE children SET AGE =

WHERE fname = Ann);

if (!res) {

printf(Updated %lu rows\n

(unsigned long)mysql_affected_rows(&my_connection));

} else {

fprintf(stderr Update error %d: %s\n

mysql_errno(&my_connection)

mysql_error(&my_connection));

}

现在假设子表中有的数据如下

childno fname age

Jenny

Andrew

Gavin

Duncan

Emma

Alex

Adrian

Ann

Ann

Ann

Ann

如果我们执行update希望报告的受影响行数为但是实际上程序报告因为它仅必须更改虽然WHERE子句标识了如果想让mysql_affected_rows报告的结果为这可能是熟悉其它数据库的人所期望的)则需要记住将CLIENT_FOUND_ROWS标志传递到mysql_real_connect在 updatec中的程序如下

if (mysql_real_connect(&my_connection localhost

rick bar rick NULL CLIENT_FOUND_ROWS)) {

如果我们在数据库中复位数据然后运行带有这种修改的程序则它报告的行数为

函数mysql_affected_rows还有最后一个奇怪之处它发生在从数据库中删除数据时如果使用WHERE子句则mysql_affected_rows将按预期返回删除行数但是如果没有WHERE子句则删除所有行报告受影响的行数却为这是因为由于效率原因优化删除整个表这种行为不受CLIENT_FOUND_ROWS选项标志的影响

返回数据的语句

现在是时候讨论SQL的最普遍用法了从数据库检索数据的SELECT语句

MySQL 还支持返回结果的SHOWDESCRIBE和EXPLAIN SQL语句但是这里不考虑它们按惯例手册中包含这些语句的说明

您将会从PostgreSQL章记起可以从PQexec中的SQL SELECT 语句检索数据这里马上获取所有数据或者使用游标从数据库中逐行检索数据以便搞定大数据

由于完全相同的原因MySQL的检索方法几乎完全相同虽然它实际上不用游标的形式描述逐行检索但是它提供了缩小这两种方法间差异的API如果需要它通常使两种方法的互换更加容易

通常从MySQL数据库中检索数据有个阶段

发出查询

检索数据

处理数据

执行所需的任何整理

象以前一样我们使用mysql_query发出查询数据检索是使用mysql_store_result或mysql_use_result完成的这取决于想如何检索数据随后使用mysql_fetch_row调用序列来处理数据最后必须调用mysql_free_result以允许MySQL执行任何所需的整理

全部立即数据检索的函数

可以从SELECT语句(或其他返回数据的语句)中检索完所有数据在单一调用中使用mysql_store_result

MYSQL_RES *mysql_store_result(MYSQL *connection);

必须在mysql_query检索数据后才能调用这个函数以在结果集中存储该数据这个函数从服务器中检索所有数据并立即将它存储在客户机中它返回一个指向以前我们从未遇到过的结构(结果集结构)的指针如果语句失败则返回NULL

使用等价的PostgreSQL时应该知道返回NULL意味着已经发生了错误并且这与未检索到数据的情况不同即使返回值不是NULL也不意味着当前有数据要处理

如果未返回NULL则可以调用mysql_num_rows并且检索实际返回的行数它当然可能是

my_ulonglong mysql_num_rows(MYSQL_RES *result);

它从mysql_store_result取得返回的结果结构并且在该结果集中返回行数行数可能为如果mysql_store_result成功则mysql_num_rows也总是成功的

这种mysql_store_result和mysql_num_rows的组合是检索数据的一种简便并且直接的方法一旦mysql_store_result成功返回则所有查询数据都已经存储在客户机上并且我们知道可以从结果结构中检索它而不用担心会发生数据库或网络错误因为对于程序所有数据都是本地的还可以立即发现返回的行数它可以使编码更简便如前所述它将所有结果立即地发送回客户机对于大结果集它可能耗费大量的服务器网络和客户机资源由于这些原因使用更大的数据集时最好仅检索需要的数据不久我们将讨论如何使用mysql_use_result函数来完成该操作

一旦检索了数据则可以使用mysql_fetch_row来检索它并且使用mysql_data_seekmysql_row_seekmysql_row_tell操作结果集在开始检索数据阶段之前让我们先讨论一下这些函数

MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);

这个函数采用从存储结果中获取的结果结构并且从中检索单一行在行结构中返回分配给您的数据当没有更多数据或者发生错误时返回NULL稍后我们将回来处理这一行中的数据

void mysql_data_seek(MYSQL_RES *result my_ulonglong offset);

这个函数允许您进入结果集设置将由下一个获取操作返回的行offset是行号它必须在从到结果集中的行数减 的范围内传递将导致在下一次调用mysql_fetch_row时返回第一行

MYSQL_ROW_OFFEST mysql_row_tell(MYSQL_RES *res               

上一篇:MySQL的远程连接出现错误提示分析

下一篇:学会设置五大类MySQL参数