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时出现段错误。
问题简化重现19 #include20 #include 2122 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 }3132 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);4142 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() 。
本文来自博客,转载请标明出处:http://blog.csdn.net/dongzhongshu/archive/2010/09/30/5915708.aspx
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");//解除锁定
Tags: 事务处理
今天在linux下用C++封装了一下mysql数据库的连接,在执行 mysql_query(connection, sql_str.c_str())时,查询得到的汉字是乱码。 最后在网上查阅资料发现需要设置读去数据库的编码格式mysql_query(connection, "set names utf8") 即在执行数据查询之前,要设置一下编码方式!
看到一篇文章是这样介绍“set names charset_name”的
1、SET NAMES ‘charset_name’SET NAMES显示客户端发送的SQL语句中使用什么字符集。因此,SET NAMES 'cp1251'语句告诉服务器将来从这个客户端传来的信息采用字符集cp1251”。它还为服务器发送回客户端的结果指定了字符集。(例如,如果你使用一个SELECT语句,它表示列值使用了什么字符集。)2、连接字符集和校对
(1) 一些字符集和校对规则系统变量与客户端和服务器的交互有关。服务器字符集和校对规则可以用作character_set_server和collation_server变量的值。默认数据库的字符集和校对规则可以用作character_set_database和collation_database变量的值。在客户端和服务器的连接处理中也涉及了字符集和校对规则变量。每一个客户端有一个连接相关的字符集和校对规则变量。
(2)考虑什么是一个“连接”:它是连接服务器时所作的事情。
客户端发送SQL语句,例如查询,通过连接发送到服务器。
服务器通过连接发送响应给客户端,例如结果集。
对于客户端连接,这样会导致一些关于连接的字符集和 校对规则的问题,这些问题均能够通过系统变量来解决:(3) 当查询离开客户端后,在查询中使用哪种字符集?服务器使用character_set_client变量作为客户端发送的查询中使用的字符集。
(4) 服务器接收到查询后应该转换为哪种字符集?
转换时,服务器使用character_set_connection和collation_connection系统变量。它将客户端发送的查询从character_set_client系统变量转换到character_set_connection(除非字符串文字具有象_latin1或_utf8的引介词)。collation_connection对比较文字字符串是重要的。对于列值的字符串比较,它不重要,因为列具有更高的 校对规则优先级。
(5)服务器发送结果集或返回错误信息到客户端之前应该转换为哪种字符集?character_set_results变量指示服务器返回查询结果到客户端使用的字符集。包括结果数据,例如列值和结果元数据(如列名)。
首先第一步,当然是去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下的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: childnoType: Numeric filedMAX width 11Auto increments
Name: fnameType: VARCHARMAX width 30
Name: ageType: Numeric filedMAX width 11
1 Jenny 21 2 Andrew 17 3 Gavin 8 4 Duncan 6 6 Alex 15 7 Adrian 9
mysql> update user set host = '%' where user = 'root';ERROR 1062 (23000): Duplicate entry '%-root' for key 1mysql> select host,user from user;+------------------+------+| host | user |+------------------+------+| % | root || 127.0.0.1 | root || 192.168.33.110 | root || yunwei2.uid5a.cn | root |+------------------+------+4 rows in set (0.00 sec)
mysql> select host,user from user;+------------------+------+| host | user |+------------------+------+| % | root || 127.0.0.1 | root || 192.168.33.110 | root || yunwei2.uid5a.cn | root |+------------------+------+4 rows in set (0.00 sec)
mysql> grant all privileges on *.* to 'root'@'%' identified by 'uid5a827' with g rant option;Query OK, 0 rows affected (0.00 sec)
mysql> flush;ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1mysql> flush privileges;Query OK, 0 rows affected (0.00 sec)
mysql> grant all privileges on *.* to 'root'@'buy2.w98-e5.ezwebtest.com' identified by 'abcd1234' with grant option;Query OK, 0 rows affected (0.00 sec)
mysql> flush privileges;Query OK, 0 rows affected (0.00 sec)
参考文章
http://till.iteye.com/blog/115659
如果你想连接你的mysql的时候发生这个错误:ERROR 1130: Host '192.168.1.3' is not allowed to connect to this MySQL server解决方法:1。 改表法。可能是你的帐号不允许从远程登陆,只能在localhost。这个时候只要在localhost的那台电脑,登入mysql后,更改 "mysql" 数据库里的 "user" 表里的 "host" 项,从"localhost"改称"%"mysql -u root -pvmwaremysql>use mysql;mysql>update user set host = '%' where user = 'root';mysql>select host, user from user;2. 授权法。例如,你想myuser使用mypassword从任何主机连接到mysql服务器的话。GRANT ALL PRIVILEGES ON *.* TO 'myuser'@'%' IDENTIFIED BY 'mypassword' WITH GRANT OPTION;如果你想允许用户myuser从ip为192.168.1.3的主机连接到mysql服务器,并使用mypassword作为密码GRANT ALL PRIVILEGES ON *.* TO 'root'@'192.168.1.3' IDENTIFIED BY 'mypassword' WITH GRANT OPTION;
GRANT ALL PRIVILEGES ON *.* TO 'root'@'10.10.40.54' IDENTIFIED BY '123456' WITH GRANT OPTION;
null转载于:https://www.cnblogs.com/stlong/p/6290335.html
相关资源:数据结构—成绩单生成器