27.7.15 C API 多语句执行支持

默认情况下,mysql_query()mysql_real_query()将它们的语句字符串参数解释为要执行的单个语句,然后根据该语句产生的是结果集(对于SELECT是一组行)还是受影响的行数( INSERTUPDATE等)。

MySQL 还支持执行包含以分号(;)字符分隔的多个语句的字符串。通过使用mysql_real_connect()连接到服务器或通过调用mysql_set_server_option()连接后指定的特殊选项可以启用此功能。

执行多语句字符串可以产生多个结果集或行计数指示符。处理这些结果所涉及的方法与单语句情况所采用的方法不同:处理完第一条语句的结果后,有必要检查是否存在更多结果,并依次进行处理。为了支持多结果处理,C API 包括mysql_more_results()mysql_next_result()函数。只要有更多结果可用,这些函数就会在循环的结尾使用。 *无法以这种方式处理结果可能会导致与服务器的连接断开。

如果对存储过程执行CALL语句,则还需要多结果处理。存储过程的结果具有以下 Feature:

通常,调用者无法知道过程将返回多少结果集。过程执行可能取决于导致执行路径从一个调用到另一个调用的不同的循环或条件语句。因此,您必须准备检索多个结果。

多重语句和结果功能只能与mysql_query()mysql_real_query()一起使用。它们不能与 prepared statement 接口一起使用。sched 义的语句处理程序被定义为仅与包含单个语句的字符串一起使用。参见第 27.7.7 节“ C API 准备语句”

为了启用多语句执行和结果处理,可以使用以下选项:

以下过程概述了用于处理多个语句的建议策略:

下面显示了上述策略的一种可能的实现方式。循环的最后一部分可以简化为mysql_next_result()是否返回非零的简单测试。所编写的代码在没有更多结果和一个错误之间进行区分,该错误使出现后一种情况时可以打印一条消息。

/* 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);
首页