一、数据类型
-
MYSQL
MYSQL
是MYSQL数据库连接的句柄(handle),几乎所有的MYSQL函数都需使用该
数据结构,不要尝试去复制该数据结构,因为不能保证副本是可用的
。 -
MYSQL_RES
MYSQL_RES
是SQL查询结果(result of query)。 -
MYSQL_ROW
MYSQL_ROW
代表着一行数据,它被实现可数字节的字符串(an array of counted
byte strings),但是认为它是以null为终结符的字符串
,因为它可能包含二进制
数据。一行数据通常通过mysql_fetch_row()
来获取。 -
MYSQL_FIELD
MYSQL_FIELD
包含元数据metadata
,字段的信息(例如字段名,数据类型,大小等)
通常可以通过重复使用mysql_fetch_field
逐个获取字段,但字段值不包括在这个结构
中,而是包含在MYSQL_ROW
.
MYSQL_FIELD的数据成员,当使用在不同场合,它的数据成员有不同含义:char* name
:char* org_name
:char* table
:char* org_name
:char* db
:char* catlog
:char* def
:unsigned long length
:unsigned long max_length
:unsigned int name_length
:unsigned int org_name_length
:unsigned int table_length
:unsigned int org_table_length
:unsigned int db_length
:unsigned int catlog_length
:unsinged int def_length
:unsigned int decimals
:unsigned int charsetnr
:enum enum_field_types type
:unsigned int flags
: flag以位形式体现字段属性,可以使用&配合以下FLAGS检查
字段属性。FLAGS 说明 NOT_NULL_FLAG 字段不能为null PRI_KEY_FLAG 字段是primary key的一部分 UNIQUE_KEY_FLAG 字段是unique key的一部分 MULTIPLE_KEY_FLAG 字段是nonunique key的一部分 UNSIGNED_FLAG 字段有unsigned 属性 ZEROFILL_FLAG 字段有zerofill属性 BINARY_FLAG 字段有binary属性 AUTO_INCREMENT_FLAG 字段有auto_increment属性 ENUM_FLAG 字段是enum SET_FLAG 字段是set BLOB_FLAG 字段是blob TIMESTAMP_FLAG 字段是timestamp NUM_FLAG 字段是numeric NO_DEFAULT_VALUE_FLAG 字段没有默认值 通常的用法是
if(field->type & NOT_NULL_FLAG)
-
MYSQL_FIELD_OFFSET
MYSQL_FIELD_OFFSET
代表着一个字段的偏移量,使用mysql_field_seek
-
my_ulonglong
数值类型,包括从0到1.84e19。 -
my_bool
布尔类型
二、API
函数名 | 说明 |
---|---|
my_init() | 初始化一个全局变量和线程句柄 |
mysql_affected_rows() | 返回通过上次update、delete、insert改变、删除、插入的行数 |
mysql_autocommit() | 切换(toggle)自动提交模式(on/off) |
mysql_change_user() | 在一个打开的数据库连接中切换用户 |
mysql_character_set_name() | 返回当前连接的默认字符集名 |
mysql_client_find_plugin() | 返回一个plugin的指针 |
mysql_close() | 关闭一个服务器连接 |
mysql_commit() | 提交事务(transaction) |
mysql_connect() | 连接到一个服务器 |
mysql_create_db() | 创建一个数据库 |
mysql_date_seek() | |
mysql_debug() | |
mysql_drop_db() | 删除一个数据库 |
mysql_dump_debug_info() | 中止服务器写debug信息到log |
mysql_eof() | |
mysql_errno() | 返回最近调用的mysql函数的error number |
mysql_error() | 返回醉经调用的mysql函数的error message |
mysql_escape_string | |
mysql_fetch_field() | 返回下一个表字段的类型 |
mysql_fetch_field_direct() | |
mysql_fetch_fields() | 返回一个所有字段的数组 |
mysql_fetch_lengths() | 返回当前行的所有列的长度 |
mysql_fetch_row() | 从结果集获取下一行 |
mysql_field_count() | |
mysql_field_seek() | 移动游标(cursor)到特定行 |
mysql_field_tell() | 返回字段游标的位置 |
mysql_free_result() | 释放结果集的内存 |
mysql_get_character_set_info() | 返回默认字符集信息 |
mysql_get_client_info() | 返回客户版本信息 |
mysql_get_client_version() | 返回客户版本信息 |
mysql_get_host_info() | 返回数据库连接的描述信息 |
mysql_get_option() | |
mysql_get_proto_info() | 返回连接的协议版本 |
mysql_get_server_info() | 返回服务版本信息 |
mysql_get_server_version() | 返回服务器版本信息 |
mysql_get_ssl_cipher() | 返回当前SSL cipher |
mysql_hex_string() | 编码字符串位十六进制模式 |
mysql_info() | 返回最近执行的query信息 |
mysql_init() | 得到并初始化一个MYSQL结构 |
mysql_insert_id() | 返回上次插入时自动生成的id |
mysql_kill() | 杀死一个线程 |
mysql_libary_end() | 结束mysql C API库 |
mysql_libary_init() | 初始化mysql C API 库 |
mysql_list_db() | 返回匹配正则表达式的数据库名 |
mysql_list_fields() | 返回匹配正则表达式的字段名 |
mysql_list_processes() | 返回当前服务线程 |
mysql_list_tables() | 返回匹配正则表达式的表名 |
mysql_load_plugin() | 加载一个plugin |
mysql_load_plugin_v() | 加载一个plugin |
mysql_more_results() | 检查是否有剩余的结果集 |
myssql_next_results() | 返回下一个在multiple-result 的结果集 |
mysql_num_fields() | 返回结果集中的列数 |
mysql_num_rows() | 返回结果集中的行数 |
mysql_options() | 设置mysql_real_connect()连接选项 |
mysql_ping() | 检查连接是否工作,并适当重连 |
mysql_query() | 执行一个SQL query |
mysql_real_connect() | 连接MYSQL Server |
mysql_real_query() | 执行一个SQL query |
mysql_reload() | |
MySQL_refresh() | |
mysql_reset_connection() | 重置连接去清除会话状态 |
mysql_rollback() | 回滚事务 |
mysql_row_seek() | 移动结果集中一个行偏移量 |
mysql_row_tell() | 返回行游标位置 |
mysql_select_db() | 选择一个数据库 |
mysql_server_end() | 结束mysql C API 库 |
mysql_server_init() | 初始化mysql C API 库 |
mysql_session_track_get_first() | |
mysql_session_track_get_next() | |
mysql_set_character_set() | 设置字符集 |
mysql_set_local_infile_default() | |
mysql_set_local_infile_handler() | |
mysql_set_server_option() | |
mysql_sqlstate() | |
mysql_shutdown() | 关闭sql服务器 |
mysql_ssl_set() | |
mysql_stat() | |
mysql_store_result() | |
mysql_thread_end() | 结束线程handler |
mysql_thread_id() | 返回当前线程id |
mysql_thread_init() | 结束线程handler |
mysql_thread_safe() | 返回1如果客户端是完全的线程安全 |
mysql_user_result() | |
mysql_waiting_count() | 返回上一次SQL statemennt的警告计数 |
三、常用API详解
- my_init();
#include<my_global.h>
#include<my_sys.h>
void my_init(void);
my_init()函数初始化一些使用MysQL必需的全局变量,而且它调用了mysql_thread_init()。
在使用MySQL客户端库之前调用my_init()是必要的,my_init()会被mysql_init(),
mysql_library_init(),mysql_server_init(),mysql_connect()自动调用。如果你
能确保在调用其他MySQL函数之前调用以上的函数,那么可以不必显式调用my_init().
- mysql_init();
MYSQL* mysql_init(MYSQL* mysql);
返回值:一个已初始化的MYSQL句柄,如果没有足够内存返回NULL
mysql_init()分配并初始化适用于mysql_real_connect()一个MYSQL对象,如果mysql参数
是一个空指针,那么函数内分配、初始化、并返回一个新的对象。否则,这个对象被初始化
并且返回对象的地址。如果mysql_init()在函数内分配了一个新的对象,它在关闭连接(即
调用mysql_close())时被释放。
在一个非多线程的环境中,mysql_init()会自动调用mysql_library_init(),但是要注
意的时mysql_library_init()在多线程环境中不是一个线程安全函数,所以mysql_init
也不是一个线程安全函数,
调用mysql_init(),无论是调用mysql_library之前切换线程,还是使用mutex保护
mysql_library_inti(),都必须在调用其他client libary call之前做完。
- mysql_real_connect();
MYSQL* mysql_real_connect(MYSQL* mysql,const char* host,const char* user,
const char* passwd,const char* db,unsigned int port,
const char* unix_socket,unsigned long client_flag);
mysql_real_connect()尝试去建立一条到MYSQL数据库的连接,在调用其他的API 函数之
前mysql_real_connect()必须完全成功。
返回值:成功返回与mysql一样的MYSQL句柄,否则返回NULL
参数:
mysql: mysql必须是一个合法的MYSQL* 结构,调用mysql_init()可以初始化该结构,调
用mysql_options()可以修改连接选项。
host: host必须是一个主机名或者一个IP地址。当host为NULL或者localhost时,意为连
接到本地数据库。
user: user时用户登陆数据库的ID,如果user为NULL或者“",假定为当前用户。
passwd: passwd为用户登陆数据库的密码
db: 数据库名,如果db不为NULL,连接到db的值默认的数据库
port: 如果port不为0,默认使用TCP/IP连接的端口号,port决定了数据库连接的类型
unix_socket: 如果unix_socket不为NULL,那么使用这个字符串指定的socket或者命名
管道。
client_flag: 通常为0,但可以使用以下flag的组合来确定特定的特性。
CAN_HANDLE_EXPRIED_PASSWORDS:客户端能处理失效密码。
CLIENT_COMPRESS:使用压缩的tcp/ip协议。
CLIENT_FOUND_ROWS:返回找到的/匹配的行数,而不是返回改变的行数。
CLIENT_IGNORE_SIGPIPE:
CLIENT_IGNORE_SPACE:允许在函数名后有空格。
CLIENT_INTERACTIVE:
CLIENT_LOCAL_FILES:
CLIENT_MULTI_RESULT:
CLIENT_MULTI_STATEMENT:
CLIENT_ODBC:
CLIENT_SSL:
CLIENT_REMBER_OPTIONS:
如果程序使用`CALL`statement来执行存储过程,那么CLIENT_MULITI_RESULTS必须被使
用,因为每个CALL返回一个结果(result)来表明call status,另外还有执行存储过程返
回的结果。 由于CALL可以返回多结果,程序中使用循环调用mysql_next_result()来检测
是否还有结果。
MySQL5.7 中CLIENT_MULITI_RESULTS是默认使用的。
错误:
CR_CONN_HOST_ERROR:无法连接到MYSQL服务器
CR_CONNECTION_ERROR:无法连接到本地MYSQL服务器
CR_IPSOCK_ERROR:无法创建IPsocket
CR_OUT_OF_MEMORY:内存溢出
CR_SOCKET_CREATE_ERROR:无法创建unix连接
CR_UNKNOW_HOST:无法通过主机名解析ip地址
CR_VERSION_ERROR:
CR_NAMEDPIPEOPEN_ERROR:
CR_NAMEDPIPEWAIT_ERROR:
CR_NAMEDPIPESTATE_ERROR:
CR_SERVER_LOST:
CR_ALREADY_CONNECTED:
- mysql_query();
int mysql_query(MYSQL* mysql,const char* stmt_str);
返回值:成功返回0,出错返会非0
执行一条以null为终结符的字符串指向的SQL Statement。通常,这个字符串是一条没有
分号或者\g结尾的单条SQL Statement。如果使用了multiple-statement,那么这个字符
串包含以分号或者\g分隔的多条SQL Statement。
mysql_query()不能使用包含二进制数据(binary data)的statement(二进制数据中可
能存在'\0'),如果想要使用带有二进制数据的statement,则使用mysql_real_query替代
如果想要知道statement是否有结果集,可以使用mysql_field_count()来检查。
- mysql_use_result();
MYSQL_RES* mysql_use_result(MYSQL* mysql);
返回值:成功时返回一个MYSQL_RES结构句柄,出错返回NULL
在调用mysql_query()或者mysql_real_query()之后,必须使用mysql_store_result()
或者mysql_use_result()为处理使用select、show、descrice、explanin、
check_table的statement返回的结果。在之后,还必须使用mysql_free_result()释放
result的空间。
mysql_use_result启动一个结果集检索(result set retrival)而不是像
mysql_store_result()读取整个结果集。相反,需要逐个调用mysql_fetch_row()来读取
每行数据。这个读取时直接从服务端读取而没有保存进一个临时的表或者本地缓存,它比
mysql_store_result()执行速度更快而且使用的内存更少。这个客户端仅为当前行分配内
存,并且这个communication buffer最多为max_allowed_packet字节。
当你使用mysql_use_result(),你必须执行mysql_fetch_row()知道返回NULL为止,否则
那些未被fetched的行将作为下一个query的结果集的一部分。
在mysql_use_result()完成之前,你不能在mysql_user_result()返回的resultset上使
用mysql_data_seek(),mysql_row_seek(),mysql_row_tell(),mysql_num_rows()或者
mysql_affected_rows,也不能执行其他的query。
- mysql_more_result()、mysql_next_result()
my_bool mysql_more_results(MYSQL *mysql);
检查是否有更多结果集
int mysql_next_result(MYSQL *mysql);
返回值:
0,执行成功,还有结果集
-1,执行成功,没有剩余结果集
>0,执行出错
- mysql_fetch_row();
MYSQL_ROW mysql_fetch_row(MYSQL_RES* result);
mysql_fetch_row()取回结果集中的下一行。
返回值:
当在mysql_store_result()之后使用,mysql_fetch_row返回NULL意味着没有剩余行数据
当在mysql_use_result()之后使用,musql_fetch_row返回NULL意味着没有剩余行数据或
者和有错误发生。
行中值的数量(即列数)可由mysql_num_fields(results)确定
字段值的长度(the length of the field values in the row)可有
mysql_fetch_lengths()获取,空字段(empty field)或者字段值为NULL的长度都为0.
可以通过检查字段值的指针为NULL确定,否则为空字段。
- mysql_fetch_field()、mysql_fetch_lengths()
MYSQL_FIELD* mysql_fetch_field(MYSQL_RES* result);
循环调用mysql_fetch_field直到返回NULL获取结果集一行所有的field。
unsigned long* mysql_fetch_lengths(MYSQL_RES* result);
返回结果集中当前行中每一列的长度。
- mysql_field_count(),mysql_num_fields()
unsigned int mysql_field_count(MYSQL* mysql);
返回值: 返回上一次query statement中列数
unsigned int mysql_num_fields(MYSQL_RES* result);
返回值:返回结果集中的列数
- mysql_num_rows(),mysql_afftected_rows()
my_ulonglong mysql_num_rows(MYSQL_RES* result);
返回值:返回结果集中的行数
当使用mysql_store_result()时,mysql_num_rows()立即返回。
当使用mysql_use_result()时,mysql_num_rows()不会立即返回,而是在所有行都被抽
取后返回。
my_ulonglong mysql_affected_rows(MYSQL *mysql);
返回值:立即返回执行query statement后改变、删除、或插入的行的数量
- mysql_error()、mysql_errno()
const char *mysql_error(MYSQL *mysql);
返回错误的描述信息的字符串,如果没有错误发生返回空字符串
unsigned int mysql_errno(MYSQL *mysql);
返回上个mysql_xxx函数的错误码,如果为0则没有错误发生。
- mysql_commit()、mysql_autocommit()
my_bool mysql_commit(MYSQL *mysql);
提交当前事务
返回值:成功返回0,出错返回非0
my_bool mysql_autocommit(MYSQL *mysql, my_bool mode);
当mode为1,设置自动提交模式为打开,mode为0,关闭自动提交模式。
返回值:成功返回0,出错返回非0
- mysql_rollback()
my_bool mysql_rollback(MYSQL *mysql);
回滚当前事务
返回值:成功返回0,出错返回非0
- mysql_close()
void mysql_close(MYSQL *mysql);
关闭数据库连接
三、Statement的数据结构和API
1.数据结构
-
MYSQL_STMT
这个数据结构是一个prepared statement的句柄,由函数mysql_stmt_init()
创建,当不在使用时需使用函数mysql_stmt_close()
关闭。不要尝试去复制一
个MYSQL_STMT
结构,因为无法保证它的副本能够被使用。 -
MYSQL_BIND
MYSQL_BIND
既能用于向statement传入参数,也能接收statement的结果。
对于输入参数,使用mysql_stmt_bind_param
去结合(bind)参数。并使用函数mysql_stmt_execute()
去执行。
对于输出参数,使用mysql_stmt_bind_result
去接收结果,并使用函数mysql_stmt_fetch()
获取每行。MYSQL_BIND
结构包含以下数据成员,对于有些数据成员,它的用法取决于它是
输入还是输出参数。