Mysql一次执行多条语句的实现及常见问题(基于C语言API:mysql_query()的实现)

Mysql一次执行多条语句的实现及常见问题(基于C语言API:mysql_query()的实现)

1.背景

mysql数据库默认情况下,mysql_query()是一次只执行一条语句。如果一次执行多条语句数据库会报语法错误(错误代码:1064)
注:通常mysql_query()一次只能执行一条语句,即必须由单个SQL语句组成,且不带有终止分号(;)。如果启用了多语句执行,则可以包含多个用分号分隔的语句

2.解决方案

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。

3.参考代码(一次执行多条语句+读完整个resault集)

3.1最小化的写法(使用的方法二)

如果仅仅是插入等不需要返回值的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;
}
3.2官方参考代码(使用的方法一)
/* 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);

你可能感兴趣的:(MySQL,C语言,mysql,c语言,mysql_query,一次执行多条语句)