mysql数据库默认情况下,mysql_query()是一次只执行一条语句。如果一次执行多条语句数据库会报语法错误(错误代码:1064)
注:通常mysql_query()一次只能执行一条语句,即必须由单个SQL语句组成,且不带有终止分号(;)。如果启用了多语句执行,则可以包含多个用分号分隔的语句
mysql_query一次执行多条语句有以下两种方法(C API多语句执行mysql官网说明):
方法一:在建立数据库连接时指定(mysql官网说明)
conn_ptr=mysql_real_connect(conn_ptr,db_ip,db_user,db_pass,db_name,db_port_int,NULL,CLIENT_MULTI_STATEMENTS);
方法二:要执行多条语句之前指定(mysql官网说明)
mysql_set_server_option(conn_ptr,MYSQL_OPTION_MULTI_STATEMENTS_ON);
int res=mysql_query(conn_ptr,alo_sql_str);
mysql_set_server_option(conn_ptr,MYSQL_OPTION_MULTI_STATEMENTS_OFF);
以上两种解决方法都需要对数据库返回的结果集进行处理,否则后续sql执行时会报错(error:2014 Commands out of sync; you can’t run this command now)。换言之即:当使用执行多语句功能后,一定要读完整个resault集,否则会出现错误:error:2014 Commands out of sync; you can’t run this command now。
如果仅仅是插入等不需要返回值的SQL语句,也一样得读完整个resault集并释放,最小化的写法如下(mysql_access.c):
#include
#include
#include
#include
void free_conn(MYSQL *mysql){
mysql_close(mysql);
free(mysql);
}
int main(){
/* gcc -o chang_mysql mysql_access.c -L /usr/lib64/mysql -lmysqlclient */
MYSQL *my_con=(MYSQL *)malloc(sizeof(MYSQL));
my_con=mysql_init(my_con);
if(!my_con){
printf("mysql_init error\n");
return -1;
}
my_con=mysql_real_connect(my_con,"db_ip","db_name","db_pass","db_name",3306,NULL,0);
if(my_con){
printf("connect success!\n");
}else{
printf("connect fail![errno:%d][error:%s][sqlstat:%s]\n",mysql_errno(my_con),mysql_error(my_con),mysql_sqlstate(my_con));
}
/* 一次执行多条语句+读完整个resault集 */
char *alo_sql_str=(char *)malloc(2048);
memset(alo_sql_str,0x00,2048);
sprintf(alo_sql_str,"LOCK TABLES test_table WRITE;INSERT INTO test_table VALUES(10);UNLOCK TABLES");
// 执行多条语句:功能打开-多语句执行-功能关闭
mysql_set_server_option(my_con,MYSQL_OPTION_MULTI_STATEMENTS_ON);
int res=mysql_query(my_con,alo_sql_str);
mysql_set_server_option(my_con,MYSQL_OPTION_MULTI_STATEMENTS_OFF);
if(res != 0){
printf("insert fail,msg:[%s]", alo_sql_str );
free(alo_sql_str);
free_conn(my_con);
return -1;
}
// 当使用执行多语句功能后,一定要读完整个resault集,否则会出现错误:erron:2014 error:Commands out of sync; you can't run this command now
MYSQL_RES *my_res; //查询结果
do
{
my_res = mysql_store_result( my_con );
if(my_res) mysql_free_result(my_res);
}while( !mysql_next_result(my_con) ); /* more my_con? -1 = no, >0 = error, 0 = yes (keep looping) */
free(alo_sql_str);
free_conn(my_con);
return 0;
}
/* connect to server with the CLIENT_MULTI_STATEMENTS option */
if (mysql_real_connect (mysql, host_name, user_name, password,
db_name, port_num, socket_name, CLIENT_MULTI_STATEMENTS) == NULL)
{
printf("mysql_real_connect() failed\n");
mysql_close(mysql);
exit(1);
}
/* execute multiple statements */
status = mysql_query(mysql,
"DROP TABLE IF EXISTS test_table;\
CREATE TABLE test_table(id INT);\
INSERT INTO test_table VALUES(10);\
UPDATE test_table SET id=20 WHERE id=10;\
SELECT * FROM test_table;\
DROP TABLE test_table");
if (status)
{
printf("Could not execute statement(s)");
mysql_close(mysql);
exit(0);
}
/* process each statement result */
do {
/* did current statement return data? */
result = mysql_store_result(mysql);
if (result)
{
/* yes; process rows and free the result set */
process_result_set(mysql, result);
mysql_free_result(result);
}
else /* no result set or error */
{
if (mysql_field_count(mysql) == 0)
{
printf("%lld rows affected\n",
mysql_affected_rows(mysql));
}
else /* some error occurred */
{
printf("Could not retrieve result set\n");
break;
}
}
/* more results? -1 = no, >0 = error, 0 = yes (keep looping) */
if ((status = mysql_next_result(mysql)) > 0)
printf("Could not execute statement\n");
} while (status == 0);
mysql_close(mysql);