在MySQL數據庫中應用C履行SQL語句的辦法。本站提示廣大學習愛好者:(在MySQL數據庫中應用C履行SQL語句的辦法)文章只能為提供參考,不一定能成為您想要的結果。以下是在MySQL數據庫中應用C履行SQL語句的辦法正文
他們將評論辯論前往數據的語句,例如INSERT和不前往數據的語句,例如UPDATE和DELETE。然後,他們將編寫從數據庫檢索數據的簡略法式
履行SQL語句
如今,我們曾經有了一個銜接,而且曉得若何處置毛病,是時刻評論辯論應用我們的數據庫來作一些現實任務了。履行一切類型的SQL的主症結字是mysql_query:
int mysql_query(MYSQL *connection, const char *query)
正如您所見,它異常簡略。它取一個指向銜接構造的指針和包括要履行的SQL的文本字符串;與敕令行對象分歧,將不應用停止分號。勝利以後,前往0。在須要包括二進制數據的特別情形下,可使用相干的函數,mysql_real_query。固然出於本章的目標,我們僅須要評論辯論mysql_query。
不前往數據的SQL語句
我們將先評論辯論UPDATE、DELETE和INSERT語句。由於它們不前往數據,所以更容易於應用。
這裡我們將引見的另外一個主要函數是檢討受影響的行數的函數:
my_ulonglong mysql_affected_rows(MYSQL *connection);
能夠關於這一函數的最不言而喻的事就是其非同平常的前往成果。因為可移植性緣由,這是一個特別的無符號類型。為了在printf中應用,建議將其強迫轉換成應用%lu格局標准的無符號長整數。這個函數前往受之前的UPDATE、INSERT或DELETE查詢影響的行數,這些查詢是應用mysql_query履行的。
平日關於mysql_函數,前往碼0表現沒有行受影響;負數表現現實成果,平日是受影響的行數。
如前所述,當應用mysql_affected_rows時能夠湧現未希冀的成果。讓我們先評論辯論受INSERT語句影響的行數,它將按預期停止操作。將以下代碼添加到法式 connect2.c 中,而且稱其為insert1.c:
#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;
}
正如預期,拔出的行數為1。
如今,我們更改代碼,所以 'insert' 部門被調換成:
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));
}
如今假定子表中有的數據,以下:
childno
fname
age
1
2
3
4
5
6
7
8
9
10
11
Jenny
Andrew
Gavin
Duncan
Emma
Alex
Adrian
Ann
Ann
Ann
Ann
14
10
4
2
0
11
5
3
4
3
4
假如我們履行update1,願望申報的受影響行數為4,然則現實上法式申報2,由於它僅必需更改2行,固然WHERE子句標識了4行。假如想讓mysql_affected_rows申報的成果為4這能夠是熟習其它數據庫的人所希冀的),則須要記住將CLIENT_FOUND_ROWS標記傳遞到mysql_real_connect,在 update2.c中的法式以下:
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);
必需在mysql_query檢索數據後能力挪用這個函數,以在成果集中存儲該數據。這個函數從辦事器中檢索一切數據並立刻將它存儲在客戶機中。它前往一個指向之前我們從未碰到過的構造(成果集構造)的指針。假如語句掉敗,則前往NULL。
應用等價的PostgreSQL時,應當曉得前往NULL意味著曾經產生了毛病,而且這與未檢索到數據的情形分歧。即便,前往值不是NULL,也不料味著以後稀有據要處置。
假如未前往NULL,則可以挪用mysql_num_rows而且檢索現實前往的行數,它固然能夠是0。
my_ulonglong mysql_num_rows(MYSQL_RES *result);
它從mysql_store_result獲得前往的成果構造,而且在該成果集中前往行數,行數能夠為0。假如mysql_store_result勝利,則mysql_num_rows也老是勝利的。
這類mysql_store_result和mysql_num_rows的組合是檢索數據的一種輕便而且直接的辦法。一旦mysql_store_result勝利前往,則一切查詢數據都曾經存儲在客戶機上而且我們曉得可以從成果構造中檢索它,而不消擔憂會產生數據庫或收集毛病,由於關於法式一切數據都是當地的。還可以立刻發明前往的行數,它可使編碼更輕便。如前所述,它將一切成果立刻地發送回客戶機。關於年夜成果集,它能夠消耗年夜量的辦事器、收集和客戶機資本。因為這些緣由,應用更年夜的數據集時,最好僅檢索須要的數據。不久,我們將評論辯論若何應用mysql_use_result函數來完成該操作。
一旦檢索了數據,則可使用mysql_fetch_row來檢索它,而且應用mysql_data_seek、mysql_row_seek、mysql_row_tell操作成果集。在開端檢索數據階段之前,讓我們先評論辯論一下這些函數。
MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);
這個函數采取從存儲成果中獲得的成果構造,而且從中檢索單一行,外行構造中前往分派給您的數據。當沒有更多半據或許產生毛病時,前往NULL。稍後,我們將回來處置這一行中的數據。
void mysql_data_seek(MYSQL_RES *result, my_ulonglong offset);
這個函數許可您進入成果集,設置將由下一個獲得操作前往的行。offset是行號,它必需在從0到成果集中的行數減 1 的規模內。傳遞0將招致鄙人一次挪用mysql_fetch_row時前往第一行。
MYSQL_ROW_OFFEST mysql_row_tell(MYSQL_RES *result);
這個函數前往一個偏移值,它表現成果集中確當前地位。它不是行號,不克不及將它用於mysql_data_seek。然則,可將它用於:
MYSQL_ROW_OFFSET mysql_row_seek(MYSQL_RES *result, MYSQL_ROW_OFFSET offset);
它挪動成果集中確當前地位,並前往之前的地位。
有時,這一對函數關於在成果集中的已知點之間跳轉很有效。請留意,不要將row tell和row seek應用的偏移值與data_seek應用的行號混雜。這些是弗成交流的,成果將是您所願望看到的。
void mysql_free_result(MYSQL_RES *result);
完成成果集時, 必需老是挪用這個函數,以許可MySQL庫整頓分派給它的對象。
檢索數據
如今開端編寫從數據庫中檢索數據的第一個法式。我們將選擇一切年紀年夜於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_store_result挪用調換成 mysql_use_result:
MYSQL_RES *mysql_use_result(MYSQL *connection);
這個函數還獲得一個銜接對象並前往成果聯合指針,或許失足時前往NULL。與mysql_store_result類似,它前往指向成果集對象的指針;症結的分歧點在於前往時,現實上未將任何數據檢索到成果集,只是初始化成果集以預備好檢索數據。
參考材料
您可以參閱本文在developerWorks全球站點上的英文原文.
本文章取自Wrox Press Ltd出書的Professional Linux一書的第5章。
關於作者
Rick Stones是一名體系設計師,他在一家年夜型泛歐制藥分銷和分派公司的IT部分任務。從1985年開端,他一向在應用各類情勢的 UNIX,而且發明帶有晚期 .99 CD-ROM刊行版的Linux。他用各類說話編寫UNIX、Linux和其它平台的軟件,同時還裝置並治理幾台Linux辦事器。在異常無限的專業時光,他盡力進步他的鋼琴吹奏技能。
從年夜學時期開端接觸C和UNIX V6時起,Neil Matthew關於UNIX和Linux曾經跨越20年的經歷。從那時起他就在IT業任務,重要從事通訊軟件的開辟,一向堅持關於深邃的編程說話和開辟技巧的熱忱。如今,他作為體系設計師,對技巧計謀和QA提出建議。他熱情於在公司企業內樹立Linux貿易案例。專業時光,寫作或騎馬為樂,Neil盡力勸告他的老婆和兩個孩子與他一路在鄉下漫步。Neil介入編寫了Wrox Press刊行的好幾本書,最有名的是配合著作了Beginning Linux Programming和Professional Linux Programming。