第25章:API和庫

目錄

25.1. libmysqld,嵌入式MySQL伺服器庫
25.1.1. 嵌入式MySQL伺服器庫概述
25.1.2. 使用libmysqld編譯程式
25.1.3. 使用嵌入式MySQL伺服器時的限制
25.1.4. 與嵌入式伺服器一起使用的選項
25.1.5. 嵌入式伺服器中尚需完成的事項(TODO)
25.1.6. 嵌入式伺服器示範
25.1.7. 嵌入式伺服器的授權
25.2. MySQL C API
25.2.1. C API數據類型
25.2.2. C API函數概述
25.2.3. C API函數描述
25.2.4. C API預處理語句
25.2.5. C API預處理語句的數據類型
25.2.6. C API預處理語句函數概述
25.2.7. C API預處理語句函數描述
25.2.8. C API預處理語句方面的問題
25.2.9. 多查詢執行的C API處理
25.2.10. 日期和時間值的C API處理
25.2.11. C API線程函數介紹
25.2.12. C API嵌入式伺服器函數介紹
25.2.13. 使用C API時的常見問題
25.2.14. 建立客戶端程式
25.2.15. 如何生成線程式客戶端
25.3. MySQL PHP API
25.3.1. 使用MySQL和PHP的常見問題
25.4. MySQL Perl API
25.5. MySQL C++ API
25.5.1. Borland C++
25.6. MySQL Python API
25.7. MySQL Tcl API
25.8. MySQL Eiffel Wrapper
25.9. MySQL程式開發實用工具
25.9.1. msql2mysql:轉換mSQL程式以用於MySQL
25.9.2. mysql_config:獲取編譯客戶端的編譯選項

本章介紹了MySQL可使用的API,從哪裡獲得它們,以及如何使用它們。 詳細介紹C API,這是因為它是由MySQL團隊開發的,而且它也是大多數其他API的基礎。 本章還介紹了libmysqld庫(嵌入式伺服器),以及對應用程式開發人員有用的一些程式。

25.1. libmysqld,嵌入式MySQL伺服器庫

25.1.1. 嵌入式MySQL伺服器庫概述

使用嵌入式MySQL伺服器庫,能夠在客戶端應用程式中使用具備全部特性的MySQL伺服器。 主要優點在於,增加了速度,並使得嵌入式應用程式的管理更簡單。

嵌入式伺服器庫是以MySQL的客戶端/伺服器版本為基礎的,採用C/C++語言編寫。 其結果是嵌入式伺服器也是用C/C++語言編寫的。 在其他語言中,嵌入式伺服器不可用。

API與嵌入式MySQL版本和客戶端/伺服器版本等效。 要想更改舊的線程式應用程式以使用嵌入式庫,正常情況下,僅需新增對下述函數的使用即可。

函數

何時使用

mysql_server_init()

應在使用任何其他MySQL函數之前使用,最好是在main()函數中使用。

mysql_server_end()

應在程式退出前使用。

mysql_thread_init()

應在您所建立的、用於訪問MySQL的每個線程中使用。

mysql_thread_end()

應在使用pthread_exit()之前使用。

隨後,必須將您的代碼與libmysqld.a連結起來,而不是libmysqlclient.a。

libmysqlclient.a中還包含mysql_server_xxx()函數,使用這類函數,通過將應用程式連結到恰當的庫,即可在嵌入式版本和客戶端/伺服器版本之間切換。 請參見25.2.12.1節,「mysql_server_init()」

嵌入式伺服器和獨立伺服器之間的一項差別在於,對於嵌入式伺服器,預設情況下,連接鑒定是禁止的。 對於嵌入式伺服器,要想使用鑒定功能,可在激活「configure」以配置MySQL分發版時使用「--with-embedded-privilege-control」選項。

25.1.2. 使用libmysqld編譯程式

要想獲得libmysqld庫,應使用--with-embedded-server選項配置MySQL 請參見2.8.2節,「典型配置選項

將您的程式與libmysqld連結時,還必須包含系統的pthread庫以及MySQL伺服器使用的一些庫。 執行「mysql_config --libmysqld-libs」,可獲得庫的完整列資料表。

對於線程程式的編譯和連結,必須使用正確的標誌,即使您未在代碼中直接使用任何線程函數也同樣。

要想編譯C程式以包含必要檔案,並將MySQL伺服器庫嵌入到程式的編譯版本中,可使用GNU C編譯器(gcc)。 編譯器需要知道各種檔案的位置,並需瞭解如何編譯程式的指令。 在下面的示範中,介紹了如何從命令行編譯程式的方法:

gcc mysql_test.c -o mysql_test -lz \
`/usr/local/mysql/bin/mysql_config --include --libmysqld-libs`

在gcc命令後緊跟著未編譯C程式檔案的名稱。 接下來,給定的「-o」選項指明,它後面的檔案名是編譯器將輸出檔案的名稱,即編譯後的程式。 在下一行的代碼中,通知編譯器獲取包含檔案和庫的位置,以及在其上進行編譯的系統的其他設置。 由於「mysql_config」存在的問題,在此新增了「-lz」選項(壓縮)。 「mysql_config」部分包含在backticks中,而不是單引號內。

25.1.3. 使用嵌入式MySQL伺服器時的限制

嵌入式伺服器存在下述限制:

·         不支援ISAM資料表。 (這樣做的主要目的是為了使庫更小)。

·         沒有自行定義函數(UDF)。

·         沒有對核心轉儲的堆棧跟蹤。

·         沒有內部RAID支援。 (由於大多數當前作業系統均支援大檔案,通常情況下不需要它)。

·         不能將其設置為「主」或「從」(無複製)。

·         在內存較低的系統上,可能無法使用很大的結果集。

·         不能使用套接字或TCP/IP從外部程序連接到嵌入式伺服器。 但是,您可以連接到中間應用程式,隨後,該中間應用程式可代資料表遠程客戶端或外部程序連接到嵌入式伺服器。

通過編輯「mysql_embed.h」包含檔案並重新編譯MySQL,可更改某些限制。

25.1.4. 與嵌入式伺服器一起使用的選項

對於任何能夠與mysqld伺服器端口監督程式一起給定的選項,也可以與嵌入式伺服器庫一起使用。在數組中,可將伺服器選項作為參量指定給用於初始化伺服器的mysql_server_init()。也能在諸如my.cnf的選項檔案中給定它們。要想為C程式指定選項檔案,請使用「--defaults-file選項作為函數mysql_server_init()的第2個參量的元素之一。關於mysql_server_init()函數的更多訊息,請參見25.2.12.1節,「mysql_server_init()」

使用選項檔案,能夠簡化客戶端/伺服器應用程式和嵌入了MySQL的應用程式之間的切換。將常用選項置於[server]組。它們可被兩種MySQL版本讀取。客戶端/伺服器選項應被放在[mysqld]部分。將嵌入式MySQL伺服器庫的選項放在[embedded]部分。將與應用程式相關的選項放在標記為[ApplicationName_SERVER]的部分。請參見4.3.2節,「使用選項檔案」

25.1.5. 嵌入式伺服器中尚需完成的事項(TODO)

·         我們將提供一些選項以省去MySQL的某些部分,從而使庫變得更小。

·         仍有很多速度最佳化工作需要完成。

·         錯誤將被寫入stderr。我們將增加1個選項為它們指定檔案名。

·         使用嵌入式版本時,需要更改InnoDB,使之不再冗長。如果您的資料庫不含InnoDB資料表,要想抑制相關消息,可為組[libmysqd_server]下的選項檔案增加--skip-innodb」選項,或在用mysql_server_init()初始化伺服器時新增該選項。

25.1.6. 嵌入式伺服器示範

LinuxFreeBSD系統上,無需更改就能使用下面這兩個示範程式。對於其他作業系統,需要進行小的修改,主要是檔案路徑。設計這兩個示範的目的在於,為您提供足夠的細節訊息,以便理解問題,它們是實際應用程式的必要組成部份。第1個示範十分直觀。第2個示範採用了一些錯誤檢查功能,略為複雜。在第1個示範的後面,給出了用於編譯程式的命令行條目。在第2個示範的後面,給出了GNUmake檔案,該檔案可用於編譯。

示範:1

test1_libmysqld.c

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include "mysql.h"
 
MYSQL *mysql;
MYSQL_RES *results;
MYSQL_ROW record;
 
static char *server_options[] = { "mysql_test", "--defaults-file=my.cnf" };
int num_elements = sizeof(server_options)/ sizeof(char *);
 
static char *server_groups[] = { "libmysqld_server", "libmysqld_client" };
 
int main(void)
{
   mysql_server_init(num_elements, server_options, server_groups);
   mysql = mysql_init(NULL);
   mysql_options(mysql, MYSQL_READ_DEFAULT_GROUP, "libmysqld_client");
   mysql_options(mysql, MYSQL_OPT_USE_EMBEDDED_CONNECTION, NULL);
 
   mysql_real_connect(mysql, NULL,NULL,NULL, "database1", 0,NULL,0);
 
   mysql_query(mysql, "SELECT column1, column2 FROM table1");
 
   results = mysql_store_result(mysql);
 
   while((record = mysql_fetch_row(results))) {
      printf("%s - %s \n", record[0], record[1]);
   }
 
   mysql_free_result(results);
   mysql_close(mysql);
   mysql_server_end();
 
   return 0;
}

下面給出了編譯上述程式的命令行命令:

gcc test1_libmysqld.c -o test1_libmysqld -lz \
 `/usr/local/mysql/bin/mysql_config --include --libmysqld-libs`

示範:2

要想檢驗該示範,建立一個與MySQL源目錄同級的test2_libmysqld目錄。將test2_libmysqld.c源檔案和GNUmakefile保存到該目錄,並在test2_libmysqld目錄下運行GNU make

test2_libmysqld.c

/*
 * A simple example client, using the embedded MySQL server library
*/
 
#include <mysql.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
 
MYSQL *db_connect(const char *dbname);
void db_disconnect(MYSQL *db);
void db_do_query(MYSQL *db, const char *query);
 
const char *server_groups[] = {
  "test2_libmysqld_SERVER", "embedded", "server", NULL
};
 
int
main(int argc, char **argv)
{
  MYSQL *one, *two;
 
  /* mysql_server_init() must be called before any other mysql
   * functions.
   *
   * You can use mysql_server_init(0, NULL, NULL), and it
   * initializes the server using groups = {
   *   "server", "embedded", NULL
   *  }.
   *
   * In your $HOME/.my.cnf file, you probably want to put:
 
[test2_libmysqld_SERVER]
language = /path/to/source/of/mysql/sql/share/english
 
   * You could, of course, modify argc and argv before passing
   * them to this function.  Or you could create new ones in any
   * way you like.  But all of the arguments in argv (except for
   * argv[0], which is the program name) should be valid options
   * for the MySQL server.
   *
   * If you link this client against the normal mysqlclient
   * library, this function is just a stub that does nothing.
   */
  mysql_server_init(argc, argv, (char **)server_groups);
 
  one = db_connect("test");
  two = db_connect(NULL);
 
  db_do_query(one, "SHOW TABLE STATUS");
  db_do_query(two, "SHOW DATABASES");
 
  mysql_close(two);
  mysql_close(one);
 
  /* This must be called after all other mysql functions */
  mysql_server_end();
 
  exit(EXIT_SUCCESS);
}
 
static void
die(MYSQL *db, char *fmt, ...)
{
  va_list ap;
  va_start(ap, fmt);
  vfprintf(stderr, fmt, ap);
  va_end(ap);
  (void)putc('\n', stderr);
  if (db)
    db_disconnect(db);
  exit(EXIT_FAILURE);
}
 
MYSQL *
db_connect(const char *dbname)
{
  MYSQL *db = mysql_init(NULL);
  if (!db)
    die(db, "mysql_init failed: no memory");
  /*
   * Notice that the client and server use separate group names.
   * This is critical, because the server does not accept the
   * client's options, and vice versa.
   */
  mysql_options(db, MYSQL_READ_DEFAULT_GROUP, "test2_libmysqld_CLIENT");
  if (!mysql_real_connect(db, NULL, NULL, NULL, dbname, 0, NULL, 0))
    die(db, "mysql_real_connect failed: %s", mysql_error(db));
 
  return db;
}
 
void
db_disconnect(MYSQL *db)
{
  mysql_close(db);
}
 
void
db_do_query(MYSQL *db, const char *query)
{
  if (mysql_query(db, query) != 0)
    goto err;
 
  if (mysql_field_count(db) > 0)
  {
    MYSQL_RES   *res;
    MYSQL_ROW    row, end_row;
    int num_fields;
 
    if (!(res = mysql_store_result(db)))
      goto err;
    num_fields = mysql_num_fields(res);
    while ((row = mysql_fetch_row(res)))
    {
      (void)fputs(">> ", stdout);
      for (end_row = row + num_fields; row < end_row; ++row)
        (void)printf("%s\t", row ? (char*)*row : "NULL");
      (void)fputc('\n', stdout);
    }
    (void)fputc('\n', stdout);
    mysql_free_result(res);
  }
  else
    (void)printf("Affected rows: %lld\n", mysql_affected_rows(db));
 
  return;
 
err:
  die(db, "db_do_query failed: %s [%s]", mysql_error(db), query);
}

GNUmakefile

# This assumes the MySQL software is installed in /usr/local/mysql
inc      := /usr/local/mysql/include/mysql
lib      := /usr/local/mysql/lib
 
# If you have not installed the MySQL software yet, try this instead
#inc      := $(HOME)/mysql-5.1/include
#lib      := $(HOME)/mysql-5.1/libmysqld
 
CC       := gcc
CPPFLAGS := -I$(inc) -D_THREAD_SAFE -D_REENTRANT
CFLAGS   := -g -W -Wall
LDFLAGS  := -static
# You can change -lmysqld to -lmysqlclient to use the
# client/server library
LDLIBS    = -L$(lib) -lmysqld -lz -lm -lcrypt
 
ifneq (,$(shell grep FreeBSD /COPYRIGHT 2>/dev/null))
# FreeBSD
LDFLAGS += -pthread
else
# Assume Linux
LDLIBS += -lpthread
endif
 
# This works for simple one-file test programs
sources := $(wildcard *.c)
objects := $(patsubst %c,%o,$(sources))
targets := $(basename $(sources))
 
all: $(targets)
 
clean:
        rm -f $(targets) $(objects) *.core

25.1.7. 嵌入式伺服器的授權

我們鼓勵所有人在GPL或兼容授權的旗幟下通過發佈代碼來推廣免費軟件。對於有能力完成該類事項的人員,也可以選擇從MySQL AB購買MySQL的商用授權。詳情請參見http://www.mysql.com/company/legal/licensing/

25.2. MySQL C API

C API代碼是與MySQL一起提供的。它包含在mysqlclient庫中,並允許C程式訪問資料庫。

MySQL原始碼分發版的很多客戶端是用C語言編寫的。如果您正在尋找能演示如何使用C API的示範,可參看這些客戶端程式。您可以在MySQL原始碼分發版的客戶端目錄下找到它們。

大多數其他客戶端API(除了Connector/JConnector/NET)採用mysqlclient庫來與MySQL伺服器進行通信。這意味著(例如),您可以利用很多相同環境變數(與其他客戶端程式使用的環境變數相同)帶來的好處,這是因為它們是從庫中引用的。關於這些變數的詳細清單,請參見第8章:客戶端和實用工具程式

客戶端具有最大的通信緩衝區大小。初始分配的緩衝區大小(16KB)將自動增加到最大(最大為16MB)。由於緩衝區大小將按需增加,簡單地增加預設的最大限制,從其本身來說不會增加資源使用。該大小檢查主要是檢查錯誤查詢和通信訊息包。

通信緩衝區必須足夠大,足以包含1SQL語句(用於客戶端-伺服器通信)以及1行返回的數據(用於伺服器-客戶端通信)。每個線程的通信緩衝區將動態增加,以處理直至最大限制的任何查詢或行。例如,如果BLOB值包含高達16MB的數據,那麼通信緩衝區的大小限制至少為16MB(在伺服器和客戶端)。客戶端的預設最大值為16MB,但伺服器的預設最大值為1MB。也可以在啟動伺服器時,通過更改max_allowed_packet參數的值增加它。請參見7.5.2節,「調節伺服器參數」

每次查詢後,MySQL伺服器會將通信緩衝區的大小降至net_buffer_length字節。對於客戶端,不會降低與連接相關緩衝區大小,直至連接關閉為止,此時,客戶端內存將被收回。

關於使用線程的編程方法,請參見25.2.15節,「如何生成線程式客戶端」。關於在相同程式建立包含「伺服器」和「客戶端」的獨立應用程式的更多訊息(不與外部MySQL伺服器通信),請參見25.1節,「libmysqld,嵌入式MySQL伺服器庫」

25.2.1. C API數據類型

  • MYSQL

    該結構代資料表1個資料庫連接的句柄。幾乎所有的MySQL函數均使用它。不應嘗試拷貝MYSQL結構。不保證這類拷貝結果會有用。

  • MYSQL_RES

    該結構代資料表返回行的查詢結果(SELECT, SHOW, DESCRIBE, EXPLAIN)。在本節的剩餘部分,將查詢返回的訊息稱為「結果集」。

  • MYSQL_ROW

    這是1行數據的「類型安全」資料表示。它目前是按照計數字節字串的數組實施的。(如果字段值可能包含二進制數據,不能將其當作由Null終結的字串對待,這是因為這類值可能會包含Null字節)。行是通過使用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()的類型。該類型提供的範圍為01.84e19

    在某些系統上,不能打印類型my_ulonglong的值。要想打印這類值,請將其轉換為無符號長整數類型並使用%lu打印格式,例如:

    printf ("Number of rows: %lu\n", (unsigned long) mysql_num_rows(result));
    

下面列出了MYSQL_FIELD結構包含的成員:

·         char * name

字段名稱,由Null終結的字串。如果用AS子句為該字段指定了別名,名稱的值也是別名。

·         char * org_name

段名稱,由Null終結的字串。忽略別名。

·         char * table

包含該字段的資料表的名稱,如果該字段不是計算出的字段的話。對於計算出的字段,資料表值為空的字串。如果用AS子句為該資料表指定了別名,資料表的值也是別名。

·         char * org_table

資料表的名稱,由Null終結的字串。忽略別名。

·         char * db

字段源自的數據的名稱,由Null終結的字串。如果該字段是計算出的字段,db為空的字串。

·         char * catalog

catalog名稱。該值總是"def"

·         char * def

該字段的預設值,由Null終結的字串。僅當使用mysql_list_fields()時才設置它。

·         unsigned long length

字段的寬度,如資料表定義中所指定的那樣。

·         unsigned long max_length

用於結果集的字段的最大寬度(對於實際位於結果集中的行,最長字段值的長度)。如果使用mysql_store_result()mysql_list_fields(),它將包含字段的最大長度。如果使用mysql_use_result(),該變數的值為0

·         unsigned int name_length

名稱的長度。

·         unsigned int org_name_length

org_name的長度。

·         unsigned int table_length

資料表的長度。

·         unsigned int org_table_length

org_table的長度。

·         unsigned int db_length

db的長度。

·         unsigned int catalog_length

catalog的長度。

·         unsigned int def_length

def的長度。

·         unsigned int flags

用於字段的不同「位標誌」。標誌的值可以有0個或多個下述位集合:

標誌值

標誌描述

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(不再重視)

SET_FLAG

字段是 SET(不再重視)

BLOB_FLAG

字段是BLOBTEXT(不再重視)

TIMESTAMP_FLAG

字段是TIMESTAMP(不再重視)

不再重視BLOB_FLAGENUM_FLAGSET_FLAGTIMESTAMP_FLAG標誌,原因在於,它們指出了字段的類型,而不是類型的屬性。更可取的方式是使用MYSQL_TYPE_BLOBMYSQL_TYPE_ENUMMYSQL_TYPE_SETMYSQL_TYPE_TIMESTAMP測試field->type

在下面的示範中,介紹了標誌值的典型用法:

if (field->flags & NOT_NULL_FLAG)
    printf("Field can't be null\n");

可以使用下述方面的宏來定義標誌值的布爾狀態:

標誌狀態

描述

IS_NOT_NULL(flags)

如果該字段定義為NOT NULL,為

IS_PRI_KEY(flags)

如果該字段是主鍵,為

IS_BLOB(flags)

如果該字段是BLOBTEXT,為(不再重視,用測試field->type取而代之)。

·         unsigned int decimals

用於數值字段的十進制數數目。

·         unsigned int charset_nr

用於字段的字元編碼編號。

·         enum enum_field_types type

字段的類型。類型值可以是下標所列的MYSQL_TYPE_符號之一:

類型值

類型描述

MYSQL_TYPE_TINY

TINYINT字段

MYSQL_TYPE_SHORT

SMALLINT字段

MYSQL_TYPE_LONG

INTEGER字段

MYSQL_TYPE_INT24

MEDIUMINT字段

MYSQL_TYPE_LONGLONG

BIGINT字段

MYSQL_TYPE_DECIMAL

DECIMALNUMERIC字段

MYSQL_TYPE_NEWDECIMAL

精度數學DECIMALNUMERIC

MYSQL_TYPE_FLOAT

FLOAT字段

MYSQL_TYPE_DOUBLE

DOUBLEREAL字段

MYSQL_TYPE_BIT

BIT字段

MYSQL_TYPE_TIMESTAMP

TIMESTAMP字段

MYSQL_TYPE_DATE

DATE字段

MYSQL_TYPE_TIME

TIME字段

MYSQL_TYPE_DATETIME

DATETIME字段

MYSQL_TYPE_YEAR

YEAR字段

MYSQL_TYPE_STRING

CHAR字段

MYSQL_TYPE_VAR_STRING

VARCHAR字段

MYSQL_TYPE_BLOB

BLOBTEXT字段(使用max_length來確定最大長度)

MYSQL_TYPE_SET

SET字段

MYSQL_TYPE_ENUM

ENUM字段

MYSQL_TYPE_GEOMETRY

Spatial字段

MYSQL_TYPE_NULL

NULL-type字段

MYSQL_TYPE_CHAR

不再重視,用MYSQL_TYPE_TINY取代

可以使用IS_NUM()宏來測試字段是否具有數值類型。將類型值傳遞給IS_NUM()如果字段為數值類型,會將其評估為「真」:

if (IS_NUM(field->type))
    printf("Field is numeric\n");

25.2.2. C API函數概述

這裡歸納了C API可使用的函數,並在下一節詳細介紹了它們。請參見25.2.3節,「C API函數描述」

函數

描述

mysql_affected_rows()

返回上次UPDATEDELETEINSERT查詢更改/刪除/插入的行數。

mysql_autocommit()

切換 autocommit模式,ON/OFF

mysql_change_user()

更改打開連接上的用戶和資料庫。

mysql_charset_name()

返回用於連接的預設字元編碼的名稱。

mysql_close()

關閉伺服器連接。

mysql_commit()

提交事務。

mysql_connect()

連接到MySQL伺服器。該函數已不再被重視,使用mysql_real_connect()取代。

mysql_create_db()

建立資料庫。該函數已不再被重視,使用SQL語句CREATE DATABASE取而代之。

mysql_data_seek()

在查詢結果集中搜尋屬性行編號。

mysql_debug()

用給定的字串執行DBUG_PUSH

mysql_drop_db()

撤銷資料庫。該函數已不再被重視,使用SQL語句DROP DATABASE取而代之。

mysql_dump_debug_info()

讓伺服器將調試訊息寫入日誌。

mysql_eof()

確定是否讀取了結果集的最後一行。該函數已不再被重視,可以使用mysql_errno()mysql_error()取而代之。

mysql_errno()

返回上次使用的MySQL函數的錯誤編號。

mysql_error()

返回上次使用的MySQL函數的錯誤消息。

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_field_tell()

返回上次mysql_fetch_field()所使用字段光標的位置。

mysql_free_result()

釋放結果集使用的內存。

mysql_get_client_info()

以字串形式返回客戶端版本訊息。

mysql_get_client_version()

以整數形式返回客戶端版本訊息。

mysql_get_host_info()

返回描述連接的字串。

mysql_get_server_version()

以整數形式返回伺服器的版本號。

mysql_get_proto_info()

返回連接所使用的協議版本。

mysql_get_server_info()

返回伺服器的版本號。

mysql_info()

返回關於最近所執行查詢的訊息。

mysql_init()

獲取或初始化MYSQL結構。

mysql_insert_id()

返回上一個查詢為AUTO_INCREMENT列生成的ID

mysql_kill()

殺死給定的線程。

mysql_library_end()

最終確定MySQL C API庫。

mysql_library_init()

初始化MySQL C API庫。

mysql_list_dbs()

返回與簡單正則資料表達式匹配的資料庫名稱。

mysql_list_fields()

返回與簡單正則資料表達式匹配的字段名稱。

mysql_list_processes()

返回當前伺服器線程的列資料表。

mysql_list_tables()

返回與簡單正則資料表達式匹配的資料表名。

mysql_more_results()

檢查是否還存在其他結果。

mysql_next_result()

在多語句執行過程中返回/初始化下一個結果。

mysql_num_fields()

返回結果集中的列數。

mysql_num_rows()

返回結果集中的行數。

mysql_options()

mysql_connect()設置連接選項。

mysql_ping()

檢查與伺服器的連接是否工作,如有必要重新連接。

mysql_query()

執行指定為「以Null終結的字串」的SQL查詢。

mysql_real_connect()

連接到MySQL伺服器。

mysql_real_escape_string()

考慮到連接的當前字元編碼,為了在SQL語句中使用,對字串中的特殊字元進行轉義處理。

mysql_real_query()

執行指定為計數字串的SQL查詢。

mysql_refresh()

刷新或復位資料表和高速緩衝。

mysql_reload()

通知伺服器再次加載授權資料表。

mysql_rollback()

回滾事務。

mysql_row_seek()

使用從mysql_row_tell()返回的值,搜尋結果集中的行偏移。

mysql_row_tell()

返回行光標位置。

mysql_select_db()

選擇資料庫。

mysql_server_end()

最終確定嵌入式伺服器庫。

mysql_server_init()

初始化嵌入式伺服器庫。

mysql_set_server_option()

為連接設置選項(如多語句)。

mysql_sqlstate()

返回關於上一個錯誤的SQLSTATE錯誤代碼。

mysql_shutdown()

關閉資料庫伺服器。

mysql_stat()

以字串形式返回伺服器狀態。

mysql_store_result()

檢索完整的結果集至客戶端。

mysql_thread_id()

返回當前線程ID

mysql_thread_safe()

如果客戶端已編譯為線程安全的,返回1

mysql_use_result()

初始化逐行的結果集檢索。

mysql_warning_count()

返回上一個SQL語句的告警數。

MySQL交互時,應用程式應使用該一般性原則:

1.    通過使用mysql_library_init(),初始化MySQL庫。庫可以是mysqlclient C客戶端庫,或mysqld嵌入式伺服器庫,具體情況取決於應用程式是否與「-libmysqlclient」或「-libmysqld」標誌連結。

2.    通過使用mysql_init()初始化連接處理程式,並通過使用mysql_real_connect()連接到伺服器。

3.    發出SQL語句並處理其結果。(在下面的討論中,詳細介紹了使用它的方法)。

4.    通過使用mysql_close(),關閉MySQL伺服器的連接。

5.    通過使用mysql_library_end(),結束MySQL庫的使用。

使用mysql_library_init()mysql_library_end()的目的在於,為MySQL庫提供恰當的初始化和結束處理。對於與客戶端庫連結的應用程式,它們提供了改進的內存管理功能。如果不使用mysql_library_end(),內存塊仍將保持分配狀態(這不會增加應用程式使用的內存量,但某些內存洩漏檢測器將抗議它)。對於與嵌入式伺服器連結的應用程式,這些使用會啟動並停止伺服器。

mysql_library_init()mysql_library_end()實際上是#define符號,這類符號使得它們等效於mysql_server_init()mysql_server_end(),但其名稱更清楚地指明,無論應用程式使用的是mysqlclientmysqld庫,啟動或結束MySQL庫時,應使用它們。對於早期的MySQL版本,可使用mysql_server_init()mysql_server_end()取而代之。

如果願意,可省略對mysql_library_init()的使用,這是因為,必要時,mysql_init()會自動使用它。

要想連接到伺服器,可使用mysql_init()來初始化連接處理程式,然後用該處理程式(以及其他訊息,如主機名、帳號和密碼)使用mysql_real_connect()。建立連接後,在低於5.0.3版的API中,mysql_real_connect()會將再連接標誌(MYSQL結構的一部分)設置為1,或在較新的版本中,將其設置為0。對於該標誌,值「1」指明,如果因連接丟失而無法執行語句,放棄之前,會嘗試再次連接到伺服器。從MySQL 5.0.13開始,可以在mysql_options()上使用MYSQL_OPT_RECONNECT選項,以控制再連接行為。完成連接後,使用mysql_close()中止它。

當連接處於活動狀態時,客戶端或許會使用mysql_query()mysql_real_query()向伺服器發出SQL查詢。兩者的差別在於,mysql_query()預期的查詢為指定的、由Null終結的字串,而mysql_real_query()預期的是計數字串。如果字串包含二進制數據(其中可能包含Null字節),就必須使用mysql_real_query()

對於每個非SELECT查詢(例如INSERTUPDATEDELETE),通過使用mysql_affected_rows(),可發現有多少行已被改變(影響)。

對於SELECT查詢,能夠檢索作為結果集的行。注意,某些語句因其返回行,類似與SELECT包括SHOWDESCRIBEEXPLAIN。應按照對待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()釋放結果集使用的內存。

這兩種檢索機制是互補的。客戶端程式應選擇最能滿足其要求的方法。實際上,客戶端最常使用的是mysql_store_result()

mysql_store_result()1個優點在於,由於將行全部提取到了客戶端上,您不僅能連續訪問行,還能使用mysql_data_seek()mysql_row_seek()在結果集中向前或向後移動,以更改結果集內當前行的位置。通過使用mysql_num_rows(),還能發現有多少行。另一方面,對於大的結果集,mysql_store_result()所需的內存可能會很大,您很可能遇到內存溢出狀況。

mysql_use_result()1個優點在於,客戶端所需的用於結果集的內存較少,原因在於,一次它僅維護一行(由於分配開銷較低,mysql_use_result()能更快)。它的缺點在於,您必須快速處理每一行以避免妨礙伺服器,您不能隨機訪問結果集中的行(只能連續訪問行),您不知道結果集中有多少行,直至全部檢索了它們為止。不僅如此,即使在檢索過程中您判定已找到所尋找的訊息,也必須檢索所有的行。

通過API,客戶端能夠恰當地對查詢作出響應(僅在必要時檢索行),而無需知道查詢是否是SELECT查詢。可以在每次mysql_query()mysql_real_query()後,通過使用mysql_store_result()完成該操作。如果結果集使用成功,查詢為SELECT,而且能夠讀取行。如果結果集使用失敗,可使用mysql_field_count()來判斷結果是否的確是所預期的。如果mysql_field_count()返回0查詢不返回數據(表明它是INSERTUPDATEDELETE等),而且不返回行。如果mysql_field_count()是非0值,查詢應返回行,但沒有返回行。這表明查詢是失敗了的SELECT。關於如何實現該操作的示範,請參見關於mysql_field_count()的介紹。

無論是mysql_store_result()還是mysql_use_result(),均允許您獲取關於構成結果集的字段的訊息(字段數目,它們的名稱和類型等)。通過重複使用mysql_fetch_field(),可以按順序訪問行內的字段訊息,或者,通過使用mysql_fetch_field_direct(),能夠在行內按字段編號訪問字段訊息。通過使用mysql_field_seek(),可以改變當前字段的光標位置。對字段光標的設置將影響後續的mysql_fetch_field()使用。此外,您也能通過使用mysql_fetch_fields(),一次性地獲得關於字段的所有訊息。

為了檢測和通報錯誤,MySQL提供了使用mysql_errno()mysql_error()函數訪問錯誤訊息的機制。它們能返回關於最近使用的函數的錯誤代碼或錯誤消息,最近使用的函數可能成功也可能失敗,這樣,您就能判斷錯誤是在何時出現的,以及錯誤是什麼。

25.2.3. C API函數描述

25.2.3.1. mysql_affected_rows()
25.2.3.2. mysql_autocommit()
25.2.3.3. mysql_change_user()
25.2.3.4. mysql_character_set_name()
25.2.3.5. mysql_close()
25.2.3.6. mysql_commit()
25.2.3.7. mysql_connect()
25.2.3.8. mysql_create_db()
25.2.3.9. mysql_data_seek()
25.2.3.10. mysql_debug()
25.2.3.11. mysql_drop_db()
25.2.3.12. mysql_dump_debug_info()
25.2.3.13. mysql_eof()
25.2.3.14. mysql_errno()
25.2.3.15. mysql_error()
25.2.3.16. mysql_escape_string()
25.2.3.17. mysql_fetch_field()
25.2.3.18. mysql_fetch_field_direct()
25.2.3.19. mysql_fetch_fields()
25.2.3.20. mysql_fetch_lengths()
25.2.3.21. mysql_fetch_row()
25.2.3.22. mysql_field_count()
25.2.3.23. mysql_field_seek()
25.2.3.24. mysql_field_tell()
25.2.3.25. mysql_free_result()
25.2.3.26. mysql_get_character_set_info()
25.2.3.27. mysql_get_client_info()
25.2.3.28. mysql_get_client_version()
25.2.3.29. mysql_get_host_info()
25.2.3.30. mysql_get_proto_info()
25.2.3.31. mysql_get_server_info()
25.2.3.32. mysql_get_server_version()
25.2.3.33. mysql_hex_string()
25.2.3.34. mysql_info()
25.2.3.35. mysql_init()
25.2.3.36. mysql_insert_id()
25.2.3.37. mysql_kill()
25.2.3.38. mysql_library_end()
25.2.3.39. mysql_library_init()
25.2.3.40. mysql_list_dbs()
25.2.3.41. mysql_list_fields()
25.2.3.42. mysql_list_processes()
25.2.3.43. mysql_list_tables()
25.2.3.44. mysql_more_results()
25.2.3.45. mysql_next_result()
25.2.3.46. mysql_num_fields()
25.2.3.47. mysql_num_rows()
25.2.3.48. mysql_options()
25.2.3.49. mysql_ping()
25.2.3.50. mysql_query()
25.2.3.51. mysql_real_connect()
25.2.3.52. mysql_real_escape_string()
25.2.3.53. mysql_real_query()
25.2.3.54. mysql_refresh()
25.2.3.55. mysql_reload()
25.2.3.56. mysql_rollback()
25.2.3.57. mysql_row_seek()
25.2.3.58. mysql_row_tell()
25.2.3.59. mysql_select_db()
25.2.3.60. mysql_set_character_set()
25.2.3.61. mysql_set_server_option()
25.2.3.62. mysql_shutdown()
25.2.3.63. mysql_sqlstate()
25.2.3.64. mysql_ssl_set()
25.2.3.65. mysql_stat()
25.2.3.66. mysql_store_result()
25.2.3.67. mysql_thread_id()
25.2.3.68. mysql_use_result()
25.2.3.69. mysql_warning_count()

在本節所作的介紹中,按照C編程語言,為NULL的參數或返回值資料表示NULL,而不是MySQL Null值。

返回值的函數通常會返回指針或整數。除非作了其他規定,返回指針的函數將返回非Null值,以指明成功,或返回NULL值以指明出錯。返回整數的函數將返回0以指明成功,或返回非0值以指明出錯。注意,非0值僅表明這點。除非在函數描述中作了其他說明,不要對非0值進行測試:

if (result)                   /* correct */
    ... error ...
 
if (result < 0)               /* incorrect */
    ... error ...
 
if (result == -1)             /* incorrect */
    ... error ...

當函數返回錯誤時,在函數描述的「錯誤」部分將列出可能的錯誤類型。通過使用mysql_errno()可發現出現的錯誤是什麼。通過使用mysql_error(),可獲得錯誤的字串資料表示。

25.2.3.1. mysql_affected_rows()

my_ulonglong mysql_affected_rows(MYSQL *mysql)

描述

返回上次UPDATE更改的行數,上次DELETE刪除的行數,或上次INSERT語句插入的行數。對於UPDATEDELETEINSERT語句,可在mysql_query()後立刻使用。對於SELECT語句,mysql_affected_rows()的工作方式與mysql_num_rows()類似。

返回值

大於0的整數表明受影響或檢索的行數。「0」資料表示UPDATE語句未更新記錄,在查詢中沒有與WHERE匹配的行,或未執行查詢。「-1」資料表示查詢返回錯誤,或者,對於SELECT查詢,在使用mysql_store_result()之前使用了mysql_affected_rows()。由於mysql_affected_rows()返回無符號值,通過比較返回值和「(my_ulonglong)-1」或等效的「(my_ulonglong)~0」,檢查是否為「-1」。

錯誤

無。

示範:

mysql_query(&mysql,"UPDATE products SET cost=cost*1.25 WHERE group=10");
printf("%ld products updated",(long) mysql_affected_rows(&mysql));

如果在連接至mysqld時指定了標誌CLIENT_FOUND_ROWS,對於UPDATE語句,mysql_affected_rows()將返回WHERE語句匹配的行數。

注意,使用REPLACE命令時,如果新行替代了舊行,mysql_affected_rows()返回2。這是因為,在該情況下,刪除了重複行後插入了1行。

如果使用「INSERT ... ON DUPLICATE KEY UPDATE」來插入行,如果行是作為新行插入的,mysql_affected_rows()返回1,如果是更新了已有的行,返回2

25.2.3.2. mysql_autocommit()

my_bool mysql_autocommit(MYSQL *mysql, my_bool mode)

描述

如果模式為「1」,啟用autocommit模式;如果模式為「0」,禁止autocommit模式。

返回值

如果成功,返回0,如果出現錯誤,返回非0值。

錯誤

無。

25.2.3.3. mysql_change_user()

my_bool mysql_change_user(MYSQL *mysql, const char *user, const char *password, const char *db)

描述

更改用戶,並使由db指定的資料庫成為由mysql指定的連接上的預設資料庫(當前資料庫)。在後續查詢中,對於不包含顯式資料庫區分符的資料表引用,該資料庫是預設資料庫。

如果不能確定已連接的用戶或用戶不具有使用資料庫的權限,mysql_change_user()將失敗。在這種情況下,不會改變用戶和資料庫。

如果不打算擁有預設資料庫,可將db參數設置為NULL

該命令總是會執行活動事務的ROLLBACK操作,關閉所有的臨時資料表,解鎖所有的鎖定資料表,並復位狀態,就像進行了新連接那樣。即使未更改用戶,也會出現該情況。

返回值

0資料表示成功,非0值資料表示出現錯誤。

錯誤

與從mysql_real_connect()獲得的相同。

·         CR_COMMANDS_OUT_OF_SYNC

以不恰當的順序執行了命令。

·         CR_SERVER_GONE_ERROR

MySQL伺服器不可用。

·         CR_SERVER_LOST

在查詢過程中丟失了與伺服器的連接。

·         CR_UNKNOWN_ERROR

出現未知錯誤。

·         ER_UNKNOWN_COM_ERROR

MySQL伺服器未實施該命令(或許是較低版本的伺服器)。

·         ER_ACCESS_DENIED_ERROR

用戶或密碼錯誤。

·         ER_BAD_DB_ERROR

資料庫不存在。

·         ER_DBACCESS_DENIED_ERROR

用戶沒有訪問資料庫的權限。

·         ER_WRONG_DB_NAME

資料庫名稱過長。

示範:

if (mysql_change_user(&mysql, "user", "password", "new_database"))
{
   fprintf(stderr, "Failed to change user.  Error: %s\n",
           mysql_error(&mysql));
}

25.2.3.4. mysql_character_set_name()

const char *mysql_character_set_name(MYSQL *mysql)

描述

為當前連接返回預設的字元編碼。

返回值

預設字元編碼。

錯誤

無。

25.2.3.5. mysql_close()

void mysql_close(MYSQL *mysql)

描述

關閉前面打開的連接。如果句柄是由mysql_init()mysql_connect()自動分配的,mysql_close()還將解除分配由mysql指向的連接句柄。

返回值

無。

錯誤

無。

25.2.3.6. mysql_commit()

my_bool mysql_commit(MYSQL *mysql)

描述

提交當前事務。

該函數的動作受completion_type系統變數的值控制。尤其是,如果completion_type的值為2,終結事務並關閉客戶端連接後,伺服器將執行釋放操作。客戶端程式應使用mysql_close(),從客戶端一側關閉連接。

返回值

如果成功,返回0,如果出現錯誤,返回非0值。

錯誤

無。

25.2.3.7. mysql_connect()

MYSQL *mysql_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd)

描述

該函數已過時。最好使用mysql_real_connect()取而代之。

mysql_connect()試圖建立與運行在主機上的MySQL資料庫引擎的連接。在能夠執行任何其他API函數之前,mysql_connect()必須成功完成,但mysql_get_client_info()例外。

這些參數的意義與mysql_real_connect()的對應參數的意義相同,差別在於連接參數可以為NULL。在這種情況下,C API將自動為連接結構分配內存,並當使用mysql_close()時釋放分配的內存。該方法的缺點是,如果連接失敗,您無法檢索錯誤消息。要想從mysql_errno()mysql_error()獲得錯誤消息,必須提供有效的MYSQL指針。

返回值

mysql_real_connect()的相同。

錯誤

mysql_real_connect()的相同。

25.2.3.8. mysql_create_db()

int mysql_create_db(MYSQL *mysql, const char *db)

描述

建立由db參數命名的資料庫。

該函數已過時。最好使用mysql_query()來發出SQL CREATE DATABASE語句。

返回值

如果資料庫已成功建立,返回0,如果出現錯誤,返回非0值。

錯誤

·         CR_COMMANDS_OUT_OF_SYNC

以不恰當的順序執行了命令。

·         CR_SERVER_GONE_ERROR

MySQL伺服器不可用。

·         CR_SERVER_LOST

在查詢過程中,與伺服器的連接丟失。

·         CR_UNKNOWN_ERROR

出現未知錯誤。

示範:

if(mysql_create_db(&mysql, "my_database"))
{
   fprintf(stderr, "Failed to create new database.  Error: %s\n",
           mysql_error(&mysql));
}

25.2.3.9. mysql_data_seek()

void mysql_data_seek(MYSQL_RES *result, my_ulonglong offset)

描述

在查詢結果集中尋找任意行。偏移值為行號,範圍從0mysql_num_rows(result)-1

該函數要求結果集結構包含查詢的所有結果,因此,so mysql_data_seek()僅應與mysql_store_result()聯合使用,而不是mysql_use_result()

返回值

無。

錯誤

無。

25.2.3.10. mysql_debug()

void mysql_debug(const char *debug)

描述

用給定的字串執行DBUG_PUSHmysql_debug()採用Fred Fish調試庫。要想使用該函數,必須編譯客戶端庫,使之支援調試功能。請參見E.1節,「調試MySQL伺服器」。請參見E.2節,「調試MySQL客戶端」

返回值

無。

錯誤

無。

示範:

這裡給出的使用將使客戶端庫在客戶端機器的/tmp/client.trace中生成1個跟蹤檔案。

mysql_debug("d:t:O,/tmp/client.trace");

25.2.3.11. mysql_drop_db()

int mysql_drop_db(MYSQL *mysql, const char *db)

描述

撤銷由db參數命名資料庫。

該函數已過時。最好使用mysql_query()來發出SQL DROP DATABASE語句

返回值

如果成功撤銷了資料庫,返回0。如果出現錯誤,返回非0值。

錯誤

·         CR_COMMANDS_OUT_OF_SYNC

以不恰當的順序執行了命令。

·         CR_SERVER_GONE_ERROR

MySQL伺服器不可用。

·         CR_SERVER_LOST

在查詢過程中,與伺服器的連接丟失。

·         CR_UNKNOWN_ERROR

出現未知錯誤。

示範:

if(mysql_drop_db(&mysql, "my_database"))
  fprintf(stderr, "Failed to drop the database: Error: %s\n",
          mysql_error(&mysql));

25.2.3.12. mysql_dump_debug_info()

int mysql_dump_debug_info(MYSQL *mysql)

描述

指示伺服器將一些調試訊息寫入日誌。要想使之工作,已連接的用戶必須具有SUPER權限。

返回值

如果命令成功,返回0。如果出現錯誤,返回非0值。

錯誤

·         CR_COMMANDS_OUT_OF_SYNC

以不恰當的順序執行了命令。

·         CR_SERVER_GONE_ERROR

MySQL伺服器不可用。

·         CR_SERVER_LOST

在查詢過程中,與伺服器的連接丟失。

·         CR_UNKNOWN_ERROR

出現未知錯誤。

25.2.3.13. mysql_eof()

my_bool mysql_eof(MYSQL_RES *result)

描述

該函數已過時。應使用mysql_errno()mysql_error()取而代之。

mysql_eof()確定是否已讀取了結果集的最後1行。

如果通過成功使用mysql_store_result()獲得了結果集,客戶端將在1次操作中收到整個結果集。在該情況下,mysql_fetch_row()返回的NULL總資料表示已到達結果集末尾,而且沒必要使用mysql_eof()mysql_store_result()一起使用時,mysql_eof()總返回

另一方面,如果您使用mysql_use_result()來初始化結果集檢索,當重複使用mysql_fetch_row()時,將逐個地從伺服器獲取結果集的行。由於在該過程中,可能出現連接上的錯誤,從mysql_fetch_row()返回的NULL值不一定資料表示已正常地抵達結果集末尾。在該情況下,可以使用mysql_eof()來判定出現了什麼情況。如果抵達結果集末尾,mysql_eof()返回非0值,如果出現錯誤,返回0

從歷史的角度上看,mysql_eof()在日期上早於標準的MySQL錯誤函數mysql_errno()mysql_error()。由於這類錯誤函數提供了相同的訊息,它們優先於已過時的mysql_eof()。事實上,它們提供了更多訊息,這是因為,mysql_eof()僅返回布爾值,錯誤函數能夠在出現錯誤時指明錯誤的原因。

返回值

如果未出現錯誤,返回0。如果抵達結果集的末尾,返回非0值。

錯誤

無。

示範:

在下面的示範中,介紹了使用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\n", 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\n", mysql_error(&mysql));
}

25.2.3.14. mysql_errno()

unsigned int mysql_errno(MYSQL *mysql)

描述

對於由mysql指定的連接,mysql_errno()返回最近使用的API函數的錯誤代碼,該函數使用可能成功也可能失敗。「0」返回值資料表示未出現錯誤。在MySQL errmsg.h頭檔案中,列出了客戶端錯誤消息編號。在附錄B:錯誤代碼和消息中,也列出了這些錯誤。

注意,如果成功,某些函數,如mysql_fetch_row()等,不會設置mysql_errno()

經驗規則是,如果成功,所有向伺服器請求訊息的函數均會復位mysql_errno()

返回值

如果失敗,返回上次mysql_xxx()使用的錯誤代碼。「0」資料表示未出現錯誤。

錯誤

無。

25.2.3.15. mysql_error()

const char *mysql_error(MYSQL *mysql)

描述

對於由mysql指定的連接,對於失敗的最近使用的API函數,mysql_error()返回包含錯誤消息的、由Null終結的字串。如果該函數未失敗,mysql_error()的返回值可能是以前的錯誤,或指明無錯誤的空字串。

經驗規則是,如果成功,所有向伺服器請求訊息的函數均會復位mysql_error()

對於復位mysql_errno()的函數,下述兩個測試是等效的:

if(mysql_errno(&mysql))
{
    // an error occurred
}
 
if(mysql_error(&mysql)[0] != '\0')
{
    // an error occurred
}

通過重新編譯MySQL客戶端庫,可以更改客戶端錯誤消息的語言。目前,能夠選擇數種語言顯示錯誤消息,請參見5.10.2節,「設置錯誤消息語言」

返回值

返回描述錯誤的、由Null終結的字串。如果未出現錯誤,返回空字串。

錯誤

無。

25.2.3.16. mysql_escape_string()

應使用mysql_real_escape_string()取而代之!

該函數與mysql_real_escape_string()等同,mysql_real_escape_string()會將連接處理程式作為其第1個參量,並按照當前字元編碼對字串進行轉義處理。mysql_escape_string()不採用連接參量,而且不考慮當前字元編碼設置。

25.2.3.17. mysql_fetch_field()

MYSQL_FIELD *mysql_fetch_field(MYSQL_RES *result)

描述

返回採用MYSQL_FIELD結構的結果集的列。重複使用該函數,以檢索關於結果集中所有列的訊息。未剩餘字段時,mysql_fetch_field()返回NULL

每次執行新的SELECT查詢時,將復位mysql_fetch_field(),以返回關於第1個字段的訊息。使用mysql_field_seek()也會影響mysql_fetch_field()返回的字段。

如果使用了mysql_query()以在資料表上執行SELECT但未使用mysql_store_result(),如果使用了mysql_fetch_field()以請求BLOB字段的長度,MySQL將返回預設的Blob長度(8KB)。之所以選擇8KB是因為MySQL不知道BLOB的最大長度。應在日後使其成為可配置的。一旦檢索了結果集,field->max_length將包含特定查詢中該列的最大值的長度。

返回值

當前列的MYSQL_FIELD結構。如果未剩餘任何列,返回NULL

錯誤

無。

示範:

MYSQL_FIELD *field;
 
while((field = mysql_fetch_field(result)))
{
    printf("field name %s\n", field->name);
}

25.2.3.18. mysql_fetch_field_direct()

MYSQL_FIELD *mysql_fetch_field_direct(MYSQL_RES *result, unsigned int fieldnr)

描述

給定結果集內某1列的字段編號fieldnr,以MYSQL_FIELD結構形式返回列的字段定義。可以使用該函數檢索任意列的定義。Fieldnr的值應在從0mysql_num_fields(result)-1的範圍內。

返回值

對於指定列,返回MYSQL_FIELD結構。

錯誤

無。

示範:

unsigned int num_fields;
unsigned int i;
MYSQL_FIELD *field;
 
num_fields = mysql_num_fields(result);
for(i = 0; i < num_fields; i++)
{
    field = mysql_fetch_field_direct(result, i);
    printf("Field %u is %s\n", i, field->name);
}

25.2.3.19. mysql_fetch_fields()

MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *result)

描述

對於結果集,返回所有MYSQL_FIELD結構的數組。每個結構提供了結果集中1列的字段定義。

返回值

關於結果集所有列的MYSQL_FIELD結構的數組。

錯誤

無。

示範:

unsigned int num_fields;
unsigned int i;
MYSQL_FIELD *fields;
 
num_fields = mysql_num_fields(result);
fields = mysql_fetch_fields(result);
for(i = 0; i < num_fields; i++)
{
   printf("Field %u is %s\n", i, fields[i].name);
}

25.2.3.20. mysql_fetch_lengths()

unsigned long *mysql_fetch_lengths(MYSQL_RES *result)

描述

返回結果集內當前行的列的長度。如果打算複製字段值,該長度訊息有助於最佳化,這是因為,您能避免使用strlen()。此外,如果結果集包含二進制數據,必須使用該函數來確定數據的大小,原因在於,對於包含Null字元的任何字段,strlen()將返回錯誤的結果。

對於空列以及包含NULL值的列,其長度為0。要想瞭解區分這兩類情況的方法,請參見關於mysql_fetch_row()的介紹。

返回值

無符號長整數的數組資料表示各列的大小(不包括任何終結NULL字元)。如果出現錯誤,返回NULL

錯誤

mysql_fetch_lengths()僅對結果集的當前行有效。如果在使用mysql_fetch_row()之前或檢索了結果集中的所有行後使用了它,將返回NULL

示範:

MYSQL_ROW row;
unsigned long *lengths;
unsigned int num_fields;
unsigned int i;
 
row = mysql_fetch_row(result);
if (row)
{
    num_fields = mysql_num_fields(result);
    lengths = mysql_fetch_lengths(result);
    for(i = 0; i < num_fields; i++)
    {
         printf("Column %u is %lu bytes in length.\n", i, lengths[i]);
    }
}

25.2.3.21. mysql_fetch_row()

MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)

描述

檢索結果集的下一行。在mysql_store_result()之後使用時,如果沒有要檢索的行,mysql_fetch_row()返回NULL。在mysql_use_result()之後使用時,如果沒有要檢索的行或出現了錯誤,mysql_fetch_row()返回NULL

行內值的數目由mysql_num_fields(result)給出。如果行中保存了使用mysql_fetch_row()返回的值,將按照row[0]row[mysql_num_fields(result)-1],訪問這些值的指針。行中的NULL值由NULL指針指明。

可以通過使用mysql_fetch_lengths()來獲得行中字段值的長度。對於空字段以及包含NULL的字段,長度為0。通過檢查字段值的指針,能夠區分它們。如果指針為NULL,字段為NULL,否則字段為空。

返回值

下一行的MYSQL_ROW結構。如果沒有更多要檢索的行或出現了錯誤,返回NULL

錯誤

注意,在對mysql_fetch_row()的兩次使用之間,不會復位錯誤。

·         CR_SERVER_LOST

在查詢過程中,與伺服器的連接丟失。

·         CR_UNKNOWN_ERROR

出現未知錯誤。

示範:

MYSQL_ROW row;
unsigned int num_fields;
unsigned int i;
 
num_fields = mysql_num_fields(result);
while ((row = mysql_fetch_row(result)))
{
   unsigned long *lengths;
   lengths = mysql_fetch_lengths(result);
   for(i = 0; i < num_fields; i++)
   {
       printf("[%.*s] ", (int) lengths[i], row[i] ? row[i] : "NULL");
   }
   printf("\n");
}

25.2.3.22. mysql_field_count()

unsigned int mysql_field_count(MYSQL *mysql)

描述

返回作用在連接上的最近查詢的列數。

該函數的正常使用是在mysql_store_result()返回NULL(因而沒有結果集指針)時。在這種情況下,可使用mysql_field_count()來判定mysql_store_result()是否應生成非空結果。這樣,客戶端就能採取恰當的動作,而無需知道查詢是否是SELECT(或類似SELECT的)語句。在這裡給出的示範中,演示了完成它的方法。

請參見25.2.13.1節,「為什麼在mysql_query()返回成功後,mysql_store_result()有時會返回NULL.

返回值

資料表示結果集中列數的無符號整數。

錯誤

無。

示範:

MYSQL_RES *result;
unsigned int num_fields;
unsigned int num_rows;
 
if (mysql_query(&mysql,query_string))
{
    // error
}
else // query succeeded, process any data returned by it
{
    result = mysql_store_result(&mysql);
    if (result)  // there are rows
    {
        num_fields = mysql_num_fields(result);
        // retrieve rows, then call mysql_free_result(result)
    }
    else  // mysql_store_result() returned nothing; should it have?
    {
        if(mysql_field_count(&mysql) == 0)
        {
            // query does not return data
            // (it was not a SELECT)
            num_rows = mysql_affected_rows(&mysql);
        }
        else // mysql_store_result() should have returned data
        {
            fprintf(stderr, "Error: %s\n", mysql_error(&mysql));
        }
    }
}

另一種可選的方法是,用mysql_errno(&mysql)替換mysql_field_count(&mysql)使用。在該情況下,無論語句是否是SELECT您將直接從mysql_store_result()搜尋錯誤,而不是從mysql_field_count()的值進行推斷。

25.2.3.23. mysql_field_seek()

MYSQL_FIELD_OFFSET mysql_field_seek(MYSQL_RES *result, MYSQL_FIELD_OFFSET offset)

描述

將字段光標設置到給定的偏移處。對mysql_fetch_field()的下一次使用將檢索與該偏移相關的列定義。

要想搜尋行的開始,請傳遞值為0的偏移量。

返回值

字段光標的前一個值。

錯誤

無。

25.2.3.24. mysql_field_tell()

MYSQL_FIELD_OFFSET mysql_field_tell(MYSQL_RES *result)

描述

返回上一個mysql_fetch_field()所使用的字段光標的定義。該值可用作mysql_field_seek()的參量。

返回值

字段光標的當前偏移量。

錯誤

無。

25.2.3.25. mysql_free_result()

void mysql_free_result(MYSQL_RES *result)

描述

釋放由mysql_store_result()mysql_use_result()mysql_list_dbs()等為結果集分配的內存。完成對結果集的操作後,必須使用mysql_free_result()釋放結果集使用的內存。

釋放完成後,不要嘗試訪問結果集。

返回值

無。

錯誤

無。

25.2.3.26. mysql_get_character_set_info()

void mysql_get_character_set_info(MYSQL *mysql, MY_CHARSET_INFO *cs)

描述

該函數提供了關於預設客戶端字元編碼的訊息。可以使用mysql_set_character_set()函數更改預設的字元編碼。

該函數是在MySQL 5.0.10中增加的。

示範:

if (!mysql_set_character_set(&mysql, "utf8"))
{
    MY_CHARSET_INFO cs;
    mysql_get_character_set_info(&mysql, &cs);
    printf("character set information:\n");
    printf("character set name: %s\n", cs.name);
    printf("collation name: %s\n", cs.csname);
    printf("comment: %s\n", cs.comment);
    printf("directory: %s\n", cs.dir);
    printf("multi byte character min. length: %d\n", cs.mbminlen);
    printf("multi byte character max. length: %d\n", cs.mbmaxlen);
}

25.2.3.27. mysql_get_client_info()

char *mysql_get_client_info(void)

描述

返回資料表示客戶端庫版本的字串。

返回值

資料表示MySQL客戶端庫版本的字串。

錯誤

無。

25.2.3.28. mysql_get_client_version()

unsigned long mysql_get_client_version(void)

描述

返回資料表示客戶端庫版本的整數。該值的格式是XYYZZ,其中X是主版本號,YY是發佈級別,ZZ是發佈級別內的版本號。例如,值40102資料表示客戶端庫的版本是4.1.2

返回值

資料表示MySQL客戶端庫版本的整數。

錯誤

無。

25.2.3.29. mysql_get_host_info()

char *mysql_get_host_info(MYSQL *mysql)

描述

返回描述了所使用連接類型的字串,包括伺服器主機名。

返回值

代資料表伺服器主機名和連接類型的字串。

錯誤

無。

25.2.3.30. mysql_get_proto_info()

unsigned int mysql_get_proto_info(MYSQL *mysql)

描述

返回當前連接所使用的協議版本。

返回值

代資料表當前連接所使用協議版本的無符號整數。

錯誤

無。

25.2.3.31. mysql_get_server_info()

char *mysql_get_server_info(MYSQL *mysql)

描述

返回代資料表伺服器版本號的字串。

返回值

代資料表伺服器版本號的字串。