|
1 MySQL C API C API代碼是隨MySQL分發(fā)的,它被包含在mysqlclient庫且允許C程序存取一個數據庫。 在 MySQL源代碼分發(fā)中的很多客戶是用C編寫的。如果你正在尋找演示怎樣使用C API的例子,看一下這些客戶程序。 大多數其他客戶 API(除了Java的所有)都使用mysqlclient庫與MySQL服務器通信。這意味著,例如,你能利用很多被其他客戶程序使用的同一環(huán)境變量,因為他們從庫中引用。 客戶有一個最大通訊緩沖區(qū)大小。初始分配的緩沖區(qū)大小(16K字節(jié)) 自動地增加到最大尺寸(缺省的最大值是24M)。因為緩沖區(qū)大小只是按保證需求而被增加,簡單地增加缺省的最大限制并不造成更多被消耗。該尺寸檢查主要是一個對錯誤的查詢和通訊包的檢查。 通訊緩沖區(qū)必須足夠大以便一個單獨的SQL語句(對客戶-服務器傳輸)和一行返回的數據(對服務器-客戶傳輸)。每個線程的通訊緩沖區(qū)被動態(tài)擴大到最大限制來處理任何查詢或行。例如,如果你包含大到16M數據的BLOB值,你必須有一個至少16M通訊緩沖區(qū)限制(在服務器和客戶兩端)。客戶的缺省最大值是24M,但是在服務器端的缺省最大值是1M。你可以在服務器啟動時通過改變max_allowed_packet參數的值來改變它。MySQL服務器在每個查詢后縮小每個通訊緩沖區(qū)到net_buffer_length個字節(jié)。對客戶,與一個連接相關的緩沖區(qū)的大小沒被減少,直到連接被關閉,在此時客戶內存被回收。 如果你用線程的編程,你應該用--with-thread-safe-client編譯MySQL C API,這將使C API線程對每個連接更安全。你可以讓2個線程共享相同的連接,只要如果你做下列事情: 兩個線程不能同時在同一個連接上發(fā)送查詢到MySQL。特別是你必須保證在一個 mysql_query()和mysql_store_result()之間沒有其他線程正在使用同一個連接。 許多線程能存取用mysql_store_result()檢索出來的不同結果集合。 如果你使用mysql_use_result,你必須保證沒有其他線程在同一個連接上正在詢問任何東西,直到結果集合被關閉。 2 C API數據類型 MYSQL 這個結構表示對一個數據庫連接的句柄,它被用于幾乎所有的MySQL函數。 MYSQL_RES 這個結構代表返回行的一個查詢的(SELECT, SHOW, DESCRIBE, EXPLAIN)的結果。從查詢返回的信息在本章下文稱為結果集合。 MYSQL_ROW 這是一個行數據的類型安全(type-safe)的表示。當前它實現為一個計數字節(jié)的字符串數組。(如果字段值可能包含二進制數據,你不能將這些視為空終止串,因為這樣的值可以在內部包含空字節(jié)) 行通過調用mysql_fetch_row()獲得。 MYSQL_FIELD 這個結構包含字段信息,例如字段名、類型和大小。其成員在下面更詳細地描述。你可以通過重復調用mysql_fetch_field()對每一列獲得MYSQL_FIELD結構。字段值不是這個結構的部分;他們被包含在一個MYSQL_ROW結構中。 MYSQL_FIELD_OFFSET 這是一個相對一個MySQL字段表的偏移量的類型安全的表示。(由mysql_field_seek()使用。) 偏移量是在一行以內的字段編號,從0開始。 my_ulonglong 該類型用于行編號和mysql_affected_rows()、mysql_num_rows()和mysql_insert_id()。這種類型提供0到1.84e19的一個范圍。在一些系統(tǒng)上,試圖打印類型my_ulonglong的值將不工作。為了打印出這樣的值,將它變換到unsigned long并且使用一個%lu打印格式。 例如: printf (Number of rows: %lu
", (unsigned long) mysql_num_rows(result)); MYSQL_FIELD結構包含列在下面的成員: char * name 字段名,是一個空結尾的字符串。 char * table 包含該字段的表的名字,如果它不是可計算的字段。對可計算的字段,table值是一個空字符串。 char * def 這字段的缺省值,是一個空結尾的字符串。只要你使用,只有你使用mysql_list_fields()才可設置它。 enum enum_field_types type 字段類型。type值可以是下列之一: 類型值 類型含義 FIELD_TYPE_TINY TINYINT字段 FIELD_TYPE_SHORT SMALLINT字段 FIELD_TYPE_LONG INTEGER字段 FIELD_TYPE_INT24 MEDIUMINT字段 FIELD_TYPE_LONGLONG BIGINT字段 FIELD_TYPE_DECIMAL DECIMAL或NUMERIC字段 FIELD_TYPE_FLOAT FLOAT字段 FIELD_TYPE_DOUBLE DOUBLE或REAL字段 FIELD_TYPE_TIMESTAMP TIMESTAMP字段 FIELD_TYPE_DATE DATE字段 FIELD_TYPE_TIME TIME字段 FIELD_TYPE_DATETIME DATETIME字段 FIELD_TYPE_YEAR YEAR字段 FIELD_TYPE_STRING 字符串(CHAR或VARCHAR)字段 FIELD_TYPE_BLOB BLOB或TEXT字段(使用max_length決定最大長度) FIELD_TYPE_SET SET字段 FIELD_TYPE_ENUM ENUM字段 FIELD_TYPE_NULL NULL- 類型字段 FIELD_TYPE_CHAR 不推薦;使用FIELD_TYPE_TINY代替 你可以使用IS_NUM()宏來測試字段是否有一種數字類型。將type值傳給IS_NUM()并且如果字段是數字的,它將計算為TRUE: if (IS_NUM(field->type)) printf("Field is numeric
"); unsigned int length 字段寬度,在表定義中指定。 unsigned int max_length 對結果集合的字段的最大寬度(對實際在結果集合中的行的最長字段值的長度)。如果你使用mysql_store_result()或mysql_list_fields(),這包含字段最大長度。如果你使用mysql_use_result(),這個變量的值是零。 unsigned int flags 字段的不同位標志。flags值可以是零個或多個下列位設置: 標志值 標志含義 NOT_NULL_FLAG 字段不能是NULL PRI_KEY_FLAG 字段是一個主鍵的一部分 UNIQUE_KEY_FLAG 字段是一個唯一鍵的一部分 MULTIPLE_KEY_FLAG 字段是一個非唯一鍵的一部分。 UNSIGNED_FLAG 字段有UNSIGNED屬性 ZEROFILL_FLAG 字段有ZEROFILL屬性 BINARY_FLAG 字段有BINARY屬性 AUTO_INCREMENT_FLAG 字段有AUTO_INCREMENT屬性 ENUM_FLAG 字段是一個ENUM(不推薦) BLOB_FLAG 字段是一個BLOB或TEXT(不推薦) TIMESTAMP_FLAG 字段是一個TIMESTAMP(不推薦) BLOB_FLAG、ENUM_FLAG和TIMESTAMP_FLAG標志的使用是不推薦的,因為他們指出字段的類型而非它的類型屬性。對FIELD_TYPE_BLOB、FIELD_TYPE_ENUM或FIELD_TYPE_TIMESTAMP,最好是測試field->type。下面例子演示了一個典型的flags值用法: if (field->flags & NOT_NULL_FLAG) printf("Field can't be null
"); 你可以使用下列方便的宏決來確定flags值的布爾狀態(tài): IS_NOT_NULL(flags) 真,如果該字段被定義為NOT NULL IS_PRI_KEY(flags) 真,如果該字段是一個主鍵 IS_BLOB(flags) 真,如果該字段是一個BLOB或TEXT(不推薦;相反測試field->type) unsigned int decimals 對數字字段的小數位數。 3 C API函數概述 在 C API 中可用的函數列在下面,并且在下一節(jié)更詳細地描述。見4 C API函數描述。 mysql_affected_row()返回被最新的UPDATE, DELETE或INSERT查詢影響的行數。 關閉一個服務器連接。 mysql_close() 連接一個MySQL服務器。該函數不推薦;使用mysql_real_connect()mysql_connect() 代替。 mysql_change_user改變在一個打開的連接上的用戶和數據庫。 創(chuàng)建一個數據庫。該函數不推薦;而使用SQL命令CREATE mysql_create_db() DATABASE。 在一個查詢結果集合中搜尋一任意行。 mysql_data_seek() 用給定字符串做一個DBUG_PUSH。 mysql_debug() 拋棄一個數據庫。該函數不推薦;而使用SQL命令DROP DATABASE。 mysql_drop_db() mysql_dump_debu讓服務器將調試信息寫入日志文件。 g_info() 確定是否已經讀到一個結果集合的最后一行。這功能被反對; mysql_eof() mysql_errno()或mysql_error()可以相反被使用。 返回最近被調用的MySQL函數的出錯編號。 mysql_errno() 返回最近被調用的MySQL函數的出錯消息。 mysql_error() mysql_escape_string()用在SQL語句中的字符串的轉義特殊字符。 返回下一個表字段的類型。 mysql_fetch_field() mysql_fetch_field_返回一個表字段的類型,給出一個字段編號。 direct () mysql_fetch_fields()返回一個所有字段結構的數組。 mysql_fetch_lengths()返回當前行中所有列的長度。 從結果集合中取得下一行。 mysql_fetch_row() 把列光標放在一個指定的列上。 mysql_field_seek() 返回最近查詢的結果列的數量。 mysql_field_count() 返回用于最后一個mysql_fetch_field()的字段光標的位置。 mysql_field_tell() 釋放一個結果集合使用的內存。 mysql_free_result() mysql_get_client_info()返回客戶版本信息。 mysql_get_host_info()返回一個描述連接的字符串。 mysql_get_proto_info()返回連接使用的協議版本。 mysql_get_server_info()返回服務器版本號。 返回關于最近執(zhí)行得查詢的信息。 mysql_info() 獲得或初始化一個MYSQL結構。 mysql_init() 返回有前一個查詢?yōu)橐粋€AUTO_INCREMENT列生成的ID。 mysql_insert_id() 殺死一個給定的線程。 mysql_kill() 返回匹配一個簡單的正則表達式的數據庫名。 mysql_list_dbs() 返回匹配一個簡單的正則表達式的列名。 mysql_list_fields() mysql_list_processes()返回當前服務器線程的一張表。 返回匹配一個簡單的正則表達式的表名。 mysql_list_tables() 返回一個結果集合重的列的數量。 mysql_num_fields() 返回一個結果集合中的行的數量。 mysql_num_rows() 設置對mysql_connect()的連接選項。 mysql_options() 檢查對服務器的連接是否正在工作,必要時重新連接。 mysql_ping() 執(zhí)行指定為一個空結尾的字符串的SQL查詢。 mysql_query() mysql_real_connect()連接一個MySQL服務器。 執(zhí)行指定為帶計數的字符串的SQL查詢。 mysql_real_query() 告訴服務器重裝授權表。 mysql_reload() 搜索在結果集合中的行,使用從mysql_row_tell()返回的值。 mysql_row_seek() 返回行光標位置。 mysql_row_tell() 連接一個數據庫。 mysql_select_db() 關掉數據庫服務器。 mysql_shutdown() 返回作為字符串的服務器狀態(tài)。 mysql_stat() mysql_store_result()檢索一個完整的結果集合給客戶。 返回當前線程的ID。 mysql_thread_id() 初始化一個一行一行地結果集合的檢索。 mysql_use_result() 為了連接服務器,調用mysql_init()以初始化一個連接處理器,然后用該處理器調用mysql_real_connect()(還有其他信息例如主機名、用戶名和口令)。當你用該連接完成工作后,調用mysql_close()終止它。 當一個連接活躍時,客戶可以用mysql_query()或mysql_real_query()將SQL查詢發(fā)送到服務器。兩者的差別是mysql_query()期望查詢作為一個空結尾的字符串來指定而mysql_real_query()期望一個計數的字符串。如果字符串包含二進制數據(它可以包括空字節(jié)),你必須使用mysql_real_query()。 對與每個非--SELECT查詢(例如,INSERT、UPDATE、DELETE等),你可以調用mysql_affected_rows()知道有多少行受到影響(改變)。 對于SELECT查詢,你作為一個結果集合來檢索選擇的行。(注意一些語句是類SELECT的,他們返回行。這些包括SHOW、DESCRIBE和EXPLAIN。他們應該象SELECT語句相同的方式來對待。) 對客戶,有兩種方法處理結果集合。一種方法是通過調用mysql_store_result()立刻檢索全部結果。該函數從服務器獲得查詢返回的所有行,并將他們存儲在客戶端。第二種方法是對客戶通過調用mysql_use_result()初始化一個一行一行地結果集合的檢索。該函數初始化檢索,但是實際上不從服務器獲得任何行。 在兩種情況中,你通過mysql_fetch_row()存取行。用mysql_store_result()、mysql_fetch_row() 儲存取已經從服務器被取出的行。用mysql_use_result()、mysql_fetch_row()實際上從服務器檢索行。調用mysql_fetch_lengths()可獲得關于每行中數據值尺寸的信息。 在你用完一個結果集合以后,調用mysql_free_result()釋放由它使用的內存。 兩種檢索機制是互補的??蛻舫绦驊撨x擇最適合他們的要求的途徑。在實踐中,客戶通常更愿意使用mysql_store_result()。 mysql_store_result()的一個優(yōu)點是既然行均被客戶取到,你不僅能順序存取行,你也能mysql_data_seek()或mysql_row_seek()在結果集合中前后移動以改變在結果集合中的當前行位置。你也能通過調用mysql_num_rows()知道有多少行。另一方面,mysql_store_result()的內存需求對較大結果集合可能很高,并且你最可能遇到out-of-memory情況。 mysql_use_result()的一個優(yōu)點是客戶為結果集合需要較少的內存,因為它一次只是維持一行(并且因為有較少的分配開銷,mysql_use_result()能更快些)。缺點是你必須盡快處理每一行以避免困住服務器,你不必再結果集合中隨意存取行(你只能順序存取行),而且你不知道在結果集合中有多少行,直到你檢索全部結果。還有,你必須檢索出所有行,即使你在檢索中途確定你已找到了想尋找的信息。 API使得客戶正確應答查詢成為可能(僅檢索必要的行),不用知道查詢是否是一個SELECT。你可以通過在mysql_query()(或mysql_real_query())之后調用mysql_store_result()做到。如果結果集合調用成功并且查詢是一個SELECT,你能讀取行。如果結果集合調用,調用mysql_field_count()確定結果是否是實際期望的。如果mysql_field_count()返回0,查詢沒有返回數據(表明它是一個INSERT、UPDATE、DELETE等),所以不期望返回行。如果mysql_field_count()是非零,查詢應該有返回行,但是沒有。這表明查詢是一個失敗的SELECT。見mysql_field_count()如何能做到的例子的描述。 mysql_store_result()和mysql_use_result()都允許你獲得有關組成結果集合的字段的信息(字段數量、他們的名字和類型等等)。你可以通過重復調用mysql_fetch_field()在行中順序存取字段信息,或調用mysql_fetch_field_direct()存取行中的字段編號。當前字段光標位置可以通過調用mysql_field_seek()改變,設置字段光標影響到后續(xù)mysql_fetch_field()調用。你也能通過調用mysql_fetch_fields()馬上獲得字段信息。 對于檢測和報告錯誤,MySQL借助于mysql_errno()和mysql_error()函數提供錯誤信息的存取。他們返回最近調用的可能成功或失敗的函數的錯誤代碼或錯誤消息,允許你確定何時發(fā)生一個錯誤和什么錯誤。 4 C API函數描述 在下面的描述中,一個NULL參數或返回值含義是在C編程語言環(huán)境的NULL,不是一個MySQL NULL值。 返回一個值的函數一般返回一個指針或一個整數。除非另外指定,返回一個指針的函數返回一個非 NULL值表明成功,或一個NULL值表明一個錯誤,而返回一個整數的函數返回零表示成功,或非零表示一個錯誤。注意,“非零”只有這個含義。除非函數描述另外說明,不要測試一個零以外的其他值: if (result) /* 正確 */ ... error ... if (result < 0) /* 不正確 */ ... error ... if (result == -1) /* 不正確 */ ... error ... 當函數返回一個錯誤時,函數描述的錯誤小節(jié)列出錯誤可能的類型。你可以調用mysql_errno()找出發(fā)生了這些重的哪一個。錯誤的字符串表示可以調用mysql_error()獲得。 4.1 mysql_affected_rows() my_ulonglong mysql_affected_rows(MYSQL *mysql) 4.1.1 說明 返回受到最后一個UPDATE、DELETE或INSERT查詢影響(變化)的行數??梢栽卺槍PDATE、DELETE或INSERT語句的mysql_query()之后立即調用。對于SELECT語句,mysql_affected_rows()的功能于mysql_num_rows()相同。 mysql_affected_rows()目前以一個宏(macro)來實現。 4.1.2 返回值 大于零的一個整數表示受到影響或檢索出來的行數。零表示沒有匹配查序中WHERE子句的記錄或目前還沒有查詢被執(zhí)行。-1表示查詢返回一個錯誤,或對于一個SELECT查詢,mysql_affected_rows()在調用mysql_store_result()之前被調用。 4.1.3 錯誤 沒有。 4.1.4 范例 mysql_query(&mysql,"UPDATE products SET cost=cost*1.25 WHERE group=10"); printf("%d products updated",mysql_affected_rows(&mysql)); 4.2 mysql_close() void mysql_close(MYSQL *mysql) 4.2.1 說明 關閉一個以前打開了的連接。如果句柄由mysql_init()或mysql_connect()自動分配,mysql_close()也釋放被mysql指向的連接句柄。 4.2.2 返回值 沒有。 4.2.3 錯誤 CR_COMMANDS_OUT_OF_SYNC 命令以一個不正確的次序被執(zhí)行。 CR_SERVER_GONE_ERROR MySQL服務器關閉了。 CR_SERVER_LOST 對服務者的連接在查詢期間失去。 CR_UNKNOWN_ERROR 發(fā)生一個未知的錯誤。 4.3 mysql_connect() MYSQL *mysql_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd) 4.3.1 說明 該函數不推薦使用,而更好使用mysql_real_connect()。 mysql_connect()試圖建立一個對運行在host的一個MySQL數據庫引擎的連接。mysql_connect()必須在你能執(zhí)行其他API函數之前成功地完成,除了mysql_get_client_info()。 參數的含義與mysql_connect()相應的參數相同,不同的是連接參數可以是NULL。在這種情況下,C API 自動為連接結構分配內存,并且當你調用mysql_close(),釋放它。這種方法的缺點是如果連接失敗,你不能檢索出一條錯誤消息。(為了從mysql_errno()或mysql_error()得到錯誤信息,你必須提供一個有效的MYSQL指針。) 4.3.2 返回值 同mysql_real_connect()。 4.3.3 錯誤 同mysql_real_connect()。 4.4mysql_change_user() my_bool mysql_change_user(MYSQL *mysql, const char *user, const char *password, const char *db) 4.4.1 說明 改變用戶并且使得由db指定數據庫成為由mysql指定的連接上的缺省(當前)數據庫。在隨后的查詢中,這個數據庫是不包括一個明確的數據庫指定符的表引用的缺省值。 這個函數功能在MySQL 3.23.3中引入。 除非連接的用戶能被認證或如果他沒有權限使用數據庫,mysql_change_user()失敗。在這種情況下,用戶和數據庫都沒被改變。 如果你不想有一個缺省數據庫,db參數可以被設置為NULL。 4.4.2 返回值 成功,零。如果發(fā)生一個錯誤發(fā)生,非零。 4.4.3 錯誤 與你能從mysql_real_connect()得到的相同。 CR_COMMANDS_OUT_OF_SYNC 命令以一個不正確的次序被執(zhí)行。 CR_SERVER_GONE_ERROR MySQL服務者關閉了。 CR_SERVER_LOST 對服務者的連接在查詢期間失去。 CR_UNKNOWN_ERROR 發(fā)生一個未知的錯誤。 ER_UNKNOWN_COM_ERROR MySQL服務器未實現這個命令(可能是一個老的服務器) ER_ACCESS_DENIED_ERROR 用戶或口令錯誤。 ER_BAD_DB_ERROR 數據庫不存在。 ER_DBACCESS_DENIED_ERROR 用戶沒有數據庫的存取權利。 ER_WRONG_DB_NAME 數據庫名字太長。 4.4.4 范例 if (mysql_change_user(&mysql, "user", "password", "new_database")) { fprintf(stderr, "Failed to change user. Error: %s
", mysql_error(&mysql)); } 4.5 mysql_create_db() int mysql_create_db(MYSQL *mysql, const char *db) 4.5.1 說明 創(chuàng)建由db參數命名的數據庫。 這個函數不推薦,而最好使用mysql_query()發(fā)出一條SQL CREATE DATABASE語句。 4.5.2 返回值 如果數據庫成功地被創(chuàng)造,零。如果發(fā)生一個錯誤,非零。 4.5.3 錯誤 CR_COMMANDS_OUT_OF_SYNC 命令以一個不正確的次序被執(zhí)行。 CR_SERVER_GONE_ERROR MySQL服務器關閉了。 CR_SERVER_LOST 對服務者的連接在查詢期間失去。 CR_UNKNOWN_ERROR 發(fā)生一個未知的錯誤。 4.5.4 范例 if(mysql_create_db(&mysql, "my_database")) { fprintf(stderr, "Failed to create new database. Error: %s
", mysql_error(&mysql)); } 4.6 mysql_data_seek() void mysql_data_seek(MYSQL_RES *result, unsigned long long offset) 4.6.1 說明 在一個查詢結果集合中定位任意行。這要求結果集合結構包含查詢的全部結果,這樣mysql_data_seek()可以僅需與mysql_store_result()一起使用,不是與mysql_use_result()。 偏移量應該是從0到mysql_num_rows(result)-1范圍的一個值。 4.6.2 返回值 無。 4.6.3 錯誤 無。 4.7 mysql_debug() void mysql_debug(char *debug) 4.7.1 說明 用一個給定字符串做一個DBUG_PUSH。mysql_debug()使用Fred Fish 調試庫。為了使用這個函數,你必須編譯客戶庫以支持調試。見G.1 調試一個MySQL服務器和節(jié)G.2 調試一個MySQL客戶。 4.7.2 返回值 無。 4.7.3 錯誤 無。 4.7.4 范例 下面所示的調用使得客戶庫在客戶機器上的“/tmp/client.trace”中產生一個跟蹤文件: mysql_debug("d:t:O,/tmp/client.trace"); 4.8 mysql_drop_db() int mysql_drop_db(MYSQL *mysql, const char *db) 4.8.1 說明 拋棄由db參數命名的數據庫。 這個函數不推薦,而最好使用mysql_query()發(fā)出一條SQL DROP DATABASE語句。 4.8.2 返回值 如果數據庫成功地被破拋棄,零。如果發(fā)生一個錯誤,非零。 4.8.3 錯誤 CR_COMMANDS_OUT_OF_SYNC 命令以一個不正確的次序被執(zhí)行。 CR_SERVER_GONE_ERROR MySQL服務器關閉了。 CR_SERVER_LOST 對服務者的連接在查詢期間失去。 CR_UNKNOWN_ERROR 發(fā)生一個未知的錯誤。 4.8.4 范例 if(mysql_drop_db(&mysql, "my_database")) fprintf(stderr, "Failed to drop the database: Error: %s
", mysql_error(&mysql)); 4.9 mysql_dump_debug_info() int mysql_dump_debug_info(MYSQL *mysql) 4.9.1 說明 指示服務者將一些調試信息寫入日志文件。連接的用戶對此必須有precess權限才能工作。 4.9.2 返回值 如果命令成功,零。如果發(fā)生一個錯誤,非零。 4.9.3 錯誤 CR_COMMANDS_OUT_OF_SYNC 命令以一個不正確的次序被執(zhí)行。 CR_SERVER_GONE_ERROR MySQL服務者關閉了。 CR_SERVER_LOST 對服務器的連接在查詢期間失去。 CR_UNKNOWN_ERROR 發(fā)生一個未知的錯誤。 4.10 mysql_eof() my_bool mysql_eof(MYSQL_RES *result) 4.10.1 說明 這個函數不推薦,而使用mysql_errno()或mysql_error()。 mysql_eof()確定是否已經讀到了一個結果集合的最后一行。 如果你從成功的mysql_store_result()調用獲得一個結果集合,客戶程序用一個操作收到全部集合。在這種情況下,從mysql_fetch_row()返回一個NULL總是意味著已經到達了結果集合的尾部,沒必要調用mysql_eof()。 在另一方面,如果你使用mysql_use_result()初始化一個結果集合的檢索,該集合的行隨著你重復調用mysql_fetch_row()一個一個地從服務器獲得。因為在這個過程中在連接上可能發(fā)生一個錯誤,從mysql_fetch_row()返回一個NULL值并不意味著集合正常到達了尾部。在這種情況下,你能使用mysql_eof()確定發(fā)生了什么。如果到達結果集合的尾部,mysql_eof()返回非零值,并且如果發(fā)生一個錯誤,返回零。 在時間上,mysql_eof()先于標準MySQL錯誤函數mysql_errno()和mysql_error()。因為這些錯誤函數提供相同的信息,他們的使用更好mysql_eof(),它現在不建議使用。(事實上,他們提供更多的信息,因為mysql_eof()值返回一個布爾值,而錯誤函數指出當發(fā)生錯誤時的出錯原因。) 4.10.2 返回值 如果發(fā)生一個錯誤,零。如果到達結果集合的結束,非零。 4.10.3 錯誤 無。 4.10.4 范例 下列例子顯示你必須如何使用mysql_eof(): mysql_query(&mysql,"SELECT * FROM some_table"); result = mysql_use_result(&mysql); while((row = mysql_fetch_row(result))) { // do something with data } if(!mysql_eof(result)) // mysql_fetch_row() failed due to an error { fprintf(stderr, "Error: %s
", mysql_error(&mysql)); } 然而,你可以用標準MySQL錯誤函數完成同樣的效果: mysql_query(&mysql,"SELECT * FROM some_table"); result = mysql_use_result(&mysql); while((row = mysql_fetch_row(result))) { // do something with data } if(mysql_errno(&mysql)) // mysql_fetch_row() failed due to an error { fprintf(stderr, "Error: %s
", mysql_error(&mysql)); } 4.11 mysql_errno() unsigned int mysql_errno(MYSQL *mysql) 4.11.1 說明 對于由mysql指定的連接,mysql_errno()返回最近調用的可能成功或失敗的API函數的錯誤代碼。返回值零意味著沒有錯誤發(fā)生。客戶錯誤消息編號列出在MySQL“errmsg.h”頭文件中。服務器錯誤消息編號列出在“mysqld_error.h”中。 4.11.2 返回值: 一個錯誤代碼值。如果沒有錯誤發(fā)生,零。 4.11.3 錯誤 無。 4.12 mysql_error() char *mysql_error(MYSQL *mysql) 4.12.1 說明 對于由mysql指定的連接,mysql_errno()返回最近調用的可能成功或失敗的API函數的錯誤代碼。如果沒有錯誤發(fā)生,返回空字符串("")。這意味著下列兩個測試是等價的: if(mysql_errno(&mysql)) { // an error occurred } if(mysql_error(&mysql)[0] != '
青娱乐大香蕉在线视频
|
中文字幕+乱码+中文乱码电影
|
黄色一级视频在线播放
|
亚洲高清在线观看视频
|
老欧性老太色HD大全
|
亚欧成人精品无码视频在线观看
|
大鸡巴久久久久久久久
|
逼逼逼逼五月情
|
好逼国产
|
东方成人av
|
|