亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

[轉(zhuǎn)] 在 MySQL 數(shù)據(jù)庫中使用 C 執(zhí)行 SQL語句

系統(tǒng) 1832 0

在 MySQL 數(shù)據(jù)庫中使用 C 執(zhí)行 SQL語句

<nobr><table cellspacing="0" cellpadding="0"><tbody><tr valign="top"> <td align="right"></td> <td width="46"><form action="https://www-130.ibm.com/developerworks/secure/email-it.jsp"></form></td> </tr></tbody></table></nobr>
內(nèi)容:
<!--Standard links for every dw-article-->
執(zhí)行 SQL 語句
不返回?cái)?shù)據(jù)的 SQL 語句
返回?cái)?shù)據(jù)的語句
全部立即數(shù)據(jù)檢索的函數(shù)
mysql_fetch_rowmysql_fetch_row
mysql_data_seek
my_sql_row_tell, mysql_row_seek
mysql_free_result
檢索數(shù)據(jù)
一次檢索一行數(shù)據(jù)
參考資料
關(guān)于作者
對本文的評價(jià)
訂閱:
developerWorks 時(shí)事通訊
Professional Linux Programming 的摘錄

<name></name>Neil Matthew 和 Richard Stones
Wrox Press Ltd
2001 年 1 月

與 PostgreSQL 相似,可使用許多不同的語言來訪問 MySQL,包括 C、C++、Java 和 Perl。從 Professional Linux Programming 中第 5 章有關(guān) MySQL 的下列章節(jié)中,Neil Matthew 和 Richard Stones 使用詳盡的 MySQL C 接口向我們介紹了如何在 MySQL 數(shù)據(jù)庫中執(zhí)行 SQL 語句。他們將討論返回?cái)?shù)據(jù)的語句,例如 INSERT 以及不返回?cái)?shù)據(jù)的語句,例如 UPDATE 和 DELETE。然后,他們將編寫從數(shù)據(jù)庫檢索數(shù)據(jù)的簡單程序。

執(zhí)行 SQL 語句
現(xiàn)在,我們已經(jīng)有了一個(gè)連接,并且知道如何處理錯(cuò)誤,是時(shí)候討論使用我們的數(shù)據(jù)庫來作一些實(shí)際工作了。執(zhí)行所有類型的 SQL 的主關(guān)鍵字是 mysql_query:

                    
                      
int mysql_query(MYSQL *connection, const char *query)

                    
                  

正如您所見,它非常簡單。它取一個(gè)指向連接結(jié)構(gòu)的指針和包含要執(zhí)行的 SQL 的文本字符串;與命令行工具不同,將不使用結(jié)束分號。成功之后,返回 0。在需要包含二進(jìn)制數(shù)據(jù)的特殊情況下,可以使用相關(guān)的函數(shù),mysql_real_query。雖然出于本章的目的,我們僅需要討論 mysql_query。

不返回?cái)?shù)據(jù)的 SQL 語句
我們將先討論 UPDATE、DELETE 和 INSERT 語句。因?yàn)樗鼈儾环祷財(cái)?shù)據(jù),所以更易于使用。

這里我們將介紹的另一個(gè)重要函數(shù)是檢查受影響的行數(shù)的函數(shù):

                    
                      
my_ulonglong mysql_affected_rows(MYSQL *connection);

                    
                  

可能關(guān)于這一函數(shù)的最顯而易見的事就是其非同尋常的返回結(jié)果。由于可移植性原因,這是一個(gè)特殊的無符號類型。為了在 printf 中使用,建議將其強(qiáng)制轉(zhuǎn)換成使用 %lu 格式規(guī)范的無符號長整數(shù)。這個(gè)函數(shù)返回受以前的 UPDATE、INSERT 或 DELETE 查詢影響的行數(shù),這些查詢是使用 mysql_query 執(zhí)行的。

通常對于 mysql_ 函數(shù),返回碼 0 表示沒有行受影響;正數(shù)表示實(shí)際結(jié)果,通常是受影響的行數(shù)。

如前所述,當(dāng)使用 mysql_affected_rows 時(shí)可能出現(xiàn)未期望的結(jié)果。讓我們先討論受 INSERT 語句影響的行數(shù),它將按預(yù)期進(jìn)行操作。將下列代碼添加到程序 connect2.c 中,并且稱其為 insert1.c:

                    
                      
#include <stdlib.h>
      #include <stdio.h>

      #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;
    }

                    
                  

正如預(yù)期,插入的行數(shù)為 1。

現(xiàn)在,我們更改代碼,所以 '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));
      }

                    
                  

現(xiàn)在假設(shè)子表中有的數(shù)據(jù),如下:

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

如果我們執(zhí)行 update1,希望報(bào)告的受影響行數(shù)為 4,但是實(shí)際上程序報(bào)告 2,因?yàn)樗鼉H必須更改 2 行,雖然 WHERE 子句標(biāo)識了 4 行。如果想讓 mysql_affected_rows 報(bào)告的結(jié)果為 4(這可能是熟悉其它數(shù)據(jù)庫的人所期望的),則需要記住將 CLIENT_FOUND_ROWS 標(biāo)志傳遞到 mysql_real_connect,在 update2.c 中的程序如下:

                    
                      
if (mysql_real_connect(&my_connection, "localhost", 
                                 "rick", "bar", "rick", 0, NULL, CLIENT_FOUND_ROWS)) {

                    
                  

如果我們在數(shù)據(jù)庫中復(fù)位數(shù)據(jù),然后運(yùn)行帶有這種修改的程序,則它報(bào)告的行數(shù)為 4。

函數(shù) mysql_affected_rows 還有最后一個(gè)奇怪之處,它發(fā)生在從數(shù)據(jù)庫中刪除數(shù)據(jù)時(shí)。如果使用 WHERE 子句,則 mysql_affected_rows 將按預(yù)期返回刪除行數(shù)。但是,如果沒有 WHERE 子句,則刪除所有行,報(bào)告受影響的行數(shù)卻為 0。這是因?yàn)橛捎谛试騼?yōu)化刪除整個(gè)表。這種行為不受 CLIENT_FOUND_ROWS 選項(xiàng)標(biāo)志的影響。

返回?cái)?shù)據(jù)的語句
現(xiàn)在是時(shí)候討論 SQL 的最普遍用法了,從數(shù)據(jù)庫檢索數(shù)據(jù)的 SELECT 語句。

MySQL 還支持返回結(jié)果的 SHOW、DESCRIBE 和 EXPLAIN SQL 語句,但是這里不考慮它們。按慣例,手冊中包含這些語句的說明。

您將會從 PostgreSQL 章記起,可以從 PQexec 中的 SQL SELECT 語句檢索數(shù)據(jù),這里馬上獲取所有數(shù)據(jù),或者使用游標(biāo)從數(shù)據(jù)庫中逐行檢索數(shù)據(jù),以便搞定大數(shù)據(jù)。

由于完全相同的原因,MySQL 的檢索方法幾乎完全相同,雖然它實(shí)際上不用游標(biāo)的形式描述逐行檢索。但是,它提供了縮小這兩種方法間差異的 API,如果需要,它通常使兩種方法的互換更加容易。

通常,從 MySQL 數(shù)據(jù)庫中檢索數(shù)據(jù)有 4 個(gè)階段:

  • 發(fā)出查詢
  • 檢索數(shù)據(jù)
  • 處理數(shù)據(jù)
  • 執(zhí)行所需的任何整理

象以前一樣,我們使用 mysql_query 發(fā)出查詢。數(shù)據(jù)檢索是使用 mysql_store_result 或 mysql_use_result 完成的,這取決于想如何檢索數(shù)據(jù),隨后使用 mysql_fetch_row 調(diào)用序列來處理數(shù)據(jù)。最后,必須調(diào)用 mysql_free_result 以允許 MySQL 執(zhí)行任何所需的整理。

全部立即數(shù)據(jù)檢索的函數(shù)
可以從 SELECT 語句(或其他返回?cái)?shù)據(jù)的語句)中檢索完所有數(shù)據(jù),在單一調(diào)用中,使用 mysql_store_result:

                    
                      
MYSQL_RES *mysql_store_result(MYSQL *connection);

                    
                  

必須在 mysql_query 檢索數(shù)據(jù)后才能調(diào)用這個(gè)函數(shù),以在結(jié)果集中存儲該數(shù)據(jù)。這個(gè)函數(shù)從服務(wù)器中檢索所有數(shù)據(jù)并立即將它存儲在客戶機(jī)中。它返回一個(gè)指向以前我們從未遇到過的結(jié)構(gòu)(結(jié)果集結(jié)構(gòu))的指針。如果語句失敗,則返回 NULL。

使用等價(jià)的 PostgreSQL 時(shí),應(yīng)該知道返回 NULL 意味著已經(jīng)發(fā)生了錯(cuò)誤,并且這與未檢索到數(shù)據(jù)的情況不同。即使,返回值不是 NULL,也不意味著當(dāng)前有數(shù)據(jù)要處理。

如果未返回 NULL,則可以調(diào)用 mysql_num_rows 并且檢索實(shí)際返回的行數(shù),它當(dāng)然可能是 0。

                    
                      
my_ulonglong mysql_num_rows(MYSQL_RES *result);

                    
                  

它從 mysql_store_result 取得返回的結(jié)果結(jié)構(gòu),并且在該結(jié)果集中返回行數(shù),行數(shù)可能為 0。如果 mysql_store_result 成功,則 mysql_num_rows 也總是成功的。

這種 mysql_store_result 和 mysql_num_rows 的組合是檢索數(shù)據(jù)的一種簡便并且直接的方法。一旦 mysql_store_result 成功返回,則所有查詢數(shù)據(jù)都已經(jīng)存儲在客戶機(jī)上并且我們知道可以從結(jié)果結(jié)構(gòu)中檢索它,而不用擔(dān)心會發(fā)生數(shù)據(jù)庫或網(wǎng)絡(luò)錯(cuò)誤,因?yàn)閷τ诔绦蛩袛?shù)據(jù)都是本地的。還可以立即發(fā)現(xiàn)返回的行數(shù),它可以使編碼更簡便。如前所述,它將所有結(jié)果立即地發(fā)送回客戶機(jī)。對于大結(jié)果集,它可能耗費(fèi)大量的服務(wù)器、網(wǎng)絡(luò)和客戶機(jī)資源。由于這些原因,使用更大的數(shù)據(jù)集時(shí),最好僅檢索需要的數(shù)據(jù)。不久,我們將討論如何使用 mysql_use_result 函數(shù)來完成該操作。

一旦檢索了數(shù)據(jù),則可以使用 mysql_fetch_row 來檢索它,并且使用 mysql_data_seek、mysql_row_seek、mysql_row_tell 操作結(jié)果集。在開始檢索數(shù)據(jù)階段之前,讓我們先討論一下這些函數(shù)。

mysql_fetch_rowmysql_fetch_row

                    
                      
MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);

                    
                  

這個(gè)函數(shù)采用從存儲結(jié)果中獲取的結(jié)果結(jié)構(gòu),并且從中檢索單一行,在行結(jié)構(gòu)中返回分配給您的數(shù)據(jù)。當(dāng)沒有更多數(shù)據(jù)或者發(fā)生錯(cuò)誤時(shí),返回 NULL。稍后,我們將回來處理這一行中的數(shù)據(jù)。

mysql_data_seek

                    
                      
void mysql_data_seek(MYSQL_RES *result, my_ulonglong offset);

                    
                  

這個(gè)函數(shù)允許您進(jìn)入結(jié)果集,設(shè)置將由下一個(gè)獲取操作返回的行。offset 是行號,它必須在從 0 到結(jié)果集中的行數(shù)減 1 的范圍內(nèi)。傳遞 0 將導(dǎo)致在下一次調(diào)用 mysql_fetch_row 時(shí)返回第一行。

my_sql_row_tell, mysql_row_seek

                    
                      
MYSQL_ROW_OFFEST mysql_row_tell(MYSQL_RES *result);

                    
                  

這個(gè)函數(shù)返回一個(gè)偏移值,它表示結(jié)果集中的當(dāng)前位置。它不是行號,不能將它用于 mysql_data_seek。但是,可將它用于:

                    
                      
MYSQL_ROW_OFFSET mysql_row_seek(MYSQL_RES *result, MYSQL_ROW_OFFSET offset);

                    
                  

它移動結(jié)果集中的當(dāng)前位置,并返回以前的位置。

有時(shí),這一對函數(shù)對于在結(jié)果集中的已知點(diǎn)之間跳轉(zhuǎn)很有用。請注意,不要將 row tell 和 row seek 使用的偏移值與 data_seek 使用的行號混淆。這些是不可交換的,結(jié)果將是您所希望看到的。

mysql_free_result
在迫不及待地使用這些新函數(shù)之前,我們需要知道的最后一個(gè)函數(shù)是 mysql_free_result。

                    
                      
void mysql_free_result(MYSQL_RES *result);

                    
                  

完成結(jié)果集時(shí), 必須總是 調(diào)用這個(gè)函數(shù),以允許 MySQL 庫整理分配給它的對象。

檢索數(shù)據(jù)
現(xiàn)在開始編寫從數(shù)據(jù)庫中檢索數(shù)據(jù)的第一個(gè)程序。我們將選擇所有年齡大于 5 的行的內(nèi)容。不幸的是我們還不知道如何處理這個(gè)數(shù)據(jù),所以我們能做的只有循環(huán)檢索它。這便是 select1.c:

                    
                      
      #include <stdlib.h>
      #include <stdio.h>

      #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;
       }

                    
                  

檢索結(jié)果集并循環(huán)通過已檢索的數(shù)據(jù)的重要部分都已突出顯示。

一次檢索一行數(shù)據(jù)
要按需要逐行檢索數(shù)據(jù),而不是立即獲取全部數(shù)據(jù)并將它存儲在客戶機(jī)中,可以將 mysql_store_result 調(diào)用替換成 mysql_use_result:

                    
                      
MYSQL_RES *mysql_use_result(MYSQL *connection);

                    
                  

這個(gè)函數(shù)還取得一個(gè)連接對象并返回結(jié)果結(jié)合指針,或者出錯(cuò)時(shí)返回 NULL 。與 mysql_store_result 相似,它返回指向結(jié)果集對象的指針;關(guān)鍵的不同點(diǎn)在于返回時(shí),實(shí)際上沒有將任何數(shù)據(jù)檢索到結(jié)果集,只是初始化結(jié)果集以準(zhǔn)備好檢索數(shù)據(jù)。

參考資料

關(guān)于作者
Rick Stones 是一位系統(tǒng)設(shè)計(jì)師,他在一家大型泛歐制藥分銷和分配公司的 IT 部門工作。從 1985 年開始,他一直在使用各種形式的 UNIX,并且發(fā)現(xiàn)帶有早期 .99 CD-ROM 發(fā)行版的 Linux。他用各種語言編寫 UNIX、Linux 和其它平臺的軟件,同時(shí)還安裝并管理幾臺 Linux 服務(wù)器。在非常有限的業(yè)余時(shí)間,他努力提高他的鋼琴演奏技巧。

從大學(xué)時(shí)代開始接觸 C 和 UNIX V6 時(shí)起,Neil Matthew 對于 UNIX 和 Linux 已經(jīng)超過 20 年的經(jīng)驗(yàn)。從那時(shí)起他就在 IT 業(yè)工作,主要從事通信軟件的開發(fā),一直保持對于深奧的編程語言和開發(fā)技術(shù)的熱情。現(xiàn)在,他作為系統(tǒng)設(shè)計(jì)師,對技術(shù)戰(zhàn)略和 QA 提出建議。他熱心于在公司企業(yè)內(nèi)建立 Linux 商業(yè)案例。業(yè)余時(shí)間,寫作或騎馬為樂,Neil 努力勸說他的妻子和兩個(gè)孩子與他一起在鄉(xiāng)間散步。 Neil 參與編寫了 Wrox Press 發(fā)行的好幾本書,最著名的是共同著作了 Beginning Linux Programming 和 Professional Linux Programming。



[轉(zhuǎn)] 在 MySQL 數(shù)據(jù)庫中使用 C 執(zhí)行 SQL語句


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 国产福利视频一区二区三区 | 中文字幕亚洲一区二区va在线 | 黄视频在线观看www 黄视频在线观看网站 | 波多野结衣精品中文字幕 | 男人天堂网在线视频 | 亚洲天天操 | 国产一级特黄a大片99 | www.中文字幕在线观看 | 97免费 | 久久99热这里只有精品7 | 高清一级毛片免免费看 | 成人欧美精品大91在线 | 国产亚洲精品成人久久网站 | 激情小视频在线播放免费 | 精品亚洲成a人在线观看 | 四虎影视免费永久在线观看黄 | 国产目拍亚洲精品一区麻豆 | 久久综合九色综合亚洲 | 亚洲黄色a级片 | a级日本理论片在线播放 | 久草免费看| 视频二区 中文字幕 欧美 | 伊人丁香狠狠色综合久久 | 成人欧美视频在线看免费 | 日韩亚洲欧美一区 | 亚洲欧美一区二区三区综合 | 日本高清一 | 欧美精品成人免费视频 | 97s色视频一区二区三区在线 | 老司机午夜网站 | 亚洲专区欧美专区 | 亚州免费一级毛片 | 精品中文字幕不卡在线视频 | 日本亚洲高清 | 四虎免费永久观看 | 99热久久只有精品6国产32 | 久草手机视频在线 | 有码中文字幕在线观看 | 日产国产精品久久久久久 | 香蕉福利| 成人手机看片 |