執行SQL語句
現在,我們已經有了一個連接,並且知道如何處理錯誤,是時候討論使用我們的數據庫來作一些實際工作了。執行所有類型的SQL的主關鍵字是mysql_query:
int mysql_query(MYSQL *connection, const char *query)
my_ulonglong mysql_affected_rows(MYSQL *connection);
#include
#include
#include "mysql.h"
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", 0, NULL, 0)) {
printf("Connection success\n");
res = mysql_query(&my_connection,
"INSERT INTO children(fname,age),
VALUES('Ann',3)");
if (!res) {
printf("Inserted %lu rows\n",
(unsigned long)mysql_affected_rows(&my_connection));
} else {
fprintf(stderr, "Insert error %d: s\n",mysql_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;
}
mysql_errno(&my_connection), mysql_error(&my_connection));
}
}
res = mysql_query(&my_connection, "UPDATE children SET AGE = 4
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));
}
2
3
4
5
6
7
8
9
10
11
JennyAndrew
Gavin
Duncan
Emma
Alex
Adrian
Ann
Ann
Ann
Ann
1410
4
2
0
11
5
3
4
3
4
if (mysql_real_connect(&my_connection, "localhost",
"rick", "bar", "rick", 0, NULL, CLIENT_FOUND_ROWS)) {
如果我們在數據庫中復位數據,然後運行帶有這種修改的程序,則它報告的行數為4。
函數mysql_affected_rows還有最後一個奇怪之處,它發生在從數據庫中刪除數據時。如果使用WHERE子句,則 mysql_affected_rows將按預期返回刪除行數。但是,如果沒有WHERE子句,則刪除所有行,報告受影響的行數卻為0。這是因為由於效率原因優化刪除整個表。這種行為不受CLIENT_FOUND_ROWS選項標志的影響。
現在是時候討論SQL的最普遍用法了,從數據庫檢索數據的SELECT語句。
MySQL 還支持返回結果的SHOW、DESCRIBE和EXPLAIN SQL語句,但是這裡不考慮它們。按慣例,手冊中包含這些語句的說明。
您將會從PostgreSQL章記起,可以從PQexec中的SQL SELECT 語句檢索數據,這裡馬上獲取所有數據,或者使用游標從數據庫中逐行檢索數據,以便搞定大數據。
由於完全相同的原因,MySQL的檢索方法幾乎完全相同,雖然它實際上不用游標的形式描述逐行檢索。但是,它提供了縮小這兩種方法間差異的API,如果需要,它通常使兩種方法的互換更加容易。
通常,從MySQL數據庫中檢索數據有4個階段:
發出查詢
檢索數據
處理數據
執行所需的任何整理
象以前一樣,我們使用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);
my_ulonglong mysql_num_rows(MYSQL_RES *result);
MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);
void mysql_data_seek(MYSQL_RES *result, my_ulonglong offset);
MYSQL_ROW_OFFEST mysql_row_tell(MYSQL_RES *result);
MYSQL_ROW_OFFSET mysql_row_seek(MYSQL_RES *result, MYSQL_ROW_OFFSET offset);
void mysql_free_result(MYSQL_RES *result);
現在開始編寫從數據庫中檢索數據的第一個程序。我們將選擇所有年齡大於5的行的內容。不幸的是我們還不知道如何處理這個數據,所以我們能做的只有循環檢索它。這便是 select1.c:
#include
#include
#include "mysql.h"
MYSQL my_connection;
MYSQL_RES *res_ptr;
MYSQL_ROW sqlrow;
int main(int argc, char *argv[]) {
int res;
mysql_init(&my_connection);
if (mysql_real_connect(&my_connection, "localhost", "rick",
"bar", "rick", 0, NULL, 0)) {
printf("Connection success\n");
res = mysql_query(&my_connection, "SELECT childno, fname,
age FROM children WHERE age > 5");
if (res) {
printf("SELECT error: %s\n", mysql_error(&my_connection));
} else {
res_ptr = mysql_store_result(&my_connection);
if (res_ptr) {
printf("Retrieved %luows\n",(unsignedlong)mysql_num_rows(res_ptr));
while ((sqlrow = mysql_fetch_row(res_ptr))) {
printf("Fetched data...\n");
}
if (mysql_errno(&my_connection)) {
fprintf(stderr, "Retrive error: s\n",mysql_error(&my_connection));
}
}
mysql_free_result(res_ptr);
}
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;
}
MYSQL_RES *mysql_use_result(MYSQL *connection);