笔记整理--Linux平台MYSQL的C语言
Linux平台MYSQL的C语言API全列表 - 第三只眼的专栏 - 博客频道 - CSDN.NET - Google Chrome (2013/8/18 22:28:58)
1.mysql_affected_rows() //返回上次UPDATE、DELETE或INSERT查询更改/删除/插入的行数。
2.mysql_autocommit() //切换 autocommit模式,ON/OFF。
3.mysql_change_user() //更改打开连接上的用户和数据库。
4.mysql_charset_name() //返回用于连接的默认字符集的名称。
5.mysql_close() //关闭服务器连接。
6.mysql_commit() //提交事务。
7.mysql_data_seek() //在查询结果集中查找属性行编号。
8.mysql_debug() //用给定的字符串执行DBUG_PUSH。
9.mysql_dump_debug_info() //让服务器将调试信息写入日志。
10.mysql_errno() //返回上次调用的MySQL函数的错误编号。
11.mysql_escape_string() //为了用在SQL语句中,对特殊字符进行转义处理。
12.mysql_fetch_field() //返回下一个表字段的类型。
13.mysql_fetch_field_direct() //给定字段编号,返回表字段的类型。
14.mysql_fetch_fields() //返回所有字段结构的数组。
15.mysql_fetch_lengths() //返回当前行中所有列的长度。
16.mysql_fetch_row() //从结果集中获取下一行
17.mysql_field_seek() //将列光标置于指定的列。
18.mysql_field_count() //返回上次执行语句的结果列的数目。
19.mysql_field_tell() //返回上次mysql_fetch_field()所使用字段光标的位置。
20.mysql_free_result() //释放结果集使用的内存。
21.mysql_get_client_info() //以字符串形式返回客户端版本信息。
22.mysql_get_client_version() //以整数形式返回客户端版本信息。
23.mysql_get_host_info() //返回描述连接的字符串。
24.mysql_get_server_version() //以整数形式返回服务器的版本号。
25.mysql_get_proto_info() //返回连接所使用的协议版本。
26.mysql_get_server_info() //返回服务器的版本号。
27.mysql_info() //返回关于最近所执行查询的信息。
28.mysql_init() //获取或初始化MYSQL结构。
29.mysql_insert_id() //返回上一个查询为AUTO_INCREMENT列生成的ID。
30.mysql_kill() //杀死给定的线程。
31.mysql_library_end() //最终确定MySQL C API库。
32.mysql_library_init() //初始化MySQL C API库。
33.mysql_list_dbs() //返回与简单正则表达式匹配的数据库名称。
34.mysql_list_fields() //返回与简单正则表达式匹配的字段名称。
35.mysql_list_processes() //返回当前服务器线程的列表。
36.mysql_list_tables() //返回与简单正则表达式匹配的表名。
37.mysql_more_results() //检查是否还存在其他结果。
38.mysql_next_result() //在多语句执行过程中返回/初始化下一个结果。
39.mysql_num_fields() //返回结果集中的列数。
40.mysql_num_rows() //返回结果集中的行数。
41.mysql_options() //为mysql_connect()设置连接选项。
42.mysql_ping() //检查与服务器的连接是否工作,如有必要重新连接。
43.mysql_query() //执行指定为“以Null终结的字符串”的SQL查询。
44.mysql_real_connect() //连接到MySQL服务器。
45.mysql_real_escape_string() //考虑到连接的当前字符集,为了在SQL语句中使用,对字符串中的特殊字符进行转义处理。
46.mysql_real_query() //执行指定为计数字符串的SQL查询。
47.mysql_refresh() //刷新或复位表和高速缓冲。
48.mysql_reload() //通知服务器再次加载授权表。
49.mysql_rollback() //回滚事务。
50.mysql_row_seek() //使用从mysql_row_tell()返回的值,查找结果集中的行偏移。
51.mysql_row_tell() //返回行光标位置。
52.mysql_select_db() //选择数据库。
53.mysql_server_end() //最终确定嵌入式服务器库。
54.mysql_server_init() //初始化嵌入式服务器库。
55.mysql_set_server_option() //为连接设置选项(如多语句)。
56.mysql_sqlstate() //返回关于上一个错误的SQLSTATE错误代码。
57.mysql_shutdown() //关闭数据库服务器。
58.mysql_stat() //以字符串形式返回服务器状态。
59.mysql_store_result() //检索完整的结果集至客户端。
60.mysql_thread_id() //返回当前线程ID。
61.mysql_thread_safe() //如果客户端已编译为线程安全的,返回1。
62.mysql_use_result() //初始化逐行的结果集检索。
63.mysql_warning_count() //返回上一个SQL语句的告警数。
mysql的多线程安全问题:在mysql_real_connect时出现 段错误_ruilinxiang_新浪博客 - Google Chrome (2013/8/15 22:43:57)
mysql的多线程安全问题:在mysql_real_connect时出现 段错误
(2011-04-28 17:27:07)mysql的多线程安全问题:
在mysql_real_connect时出现段错误。
问题简化重现
19 #include
20 #include 21
22 void* func(void* arg)
23 {
24 MYSQL* mysql = (MYSQL *)arg;
26 mysql_real_connect(mysql, “127.0.0.1″, “root”, “213456″, “FC_word”, 3344, NULL, 0);
27 mysql_close(mysql);
29 return (void *)0;
30 }
31
32 int main()
33 {
34 MYSQL mysql;
35 if (NULL == mysql_init(&mysql)){
36 return -1;
37 }
38 pthread_t thread;
39 pthread_create(&thread, NULL, func, &mysql);
40 pthread_join(thread, NULL);
41
42 return 0;
43 }
会core掉:
#0 0×0000000000417db2 in my_stat ()
(gdb) bt
#0 0×0000000000417db2 in my_stat ()
#1 0×00000000004169f4 in my_read_charset_file ()
#2 0×0000000000416cb2 in init_available_charsets ()
#3 0×00000000004170ea in get_charset_by_csname ()
#4 0×0000000000405fda in mysql_init_character_set ()
#5 0×0000000000407024 in mysql_real_connect ()
问题原因
粗略看了下源代码,Mysql_init()会初始化一些线程私有数据。 Mysql_init()中调用my_thread_init(), 其中设置线程私有数据。
解决办法
所以可以这么使用:(1)mysql_init()和mysql_real_connect()放在一起:
(2)调用mysql_thread_init()和mysql_thread_end()来初始化和线程相关的数据
如:
22 void* func(void* arg)
23 {
24 MYSQL* mysql = (MYSQL *)arg;
25 mysql_thread_init();
26 mysql_real_connect(mysql, “127.0.0.1″, “root”, “213456″, “FC_word”, 3344, NULL, 0);
27 mysql_close(mysql);
28 mysql_thread_end();
29 return (void *)0;
30 }
其他
另外还遇到一个比较诡异的问题,MYSQL_OPT_RECONNECT不起作用。具体情况是:
Mysql server 使用5.0.22版本, mysql client api 使用third-64/mysql下的5.1.30版本, 重连不起作用,mysql_error也被置空
Mysql server 使用5.0.45版本(凤巢线上版本), mysql client api 使用third-64/mysql下的5.1.30版本, 重连起作用了。
提醒大家使用时注意mysql sever 和client api的版本,^_^
其他共享经验
mysql_init()不是完全线程安全的,但是只要成功调用一次就后就线程安全了,如果有多线程并发使用mysql_init(),建议在程序初始化时空调一次mysql_init(),他的这点特性很像qsort() 。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/dongzhongshu/archive/2010/09/30/5915708.aspx
Mysql C 带事务管理的添删查改 - 努力创造未来! - BlogJava - Google Chrome (2013/8/9 21:56:26)
今天写的例子,只贴代码,不使用文字说明.mysqltool.h
#include <stdlib.h>
#include <winsock.h>
#include <mysql.h>
int xinsert(MYSQL *mysql,char *strsql)
{
int t;
MYSQL_RES *res;
t=mysql_real_query(mysql,strsql,(unsigned int)strlen(strsql));
if(t){
printf( "Error id=%d Error: %s\n",mysql_errno(mysql),mysql_error(mysql));
return mysql_errno(mysql);
}else{
res=mysql_store_result(mysql);
printf("插入行数=%d\n",mysql_affected_rows(mysql));
mysql_free_result(res);
}
return 0;
}
int xupate(MYSQL *mysql,char *strsql)
{
int t;
MYSQL_RES *res;
t=mysql_real_query(mysql,strsql,(unsigned int)strlen(strsql));
if(t){
printf( "Error id=%d Error: %s\n",mysql_errno(mysql),mysql_error(mysql));
return mysql_errno(mysql);
}else{
res=mysql_store_result(mysql);
printf("更新行数=%d\n",mysql_affected_rows(mysql));
mysql_free_result(res);
}
return 0;
}
int xdelete(MYSQL *mysql,char *strsql)
{
int t;
MYSQL_RES *res;
t=mysql_real_query(mysql,strsql,(unsigned int)strlen(strsql));
if(t){
printf( "Error id=%d Error: %s\n",mysql_errno(mysql),mysql_error(mysql));
return mysql_errno(mysql);
}else{
res=mysql_store_result(mysql);
printf("删行数=%d\n",mysql_affected_rows(mysql));
mysql_free_result(res);
}
return 0;
}
one.c 代码如下:
#include <winsock.h>
#include <mysql.h>
#include <stdio.h>
#include <mysqltool.h>
int main()
{
MYSQL mysql; //mysql连接
MYSQL_RES *res; //这个结构代表返回行的一个查询结果集
MYSQL_ROW row; //一个行数据的类型安全(type-safe)的表示
char *query; //查询语句
int t,r;
mysql_init(&mysql);
if (!mysql_real_connect(&mysql,"localhost", "lottobar", "123456", "lottobar",3306,NULL,0))
{
printf( "Error connecting to database: %s\n",mysql_error(&mysql));
} else
printf("Connected\n");
query="SET CHARACTER SET GBK"; //设置编码
t=mysql_real_query(&mysql,query,(unsigned int)strlen(query));
if(t)
{
printf("编码设置失败\n");
}
query=" select * from demo ";
t=mysql_real_query(&mysql,query,(unsigned int)strlen(query));
if(t)
{
printf("执行查询时出现异常: %s",mysql_error(&mysql));
}else
printf("[%s] 构建成功 \n",query);
res=mysql_store_result(&mysql);
while(row=mysql_fetch_row(res))
{
for(t=0;t<mysql_num_fields(res);t++)
{
printf("%s\t",row[t]);
}
printf("\n");
}
mysql_free_result(res);
t=mysql_real_query(&mysql,"SET AUTOCOMMIT =0",(unsigned int)strlen("SET AUTOCOMMIT =0"));
if(t){
printf("启用手工事务失败\n");
}else{
printf("启用手工事务成功\n");
}
t=mysql_real_query(&mysql,"Begin ;",(unsigned int)strlen("Begin ;"));
query="insert into demo(name,age)values('老裴','89')";
int inset_result=xinsert(&mysql,query);
query="delete from demo where name='老裴'";
int delete_result=xdelete(&mysql,query);
query="update demo set name='裴屋村' where name='ccd' and inc_id=13";
int update_result=xupate(&mysql,query);
query="insert into demo(inc_id,name,age)values(16,'老裴','89')";//执行会出现异常的语句
int fail_result=xinsert(&mysql,query);
if(inset_result==0 && delete_result==0 && update_result==0 && fail_result==0){
printf("事务提交\n");
t=mysql_real_query(&mysql,"COMMIT;",(unsigned int)strlen("COMMIT;"));
}else{
printf("事务回滚\n");
t=mysql_real_query(&mysql,"ROLLBACK;",(unsigned int)strlen("ROLLBACK;"));
}
return 0;
}
mysql事务处理(实例) - Mysql,事务处理,shf321,学会做人,学会做事!----孙鸿峰 - Powered by sunhongfeng - Google Chrome (2013/8/9 21:56:03)
mysql事务处理(实例)
Submitted by shf321 on 2011-07-06, 09:45 AM. Mysql
MYSQL的事务处理主要有两种方法。
1、用begin,rollback,commit来实现
begin 开始一个事务
rollback 事务回滚
commit 事务确认
2、直接用set来改变mysql的自动提交模式
MYSQL默认是自动提交的,也就是你提交一个QUERY,它就直接执行!我们可以通过
set autocommit=0 禁止自动提交
set autocommit=1 开启自动提交
来实现事务的处理。
当你用 set autocommit=0 的时候,你以后所有的SQL都将做为事务处理,直到你用commit确认或rollback结束。
注意当你结束这个事务的同时也开启了个新的事务!按第一种方法只将当前的作为一个事务!
个人推荐使用第一种方法!
MYSQL中只有INNODB和BDB类型的数据表才能支持事务处理!其他的类型是不支持的!
***:一般MYSQL数据库默认的引擎是MyISAM,这种引擎不支持事务!如果要让MYSQL支持事务,可以自己手动修改:
方法如下:1.修改c:\appserv\mysql\my.ini文件,找到skip-InnoDB,在前面加上#,后保存文件。
2.在运行中输入:services.msc,重启mysql服务。
3.到phpmyadmin中,mysql->show engines;(或执行mysql->show variables like 'have_%'; ),查看InnoDB为YES,即表示数据库支持InnoDB了。
也就说明支持事务transaction了。
4.在创建表时,就可以为Storage Engine选择InnoDB引擎了。如果是以前创建的表,可以使用mysql->alter table table_name type=InnoDB;
或 mysql->alter table table_name engine=InnoDB;来改变数据表的引擎以支持事务。
*/
/*************** transaction--1 ***************/
$conn = mysql_connect('localhost','root','root') or die ("数据连接错误!!!");
mysql_select_db('test',$conn);
mysql_query("set names 'GBK'"); //使用GBK中文编码;
//开始一个事务
mysql_query("BEGIN"); //或者mysql_query("START TRANSACTION");
$sql = "INSERT INTO `user` (`id`, `username`, `sex`) VALUES (NULL, 'test1', '0')";
$sql2 = "INSERT INTO `user` (`did`, `username`, `sex`) VALUES (NULL, 'test1', '0')";//这条我故意写错
$res = mysql_query($sql);
$res1 = mysql_query($sql2);
if($res && $res1){
mysql_query("COMMIT");
echo '提交成功。';
}else{
mysql_query("ROLLBACK");
echo '数据回滚。';
}
mysql_query("END");
/**************** transaction--2 *******************/
/*方法二*/
mysql_query("SET AUTOCOMMIT=0"); //设置mysql不自动提交,需自行用commit语句提交
$sql = "INSERT INTO `user` (`id`, `username`, `sex`) VALUES (NULL, 'test1', '0')";
$sql2 = "INSERT INTO `user` (`did`, `username`, `sex`) VALUES (NULL, 'test1', '0')";//这条我故意写错
$res = mysql_query($sql);
$res1 = mysql_query($sql2);
if($res && $res1){
mysql_query("COMMIT");
echo '提交成功。';
}else{
mysql_query("ROLLBACK");
echo '数据回滚。';
}
mysql_query("END"); //事务处理完时别忘记mysql_query("SET AUTOCOMMIT=1");自动提交
/******************对于不支持事务的MyISAM引擎数据库可以使用表锁定的方法:********************/
//MyISAM & InnoDB 都支持,
/*
LOCK TABLES可以锁定用于当前线程的表。如果表被其它线程锁定,则造成堵塞,直到可以获取所有锁定为止。
UNLOCK TABLES可以释放被当前线程保持的任何锁定。当线程发布另一个LOCK TABLES时,或当与服务器的连接被关闭时,所有由当前线程锁定的表被隐含地解锁。
*/
mysql_query("LOCK TABLES `user` WRITE");//锁住`user`表
$sql = "INSERT INTO `user` (`id`, `username`, `sex`) VALUES (NULL, 'test1', '0')";
$res = mysql_query($sql);
if($res){
echo '提交成功。!';
}else{
echo '失败!';
}
mysql_query("UNLOCK TABLES");//解除锁定
linux下C连接mysql查询表信息汉字乱码问题 - it_machie_的个人页面 - 开源中国社区 - Google Chrome (2013/8/7 11:00:22)
mysql的c api 简单用法 - 冷侃 - 博客园 - Google Chrome (2013/8/5 17:02:14)
mysql的c api 简单用法
首先第一步,当然是去mysql网站下载一下C API的库文件以及头文件了
地址为http://dev.mysql.com/downloads/connector/c/6.0.html
无非也是几个数据结构以及几个函数
先看一下数据结构,如下
MYSQL
- 这个结构表示对一个数据库连接的句柄,它被用于几乎所有的MySQL函数。
MYSQL_RES
- 这个结构代表返回行的一个查询的(
SELECT
,SHOW
,DESCRIBE
,EXPLAIN
)的结果。从查询返回的信息在本章下文称为结果集合。 MYSQL_ROW
- 这是一个行数据的类型安全(type-safe)的表示。当前它实现为一个计数字节的字符串数组。(如果字段值可能包含二进制数据,你不能将这些视为空终止串,因为这样的值可以在内部包含空字节) 行通过调用
mysql_fetch_row()
获得。 MYSQL_FIELD
- 这个结构包含字段信息,例如字段名、类型和大小。其成员在下面更详细地描述。你可以通过重复调用
mysql_fetch_field()
对每一列获得MYSQL_FIELD
结构。字段值不是这个结构的部分;他们被包含在一个MYSQL_ROW
结构中。
然后介绍几个最常用的api函数
mysql_affected_rows() | 返回被最新的UPDATE , DELETE 或INSERT 查询影响的行数。 |
mysql_close() | 关闭一个服务器连接。 |
mysql_errno() | 返回最近被调用的MySQL函数的出错编号。 |
mysql_error() | 返回最近被调用的MySQL函数的出错消息。 |
mysql_fetch_row() | 从结果集合中取得下一行。 |
mysql_field_count() | 返回最近查询的结果列的数量。 |
mysql_init() | 获得或初始化一个MYSQL 结构。 |
mysql_insert_id() | 返回有前一个查询为一个AUTO_INCREMENT 列生成的ID。 |
mysql_num_rows() | 返回一个结果集合中的行的数量。 |
mysql_query() | 执行指定为一个空结尾的字符串的SQL查询。 |
mysql_real_connect() | 连接一个MySQL服务器。 |
mysql_real_query() | 执行指定为带计数的字符串的SQL查询。 |
[linux c]mysql 编程笔记 - co1d7urt - 博客园 - Google Chrome (2013/8/5 16:46:03)
[linux c]mysql 编程笔记
要进行linux下的mysql的C编程,需要安装mysql及mysql的开发包,ubuntu下直接apt-get install libmysql++安装开发包。
#include <mysql.h>
相关函数:
MYSQL *mysql_init(MYSQL *); //这里称之为载入函数吧,返回的MYSQL指针要用到后续的函数中 int mysql_options(MYSQL *connection, enum option_to_set,const char *argument); //设置MYSQL*的一些属性,比如超时时间等 MYSQL *mysql_real_connect(MYSQL *connection, const char *server_host, const char *sql_user_name, const char *sql_password, const char *db_name, unsigned int port_number,//置0连接默认端口,一般为3306 const char *unix_socket_name,//NULL unsigned int flags);//无另外属性时置0 //连接函数 void mysql_close(MYSQL *connection); //关闭连接 unsigned int mysql_errno(MYSQL *connection); //返回错误代码 char *mysql_error(MYSQL *connection); //返回错误信息 int mysql_query(MYSQL *connection, const char *query); //执行sql语句 my_ulonglong mysql_affected_rows(MYSQL *connection); //返回执行语句过后受影响的行数 MYSQL_RES *mysql_store_result(MYSQL *connection); //返回执行结果,适用于数据量较小时 my_ulonglong mysql_num_rows(MYSQL_RES *result); //返回上面函数返回结果的行数 MYSQL_ROW mysql_fetch_row(MYSQL_RES *result); //抽取一条记录,返回NULL时表示抽取完记录或者错误 void mysql_data_seek(MYSQL_RES *result, my_ulonglong offset); //调整数据位置,offset为0时,下次调用mysql_fetch_row将返回result第一条记录 MYSQL_ROW_OFFSET mysql_row_tell(MYSQL_RES *result); //返回当前的位置 MYSQL_ROW_OFFSET mysql_row_seek(MYSQL_RES *result, MYSQL_ROW_OFFSET offset); //移动数据位置,并返回先前的位置,可以和上一个函数结合使用 void mysql_free_result(MYSQL_RES *result); //释放result空间 MYSQL_RES *mysql_use_result(MYSQL *connection); //返回执行结果,适用于数据量较大时 unsigned int mysql_field_count(MYSQL *connection); //返回查询结果中的列数(column数) MYSQL_FIELD *mysql_fetch_field(MYSQL_RES *result); //获得查询结果中的列名等信息(表头信息)
例子:
创建测试数据库
mysql> create database test;
创建用户
mysql> grant all on test.* to test@'localhost' identified by 'test';
sql文件:
-- -- Create the table children -- CREATE TABLE children ( childno int(11) NOT NULL auto_increment, fname varchar(30), age int(11), PRIMARY KEY (childno) ); -- -- Populate the table ‘children’ -- INSERT INTO children(childno,fname,age) VALUES(1,'Jenny',21); INSERT INTO children(childno,fname,age) VALUES(2,'Andrew',17); INSERT INTO children(childno,fname,age) VALUES(3,'Gavin',8); INSERT INTO children(childno,fname,age) VALUES(4,'Duncan',6); INSERT INTO children(childno,fname,age) VALUES(5,'Emma',4); INSERT INTO children(childno,fname,age) VALUES(6,'Alex',15); INSERT INTO children(childno,fname,age) VALUES(7,'Adrian',9);
导入sql文件:
mysql -u test --password=test test<mysqlchildren.sql
导入后的情况:
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| children |
+----------------+
1 row in set (0.00 sec)
mysql> select * from children;
+---------+--------+------+
| childno | fname | age |
+---------+--------+------+
| 1 | Jenny | 21 |
| 2 | Andrew | 17 |
| 3 | Gavin | 8 |
| 4 | Duncan | 6 |
| 5 | Emma | 4 |
| 6 | Alex | 15 |
| 7 | Adrian | 9 |
+---------+--------+------+
7 rows in set (0.00 sec)
C代码:
#include <stdio.h> #include <stdlib.h> #include <mysql.h> MYSQL *mysql_main; MYSQL_RES *res_ptr; MYSQL_ROW sqlrow; void display_header(); void display_row(); int main(int argc,char *argv[]) { int res; int first_row = 1; mysql_main = mysql_init(NULL); if(!mysql_main) { fprintf(stderr,"mysql_init failed\n"); return EXIT_FAILURE; } mysql_main = mysql_real_connect(mysql_main,"localhost","test","test","test",0,NULL,0); if(mysql_main) { printf("Connection success:\n"); res = mysql_query(mysql_main,"SELECT childno,fname,age FROM children WHERE age>5"); if(res) { fprintf(stderr,"SELECT error: %s\n",mysql_error(mysql_main)); } else { res_ptr = mysql_use_result(mysql_main); if(res_ptr) { while((sqlrow = mysql_fetch_row(res_ptr))) { if(first_row) { display_header(); first_row = 0; } display_row(); } } } } else { printf("Connection failed\n"); } mysql_close(mysql_main); return EXIT_SUCCESS; } void display_header() { MYSQL_FIELD *field_ptr; printf("Column details:\n"); while((field_ptr = mysql_fetch_field(res_ptr))!=NULL) { printf("\t Name: %s\n",field_ptr->name); printf("\t Type: "); if(IS_NUM(field_ptr->type)) { printf("Numeric filed\n"); } else { switch(field_ptr->type) { case FIELD_TYPE_VAR_STRING: printf("VARCHAR\n"); break; case FIELD_TYPE_LONG: printf("LONG\n"); break; default: printf("Type is %d,check in mysql_com.h\n",field_ptr->type); } } printf("\t MAX width %ld\n",field_ptr->length); if(field_ptr->flags&AUTO_INCREMENT_FLAG) printf("\t Auto increments\n"); printf("\n"); } } void display_row() { unsigned int field_count; field_count = 0; while(field_count<mysql_field_count(mysql_main)) { if(sqlrow[field_count]) printf("%s ",sqlrow[field_count]); else printf("NULL"); field_count++; } printf("\n"); }
gcc -I/usr/include/mysql -L/usr/lib/mysql -lmysqlclient -o mysqltest mysqltest.c
./test
结果如下:
Connection success:
Column details:
Name: childno
Type: Numeric filed
MAX width 11
Auto increments
Name: fname
Type: VARCHAR
MAX width 30
Name: age
Type: Numeric filed
MAX width 11
1 Jenny 21
2 Andrew 17
3 Gavin 8
4 Duncan 6
6 Alex 15
7 Adrian 9
mysql 远程访问不行解决方法 Host is not allowed to connect to this MySQL server - 鞋chen3888015.taobao.com - 51C (2013/8/5 15:49:09)
本文来自博客园,作者:suntl,转载请注明原文链接:https://www.cnblogs.com/stlong/p/6290335.html