1、以不同字符集登录导致的格式混乱
以utf-8登录数据库,通过如下语句查看数据库中所有应用的字符集种类
上图中8个字符集,与我们有关的是6个(除去filesystem和dir之后余下六个)
一gbk登录数据库,通过如下语句查看数据库中所有字符集种类发现与以utf-8登录的存在差异
因此,通过不同的字符集进行登录,存储的数据之间就会出现格式的混乱
注意:因为字符集错了而导致的报错的不可信的。
2、由于操作系统的语言集导致中文乱码
分别查看本地虚拟机以及阿里云虚拟机中的字符集
其中zh_CN.UTF-8表示——菜单显示按照简体中文,数据存储按照utf8
UTF-8的时候数据存储是不受影响的,其他就不好说了。
当数据存储并不是按照utf-8时,输入的中文数据在存储的过程中有可能会消失,然而存储数据过程并不会发生报错。因此这种错误很难排查。
/usr/include/mysql/mysql.h
/usr/lib64/mysql/libmysqlclient.a
除了用find查找,还可以用locate命令进行查找数据(ubuntu下好使)
locate找的更快,是因为有底层的数据库映射。缺点就是实时性不好。
MYSQL *mysql_init(MYSQL *mysql)
描述
分配或初始化与mysql_real_connect()相适应的MYSQL对象。如果mysql是NULL指针,该函数将分配、初始化、并返回新对象。否则,将初始化对象,并返回对象的地址。如果mysql_init()分配了新的对象,当调用mysql_close()来关闭连接时。将释放该对象。
返回值
初始化的MYSQL*句柄。如果无足够内存以分配新的对象,返回NULL。
错误
在内存不足的情况下,返回NULL。
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数据库引擎建立连接。在你能够执行需要有效MySQL连接句柄结构的任何其他API函数之前,mysql_real_connect()必须成功完成。
参数的指定方式如下:
host 主机 ip
user 用户名(数据库)
passwd 密码
db 要登录的库名
port 端口 默认填0
unix_socket 套接字,默认填NULL
client_flag 客户端标志,一般填0
示例:
MYSQL mysql;
mysql_init(&mysql);
mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"your_prog_name");
if (!mysql_real_connect(&mysql,"host","user","passwd","database",0,NULL,0)) {
fprintf(stderr, "Failed to connect to database: Error: %s\n",
mysql_error(&mysql));
}
通过使用mysql_options(),MySQL库将读取my.cnf文件的[client]和[your_prog_name]部分,以确保程序工作,即使某人以某种非标准的方式设置MySQL也同样。
注意,一旦建立了连接,mysql_real_connect()将设置再连接标志(MYSQL结构的组成部份)的值,在低于5.0.3版的API中,将其设为“1”,在较新的版本中,将其设为“0”。对于该标志,值“1”表示,如果因连接丢失而无法执行语句,放弃前,将尝试再次连接到服务器。从MySQL 5.0.13开始,可以对mysql_options()使用MYSQL_OPT_RECONNECT选项,对再连接行为进行控制。
void mysql_close(MYSQL *mysql)
描述
关闭前面打开的连接。如果句柄是由mysql_init()或mysql_connect()自动分配的,mysql_close()还将解除分配由mysql指向的连接句柄。
返回值
无。
错误
无。
#include
#include
#include
#include
#include"mysql.h"
//define something for the connect function
//connect to localhost
#define _HOST_ "127.0.0.1"
//user of the database,not the linux
#define _USER_ "debian-sys-maint"
#define _PASSWD_ "7kEJiQ1hzUC3dpGm"
#define _DBNAME_ "mydb1"
int main(){
//1.init
MYSQL *mysql=mysql_init(NULL);
if(mysql==NULL){
printf("init err\n");
exit(1);
}
//2.real_connect
mysql=mysql_real_connect(mysql, _HOST_, _USER_,_PASSWD_,_DBNAME_,0,NULL,0);
if(mysql==NULL){
printf("connect err\n");
exit(1);
}
printf("revenger never die!!!\n");
//3.close
mysql_close(mysql);
return 0;
}
注:用户名密码通过查看/etc/mysql/debian.cnf.获取
# Automatically generated for Debian scripts. DO NOT TOUCH!
[client]
host = localhost
user = debian-sys-maint
password = 7kEJiQ1hzUC3dpGm
socket = /var/run/mysqld/mysqld.sock
[mysql_upgrade]
host = localhost
user = debian-sys-maint
password = 7kEJiQ1hzUC3dpGm
socket = /var/run/mysqld/mysqld.sock
编译
gcc hello.c -I/usr/include/mysql -L/usr/lib64/mysql -lmysqlclient -lstdc++ -ldl -lpthread -lrt
运行结果
int mysql_query(MYSQL *mysql, const char *query)
根据数据库实际情况,选择一张表,向其中插入数据
#include
#include
#include
#include
#include"mysql.h"
//define something for the connect function
//connect to localhost
#define _HOST_ "127.0.0.1"
//user of the database,not the linux
#define _USER_ "debian-sys-maint"
#define _PASSWD_ "7kEJiQ1hzUC3dpGm"
#define _DBNAME_ "mydb1"
int main(){
//1.init
MYSQL *mysql=mysql_init(NULL);
if(mysql==NULL){
printf("init err\n");
exit(1);
}
//2.real_connect
mysql=mysql_real_connect(mysql, _HOST_, _USER_,_PASSWD_,_DBNAME_,0,NULL,0);
if(mysql==NULL){
printf("connect err\n");
exit(1);
}
printf("revenger never die!!!\n");
char rSql[256]={0};
strcpy(rSql, "insert into myclass(name) value('cnm')");
if(mysql_query(mysql, rSql)!=0){
printf("mysql_query err\n");
exit(1);
}
//3.close
mysql_close(mysql);
return 0;
}
写一个makefile,方便编译
SrcFiles=$(wildcard *.c)
TargetFiles=$(patsubst %.c,%,$(SrcFiles))
IncPath=/usr/include/mysql
LibPath=/usr/lib64/mysql
PubLib=-lmysqlclient -lstdc++ -ldl -lpthread -lrt
all:$(TargetFiles)
%:%.c
gcc -o $@ $^ -I$(IncPath) -L$(LibPath) $(PubLib)
clean:
-rm -f $(TargetFiles)
其中:
makefile
wildcard——Makefile中wildcard的介绍 - haoxing990 - 博客园
makefile中的notdir,wildcard和patsubst - Biiigfish - 博客园
运行结果
MYSQL_RES *mysql_store_result(MYSQL *mysql)
描述
对于成功检索了数据的每个查询(SELECT、SHOW、DESCRIBE、EXPLAIN、CHECK TABLE等),必须调用mysql_store_result()或mysql_use_result() 。
对于其他查询,不需要调用mysql_store_result()或mysql_use_result(),但是如果在任何情况下均调用了mysql_store_result(),它也不会导致任何伤害或性能降低。通过检查mysql_store_result()是否返回0,可检测查询是否没有结果集(以后会更多)。
如果希望了解查询是否应返回结果集,可使用mysql_field_count()进行检查。
mysql_store_result()将查询的全部结果读取到客户端,分配1个MYSQL_RES结构,并将结果置于该结构中。
如果查询未返回结果集,mysql_store_result()将返回Null指针(例如,如果查询是INSERT语句)。
如果读取结果集失败,mysql_store_result()还会返回Null指针。通过检查mysql_error()是否返回非空字符串,mysql_errno()是否返回非0值,或mysql_field_count()是否返回0,可以检查是否出现了错误。
如果未返回行,将返回空的结果集。(空结果集设置不同于作为返回值的空指针)。
一旦调用了mysql_store_result()并获得了不是Null指针的结果,可调用mysql_num_rows()来找出结果集中的行数。
可以调用mysql_fetch_row()来获取结果集中的行,或调用mysql_row_seek()和mysql_row_tell()来获取或设置结果集中的当前行位置。
一旦完成了对结果集的操作,必须调用mysql_free_result()。
void mysql_free_result(MYSQL_RES *result)
描述
释放由mysql_store_result()、mysql_use_result()、mysql_list_dbs()等为结果集分配的内存。完成对结果集的操作后,必须调用mysql_free_result()释放结果集使用的内存。
释放完成后,不要尝试访问结果集。
返回值
无。
错误
无。
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_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");
}
#include
#include
#include
#include
#include"mysql.h"
//define something for the connect function
//connect to localhost
#define _HOST_ "127.0.0.1"
//user of the database,not the linux
#define _USER_ "debian-sys-maint"
#define _PASSWD_ "7kEJiQ1hzUC3dpGm"
#define _DBNAME_ "mydb1"
int main(){
//1.init
MYSQL *mysql=mysql_init(NULL);
if(mysql==NULL){
printf("init err\n");
exit(1);
}
//2.real_connect
mysql=mysql_real_connect(mysql, _HOST_, _USER_,_PASSWD_,_DBNAME_,0,NULL,0);
if(mysql==NULL){
printf("connect err\n");
exit(1);
}
printf("revenger never die!!!\n");
char rSql[256]={0};
strcpy(rSql, "select * from myclass");
if(mysql_query(mysql, rSql)!=0){
printf("mysql_query err\n");
exit(1);
}
//get the reault
MYSQL_RES *result = mysql_store_result(mysql);
MYSQL_ROW row;
if(result !=NULL){
//PRINT THE RESULT line by line
while((row=mysql_fetch_row(result))!=NULL){
for(int i=0; i<2; i++){
printf("%s\t",row[i]);
}
printf("\n");
}
}
//free the MYSQL_RES
mysql_free_result(result);
//3.close
mysql_close(mysql);
return 0;
}
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);
}
#include
#include
#include
#include
#include "mysql.h"
//define something for the connect function
//connect to localhost
#define _HOST_ "127.0.0.1"
//user of the database,not the linux
#define _USER_ "debian-sys-maint"
#define _PASSWD_ "7kEJiQ1hzUC3dpGm"
#define _DBNAME_ "mydb1"
void show_result(MYSQL_RES * result)
{
//打印表头
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("%s\t", fields[i].name);
}
printf("\n+-------+--------+-----------+------+------------+------+------+--------+\n");
MYSQL_ROW row;
num_fields = mysql_num_fields(result);//取字段个数
while ((row = mysql_fetch_row(result)))//循环取一行
{
for(i = 0; i < num_fields; i++)
{
printf("%s\t", row[i] ? row[i] : "NULL");
}
printf("\n");
}
}
int main()
{
//1.init
MYSQL *mysql = mysql_init(NULL);
if (mysql == NULL) {
printf("init err\n");
exit(1);
}
//2.real_connect
mysql = mysql_real_connect(mysql, _HOST_, _USER_, _PASSWD_, _DBNAME_, 0, NULL, 0);
if (mysql == NULL) {
printf("connect err\n");
exit(1);
}
printf("revenger never die!!!\n");
char rSql[256] = { 0 };
strcpy(rSql, "select * from myclass");
if (mysql_query(mysql, rSql) != 0) {
printf("mysql_query err\n");
exit(1);
}
//取回结果集
int i=0;
MYSQL_RES * result = mysql_store_result(mysql);
MYSQL_ROW row;
if(result != NULL){
//需要打印结果集
show_result(result);
mysql_free_result(result);//释放结果集
}
//3. close
mysql_close(mysql);
return 0;
}