<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # MySQL C API 編程教程 > 原文: [http://zetcode.com/db/mysqlc/](http://zetcode.com/db/mysqlc/) 這是針對 MySQL 數據庫的 C 編程教程。 它涵蓋了使用 C API 進行 MySQL 編程的基礎。 您還可以考慮查看有關 ZetCode 的 [MySQL 教程](/databases/mysqltutorial/)。 [Tweet](https://twitter.com/share) ## 關于 MySQL 數據庫 MySQL 是領先的開源數據庫管理系統。 它是一個多用戶,多線程的數據庫管理系統。 MySQL 在網絡上特別流行。 它是由 Linux,Apache,MySQL 和 PHP 組成的非常流行的 _LAMP_ 平臺的一部分。 Oracle 當前擁有 MySQL。 MySQL 數據庫在最重要的 OS 平臺上可用。 它可以在 BSD Unix,Linux,Windows 或 Mac OS 上運行。 維基百科和 YouTube 使用 MySQL。 這些站點每天管理數百萬個查詢。 MySQL 有兩個版本:MySQL 服務器系統和 MySQL 嵌入式系統。 ```perl $ sudo apt-get install libmysqlclient-dev ``` 為了能夠編譯 C 示例,我們需要安裝 MySQL C 開發庫。 上一行顯示了我們如何在基于 Debian 的 Linux 上做到這一點。 ## C99 本教程使用 C99。 對于 GNU C 編譯器,我們需要添加-std = c99 選項。 對于 Windows 用戶,強烈建議使用 Pelles C IDE。 (MSVC 不支持 C99。) ```perl MYSQL *con = mysql_init(NULL); ``` 在 C99 中,我們可以將聲明與代碼混合使用。 在較早的 C 程序中,我們需要將這一行分成兩行。 ## 第一個例子 我們的第一個示例將測試一個 MySQL 函數調用。 ```perl #include <my_global.h> #include <mysql.h> int main(int argc, char **argv) { printf("MySQL client version: %s\n", mysql_get_client_info()); exit(0); } ``` `mysql_get_client_info()`顯示 MySQL 客戶端版本。 ```perl #include <my_global.h> #include <mysql.h> ``` 我們包括必要的頭文件。 `mysql.h`是 MySQL 函數調用的最重要的頭文件。 `my_global.h`包含一些全局函數聲明。 除其他外,它包括標準輸入/輸出頭文件。 ```perl printf("MySQL client version: %s\n", mysql_get_client_info()); ``` 此代碼行輸出 MySQL 客戶端的版本。 為此,我們使用`mysql_get_client_info()`函數調用。 ```perl exit(0); ``` 我們從腳本退??出。 ```perl $ gcc version.c -o version `mysql_config --cflags --libs` ``` 這是我們編譯代碼示例的方式。 ```perl $ ./version MySQL client version: 5.1.67 ``` 示例輸出。 ## 建立數據庫 下一個代碼示例將創建一個數據庫。 該代碼示例可以分為以下幾部分: * 創建連接句柄結構 * 建立連接 * 執行查詢 * 關閉連接 ```perl #include <my_global.h> #include <mysql.h> int main(int argc, char **argv) { MYSQL *con = mysql_init(NULL); if (con == NULL) { fprintf(stderr, "%s\n", mysql_error(con)); exit(1); } if (mysql_real_connect(con, "localhost", "root", "root_pswd", NULL, 0, NULL, 0) == NULL) { fprintf(stderr, "%s\n", mysql_error(con)); mysql_close(con); exit(1); } if (mysql_query(con, "CREATE DATABASE testdb")) { fprintf(stderr, "%s\n", mysql_error(con)); mysql_close(con); exit(1); } mysql_close(con); exit(0); } ``` 該代碼示例連接到 MySQL 數據庫系統,并創建一個名為`testdb`的新數據庫。 ```perl MYSQL *con = mysql_init(NULL); ``` `mysql_init()`函數分配或初始化適合`mysql_real_connect()`函數的 MYSQL 對象。 記住這是 C99。 ```perl if (con == NULL) { fprintf(stderr, "%s\n", mysql_error(con)); exit(1); } ``` 我們檢查返回值。 如果`mysql_init()`函數失敗,我們將打印錯誤消息并終止應用。 ```perl if (mysql_real_connect(con, "localhost", "root", "root_pswd", NULL, 0, NULL, 0) == NULL) { fprintf(stderr, "%s\n", mysql_error(con)); mysql_close(con); exit(1); } ``` `mysql_real_connect()`函數建立與數據庫的連接。 我們為該函數提供連接處理器,主機名,用戶名和密碼參數。 其他四個參數是數據庫名稱,端口號,unix 套接字以及最后的客戶端標志。 我們需要超級用戶特權才能創建新數據庫。 ```perl if (mysql_query(con, "CREATE DATABASE testdb")) { fprintf(stderr, "%s\n", mysql_error(con)); mysql_close(con); exit(1); } ``` `mysql_query()`執行 SQL 語句。 在我們的例子中,該語句創建一個新數據庫。 ```perl mysql_close(con); ``` 最后,我們關閉數據庫連接。 ```perl $ gcc createdb.c -o createdb -std=c99 `mysql_config --cflags --libs` ``` 第二個示例已經利用了 C99 標準的功能。 因此,我們需要添加`-std=c99`選項。 ```perl mysql> SHOW DATABASES; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | testdb | +--------------------+ 3 rows in set (0.00 sec) ``` 這是數據庫已創建的證明。 ## 創建并填充表 在創建新表之前,我們將創建一個將在本教程其余部分中使用的用戶。 ```perl mysql> CREATE USER user12@localhost IDENTIFIED BY '34klq*'; ``` 我們創建了一個新用戶`user12`。 ```perl mysql> GRANT ALL ON testdb.* to user12@localhost; ``` 在這里,我們將所有特權授予`testdb`數據庫上的`user12`。 下一個代碼示例將創建一個表并將一些數據插入其中。 ```perl #include <my_global.h> #include <mysql.h> void finish_with_error(MYSQL *con) { fprintf(stderr, "%s\n", mysql_error(con)); mysql_close(con); exit(1); } int main(int argc, char **argv) { MYSQL *con = mysql_init(NULL); if (con == NULL) { fprintf(stderr, "%s\n", mysql_error(con)); exit(1); } if (mysql_real_connect(con, "localhost", "user12", "34klq*", "testdb", 0, NULL, 0) == NULL) { finish_with_error(con); } if (mysql_query(con, "DROP TABLE IF EXISTS Cars")) { finish_with_error(con); } if (mysql_query(con, "CREATE TABLE Cars(Id INT, Name TEXT, Price INT)")) { finish_with_error(con); } if (mysql_query(con, "INSERT INTO Cars VALUES(1,'Audi',52642)")) { finish_with_error(con); } if (mysql_query(con, "INSERT INTO Cars VALUES(2,'Mercedes',57127)")) { finish_with_error(con); } if (mysql_query(con, "INSERT INTO Cars VALUES(3,'Skoda',9000)")) { finish_with_error(con); } if (mysql_query(con, "INSERT INTO Cars VALUES(4,'Volvo',29000)")) { finish_with_error(con); } if (mysql_query(con, "INSERT INTO Cars VALUES(5,'Bentley',350000)")) { finish_with_error(con); } if (mysql_query(con, "INSERT INTO Cars VALUES(6,'Citroen',21000)")) { finish_with_error(con); } if (mysql_query(con, "INSERT INTO Cars VALUES(7,'Hummer',41400)")) { finish_with_error(con); } if (mysql_query(con, "INSERT INTO Cars VALUES(8,'Volkswagen',21600)")) { finish_with_error(con); } mysql_close(con); exit(0); } ``` 我們在這里不使用任何新的 MySQL 函數調用。 我們使用`mysql_query()`函數調用來創建表并將數據插入其中。 ```perl void finish_with_error(MYSQL *con) { fprintf(stderr, "%s\n", mysql_error(con)); mysql_close(con); exit(1); } ``` 為了避免不必要的重復,我們創建了一個自定義`finish_with_error()`函數。 ```perl if (mysql_real_connect(con, "localhost", "user12", "34klq*", "testdb", 0, NULL, 0) == NULL) { finish_with_error(con); } ``` 我們連接到`testdb`數據庫。 用戶名為`user12`,密碼為`34klq*`。 第五個參數是數據庫名稱。 ```perl if (mysql_query(con, "CREATE TABLE Cars(Id INT, Name TEXT, Price INT)")) { finish_with_error(con); } ``` 在這里,我們創建一個名為`Cars`的表。 它具有三列。 ```perl if (mysql_query(con, "INSERT INTO Cars VALUES(1,'Audi',52642)")) { finish_with_error(con); } ``` 我們在`Cars`表中插入一行。 ```perl mysql> USE testdb; mysql> SHOW TABLES; +------------------+ | Tables_in_testdb | +------------------+ | Cars | +------------------+ 1 row in set (0.00 sec) ``` 我們顯示數據庫中的表。 ```perl mysql> SELECT * FROM Cars; +------+------------+--------+ | Id | Name | Price | +------+------------+--------+ | 1 | Audi | 52642 | | 2 | Mercedes | 57127 | | 3 | Skoda | 9000 | | 4 | Volvo | 29000 | | 5 | Bentley | 350000 | | 6 | Citroen | 21000 | | 7 | Hummer | 41400 | | 8 | Volkswagen | 21600 | +------+------------+--------+ 8 rows in set (0.00 sec) ``` 我們從表中選擇所有數據。 ## 從數據庫中檢索數據 在下一個示例中,我們將從表中檢索數據。 我們需要執行以下步驟: * 建立連接 * 執行查詢 * 獲取結果集 * 獲取所有可用行 * 釋放結果集 ```perl #include <my_global.h> #include <mysql.h> void finish_with_error(MYSQL *con) { fprintf(stderr, "%s\n", mysql_error(con)); mysql_close(con); exit(1); } int main(int argc, char **argv) { MYSQL *con = mysql_init(NULL); if (con == NULL) { fprintf(stderr, "mysql_init() failed\n"); exit(1); } if (mysql_real_connect(con, "localhost", "user12", "34klq*", "testdb", 0, NULL, 0) == NULL) { finish_with_error(con); } if (mysql_query(con, "SELECT * FROM Cars")) { finish_with_error(con); } MYSQL_RES *result = mysql_store_result(con); if (result == NULL) { finish_with_error(con); } int num_fields = mysql_num_fields(result); MYSQL_ROW row; while ((row = mysql_fetch_row(result))) { for(int i = 0; i < num_fields; i++) { printf("%s ", row[i] ? row[i] : "NULL"); } printf("\n"); } mysql_free_result(result); mysql_close(con); exit(0); } ``` 該示例打印`Cars`表中的所有列。 ```perl if (mysql_query(con, "SELECT * FROM Cars")) { finish_with_error(con); } ``` 我們執行查詢,該查詢將從 Cars 表中檢索所有數據。 ```perl MYSQL_RES *result = mysql_store_result(con); ``` 我們使用`mysql_store_result()`函數獲得結果集。 `MYSQL_RES`是用于保存結果集的結構。 ```perl int num_fields = mysql_num_fields(result); ``` 我們獲得表中的字段(列)數。 ```perl MYSQL_ROW row; while ((row = mysql_fetch_row(result))) { for(int i = 0; i < num_fields; i++) { printf("%s ", row[i] ? row[i] : "NULL"); } printf("\n"); } ``` 我們獲取行并將其打印到屏幕上。 ```perl mysql_free_result(result); mysql_close(con); ``` 我們釋放資源。 ```perl $ ./retrieva_data 1 Audi 52642 2 Mercedes 57127 3 Skoda 9000 4 Volvo 29000 5 Bentley 350000 6 Citroen 21000 7 Hummer 41400 8 Volkswagen 21600 ``` 示例輸出。 ## 最后插入的行 ID 有時,我們需要確定最后插入的行的 ID。 我們可以通過調用`mysql_insert_id()`函數來確定最后插入的行 ID。 僅當我們在表中定義了`AUTO_INCREMENT`列時,該函數才起作用。 ```perl #include <my_global.h> #include <mysql.h> void finish_with_error(MYSQL *con) { fprintf(stderr, "%s\n", mysql_error(con)); mysql_close(con); exit(1); } int main(int argc, char **argv) { MYSQL *con = mysql_init(NULL); if (con == NULL) { fprintf(stderr, "mysql_init() failed\n"); exit(1); } if (mysql_real_connect(con, "localhost", "user12", "34klq*", "testdb", 0, NULL, 0) == NULL) { finish_with_error(con); } if (mysql_query(con, "DROP TABLE IF EXISTS Writers")) { finish_with_error(con); } char *sql = "CREATE TABLE Writers(Id INT PRIMARY KEY AUTO_INCREMENT, Name TEXT)"; if (mysql_query(con, sql)) { finish_with_error(con); } if (mysql_query(con, "INSERT INTO Writers(Name) VALUES('Leo Tolstoy')")) { finish_with_error(con); } if (mysql_query(con, "INSERT INTO Writers(Name) VALUES('Jack London')")) { finish_with_error(con); } if (mysql_query(con, "INSERT INTO Writers(Name) VALUES('Honore de Balzac')")) { finish_with_error(con); } int id = mysql_insert_id(con); printf("The last inserted row id is: %d\n", id); mysql_close(con); exit(0); } ``` 創建一個新表。 三行插入到表中。 我們確定最后插入的行 ID。 ```perl char *sql = "CREATE TABLE Writers(Id INT PRIMARY KEY AUTO_INCREMENT, Name TEXT)"; ``` `Id`列具有`AUTO_INCREMENT`類型。 ```perl int id = mysql_insert_id(con); ``` `mysql_insert_id()`函數返回由先前的`INSERT`或`UPDATE`語句為`AUTO_INCREMENT`列生成的值。 ```perl $ ./last_row_id The last inserted row id is: 3 ``` 輸出。 ## 列標題 在下一個示例中,我們將從表及其列名稱中檢索數據。 ```perl #include <my_global.h> #include <mysql.h> void finish_with_error(MYSQL *con) { fprintf(stderr, "%s\n", mysql_error(con)); mysql_close(con); exit(1); } int main(int argc, char **argv) { MYSQL *con = mysql_init(NULL); if (con == NULL) { fprintf(stderr, "mysql_init() failed\n"); exit(1); } if (mysql_real_connect(con, "localhost", "user12", "34klq*", "testdb", 0, NULL, 0) == NULL) { finish_with_error(con); } if (mysql_query(con, "SELECT * FROM Cars LIMIT 3")) { finish_with_error(con); } MYSQL_RES *result = mysql_store_result(con); if (result == NULL) { finish_with_error(con); } int num_fields = mysql_num_fields(result); MYSQL_ROW row; MYSQL_FIELD *field; while ((row = mysql_fetch_row(result))) { for(int i = 0; i < num_fields; i++) { if (i == 0) { while(field = mysql_fetch_field(result)) { printf("%s ", field->name); } printf("\n"); } printf("%s ", row[i] ? row[i] : "NULL"); } } printf("\n"); mysql_free_result(result); mysql_close(con); exit(0); } ``` 我們從`Cars`表中打印前三行。 我們還包括列標題。 ```perl MYSQL_FIELD *field; ``` `MYSQL_FIELD`結構包含有關字段的信息,例如字段的名稱,類型和大小。 字段值不屬于此結構; 它們包含在`MYSQL_ROW`結構中。 ```perl if (i == 0) { while(field = mysql_fetch_field(result)) { printf("%s ", field->name); } printf("\n"); } ``` 第一行包含列標題。 `mysql_fetch_field()`調用返回`MYSQL_FIELD`結構。 我們從該結構中獲取列標題名稱。 ```perl $ ./headers Id Name Price 1 Audi 52642 2 Mercedes 57127 3 Skoda 9000 ``` 這是我們程序的輸出。 ## 多個語句 可以在一個查詢中執行多個 SQL 語句。 我們必須在`connect`方法中設置`CLIENT_MULTI_STATEMENTS`標志。 ```perl #include <my_global.h> #include <mysql.h> void finish_with_error(MYSQL *con) { fprintf(stderr, "%s\n", mysql_error(con)); mysql_close(con); exit(1); } int main(int argc, char **argv) { int status = 0; MYSQL *con = mysql_init(NULL); if (con == NULL) { fprintf(stderr, "mysql_init() failed\n"); exit(1); } if (mysql_real_connect(con, "localhost", "user12", "34klq*", "testdb", 0, NULL, CLIENT_MULTI_STATEMENTS) == NULL) { finish_with_error(con); } if (mysql_query(con, "SELECT Name FROM Cars WHERE Id=2;\ SELECT Name FROM Cars WHERE Id=3;SELECT Name FROM Cars WHERE Id=6")) { finish_with_error(con); } do { MYSQL_RES *result = mysql_store_result(con); if (result == NULL) { finish_with_error(con); } MYSQL_ROW row = mysql_fetch_row(result); printf("%s\n", row[0]); mysql_free_result(result); status = mysql_next_result(con); if (status > 0) { finish_with_error(con); } } while(status == 0); mysql_close(con); exit(0); } ``` 在該示例中,我們在一個查詢中執行了三個`SELECT`語句。 ```perl if (mysql_real_connect(con, "localhost", "user12", "34klq*", "testdb", 0, NULL, CLIENT_MULTI_STATEMENTS) == NULL) { finish_with_error(con); } ``` `mysql_real_connect()`方法的最后一個選項是客戶端標志。 它用于啟用某些功能。 `CLIENT_MULTI_STATEMENTS`允許執行多個語句。 默認情況下禁用此功能。 ```perl if (mysql_query(con, "SELECT Name FROM Cars WHERE Id=2;\ SELECT Name FROM Cars WHERE Id=3;SELECT Name FROM Cars WHERE Id=6")) { finish_with_error(con); } ``` 該查詢包含三個`SELECT`語句。 它們之間用分號`;`字符分隔。 反斜杠字符`\`用于將字符串分成兩行。 它與多個語句無關。 ```perl do { ... } while(status == 0); ``` 該代碼位于`do/while`語句之間。 數據檢索要分多個周期進行。 我們將分別為每個`SELECT`語句檢索數據。 ```perl status = mysql_next_result(con); ``` 我們期望有多個結果集。 因此,我們稱為`mysql_next_result()`函數。 它讀取下一個語句結果,并返回狀態以指示是否存在更多結果。 如果執行正常并且有更多結果,該函數將返回 0。 當執行 OK 且沒有更多結果時,它將返回 -1。 最后,如果發生錯誤,它將返回大于零的值。 ```perl if (status > 0) { finish_with_error(con); } ``` 我們檢查錯誤。 ```perl $ ./multiple_statements Mercedes Skoda Citroen ``` 示例輸出。 ## 將圖像插入 MySQL 數據庫 有些人喜歡將其圖像放入數據庫中,有些人則希望將其保留在文件系統中以供其應用使用。 當我們處理大量圖像時,會出現技術難題。 圖像是二進制數據。 MySQL 數據庫具有一種特殊的數據類型來存儲稱為`BLOB`(二進制大對象)的二進制數據。 ```perl mysql> CREATE TABLE Images(Id INT PRIMARY KEY, Data MEDIUMBLOB); ``` 對于我們的示例,我們創建一個新的`Images`表。 圖像大小最大為 16 MB。 它由`MEDIUMBLOB`數據類型確定。 ```perl #include <my_global.h> #include <mysql.h> #include <string.h> void finish_with_error(MYSQL *con) { fprintf(stderr, "%s\n", mysql_error(con)); mysql_close(con); exit(1); } int main(int argc, char **argv) { FILE *fp = fopen("woman.jpg", "rb"); if (fp == NULL) { fprintf(stderr, "cannot open image file\n"); exit(1); } fseek(fp, 0, SEEK_END); if (ferror(fp)) { fprintf(stderr, "fseek() failed\n"); int r = fclose(fp); if (r == EOF) { fprintf(stderr, "cannot close file handler\n"); } exit(1); } int flen = ftell(fp); if (flen == -1) { perror("error occurred"); int r = fclose(fp); if (r == EOF) { fprintf(stderr, "cannot close file handler\n"); } exit(1); } fseek(fp, 0, SEEK_SET); if (ferror(fp)) { fprintf(stderr, "fseek() failed\n"); int r = fclose(fp); if (r == EOF) { fprintf(stderr, "cannot close file handler\n"); } exit(1); } char data[flen+1]; int size = fread(data, 1, flen, fp); if (ferror(fp)) { fprintf(stderr, "fread() failed\n"); int r = fclose(fp); if (r == EOF) { fprintf(stderr, "cannot close file handler\n"); } exit(1); } int r = fclose(fp); if (r == EOF) { fprintf(stderr, "cannot close file handler\n"); } MYSQL *con = mysql_init(NULL); if (con == NULL) { fprintf(stderr, "mysql_init() failed\n"); exit(1); } if (mysql_real_connect(con, "localhost", "user12", "34klq*", "testdb", 0, NULL, 0) == NULL) { finish_with_error(con); } char chunk[2*size+1]; mysql_real_escape_string(con, chunk, data, size); char *st = "INSERT INTO Images(Id, Data) VALUES(1, '%s')"; size_t st_len = strlen(st); char query[st_len + 2*size+1]; int len = snprintf(query, st_len + 2*size+1, st, chunk); if (mysql_real_query(con, query, len)) { finish_with_error(con); } mysql_close(con); exit(0); } ``` 在此示例中,我們將一張圖像插入`Images`表。 ```perl #include <string.h> ``` 這包括`strlen()`函數。 ```perl FILE *fp = fopen("woman.jpg", "rb"); if (fp == NULL) { fprintf(stderr, "cannot open image file\n"); exit(1); } ``` 在這里,我們打開圖像文件。 在當前工作目錄中,我們應該有`woman.jpg`文件。 ```perl fseek(fp, 0, SEEK_END); if (ferror(fp)) { fprintf(stderr, "fseek() failed\n"); int r = fclose(fp); if (r == EOF) { fprintf(stderr, "cannot close file handler\n"); } exit(1); } ``` 我們使用`fseek()`函數將文件指針移到文件末尾。 我們將確定圖像的大小。 如果發生錯誤,則設置錯誤指示器。 我們使用`fseek()`函數檢查指示器。 如果發生錯誤,我們還將關閉打開的文件處理器。 ```perl int flen = ftell(fp); if (flen == -1) { perror("error occurred"); int r = fclose(fp); if (r == EOF) { fprintf(stderr, "cannot close file handler\n"); } exit(1); } ``` 對于二進制流,`ftell()`函數返回文件開頭的字節數,例如圖像文件的大小。 如果發生錯誤,該函數將返回 -1 并設置`errno`。 `perrro()`函數將`errno`的值解釋為錯誤消息,并將其打印到標準錯誤輸出流。 ```perl char data[flen+1]; ``` 在這個數組中,我們將存儲圖像數據。 ```perl int size = fread(data, 1, flen, fp); ``` 我們從文件指針讀取數據并將其存儲在數據數組中。 返回成功讀取的元素總數。 ```perl int r = fclose(fp); if (r == EOF) { fprintf(stderr, "cannot close file handler\n"); } ``` 讀取數據后,我們可以關閉文件處理器。 ```perl char chunk[2*size+1]; mysql_real_escape_string(con, chunk, data, size); ``` `mysql_real_escape_string()`函數在傳遞給該函數的字符串中的某些潛在危險字符之前添加轉義字符反斜杠`\`。 這可以幫助防止 SQL 注入攻擊。 新緩沖區的長度必須至少為`2*size+1`。 ```perl char *st = "INSERT INTO Images(Id, Data) VALUES(1, '%s')"; size_t st_len = strlen(st); ``` 在這里,我們開始構建 SQL 語句。 我們使用`strlen()`函數確定 SQL 字符串的大小。 ```perl char query[st_len + 2*size+1]; int len = snprintf(query, st_len + 2*size+1, st, chunk); ``` 查詢的時間必須足夠長,以包含 SQL 字符串語句的大小和圖像文件的大小。 使用`snprintf()`函數,將格式化的輸出寫入查詢緩沖區。 ```perl if (mysql_real_query(con, query, len)) { finish_with_error(con); }; ``` 我們使用`mysql_real_query()`函數執行查詢。 `mysql_query()`不能用于包含二進制數據的語句; 我們必須改用`mysql_real_query()`。 ## 從 MySQL 數據庫中選擇圖像 在前面的示例中,我們已將圖像插入數據庫。 在下面的示例中,我們將從數據庫中選擇回插入的圖像。 ```perl #include <my_global.h> #include <mysql.h> void finish_with_error(MYSQL *con) { fprintf(stderr, "%s\n", mysql_error(con)); mysql_close(con); exit(1); } int main(int argc, char **argv) { FILE *fp = fopen("woman2.jpg", "wb"); if (fp == NULL) { fprintf(stderr, "cannot open image file\n"); exit(1); } MYSQL *con = mysql_init(NULL); if (con == NULL) { fprintf(stderr, "mysql_init() failed\n"); exit(1); } if (mysql_real_connect(con, "localhost", "user12", "34klq*", "testdb", 0, NULL, 0) == NULL) { finish_with_error(con); } if (mysql_query(con, "SELECT Data FROM Images WHERE Id=1")) { finish_with_error(con); } MYSQL_RES *result = mysql_store_result(con); if (result == NULL) { finish_with_error(con); } MYSQL_ROW row = mysql_fetch_row(result); unsigned long *lengths = mysql_fetch_lengths(result); if (lengths == NULL) { finish_with_error(con); } fwrite(row[0], lengths[0], 1, fp); if (ferror(fp)) { fprintf(stderr, "fwrite() failed\n"); mysql_free_result(result); mysql_close(con); exit(1); } int r = fclose(fp); if (r == EOF) { fprintf(stderr, "cannot close file handler\n"); } mysql_free_result(result); mysql_close(con); exit(0); } ``` 在此示例中,我們將從數據庫中創建一個圖像文件。 ```perl FILE *fp = fopen("woman2.jpg", "wb"); if (fp == NULL) { fprintf(stderr, "cannot open image file\n"); exit(1); } ``` 我們打開一個新的文件處理器進行寫入。 ```perl if (mysql_query(con, "SELECT Data FROM Images WHERE Id=1")) { finish_with_error(con); } ``` 我們使用`Id` 1 從`Image`表中選擇`Data`列。 ```perl MYSQL_ROW row = mysql_fetch_row(result); ``` 該行包含原始數據。 ```perl unsigned long *lengths = mysql_fetch_lengths(result); ``` 我們得到圖像的長度。 ```perl fwrite(row[0], lengths[0], 1, fp); if (ferror(fp)) { fprintf(stderr, "fwrite() failed\n"); mysql_free_result(result); mysql_close(con); exit(1); } ``` 我們使用`fwrite()`函數調用將檢索到的數據寫入磁盤。 我們使用`ferror()`函數檢查錯誤指示符。 ```perl int r = fclose(fp); if (r == EOF) { fprintf(stderr, "cannot close file handler\n"); } ``` 寫入圖像數據后,使用`fclose()`函數關閉文件處理器。 這是 MySQL C API 教程。 您可能也對 [MySQL Python 教程](/db/mysqlpython/), [MySQL Visual Basic 教程](/db/mysqlvb/)或 [MySQL PHP 教程](/databases/mysqlphptutorial/), [PostgreSQL C 教程](/db/postgresqlc/)或[ [關于 ZetCode 的 SQLite C 教程](/db/sqlitec/)。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看