3.6.2多语句执行支持

默认,mysql_real_query()mysql_query()将其语句字符串参数解释为要执行的单个语句,并且根据语句是否产生结果集(一组行,如图所示)处理结果选择)或受影响的行计数(如更新等等)。

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

执行多语句字符串可以生成多个结果集或行计数指示符。处理这些结果涉及不同的方法,而不是单个陈述案例:处理来自第一个语句的结果后,有必要检查是否存在更多结果并反过来处理它们。为了支持多个结果处理,C API包括mysql_more_results()mysql_next_result()职能。这些函数在循环的末尾使用,即只要有更多结果即可迭代。未能处理结果,这种方式可能导致与服务器的删除连接。

如果执行,也需要多个结果处理称呼存储过程的陈述。存储过程的结果具有以下特征:

  • 过程中的语句可以生成结果集(例如,如果执行选择陈述)。这些结果集按照程序执行的顺序返回。

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

  • 过程中的最终结果是一个包含结果集的状态结果。状态指示程序是否成功或发生错误。

可以仅使用多个语句和结果功能mysql_real_query()或者mysql_query()。它们不能与准备好的声明界面一起使用。准备的语句处理程序定义为仅使用包含单个语句的字符串工作。看第6章,C API准备了语句界面

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

  • mysql_real_connect()功能有一个旗帜两个选项值相关的参数:

    • client_multi_results.使客户端程序能够处理多个结果。这个选项必须如果执行,请启用称呼生成结果集的存储过程的语句。否则,此类程序会导致错误错误1312(0a000):程序proc_name.在给定的上下文中无法返回结果集。在mysql 5.7中,client_multi_results.默认情况下启用。

    • client_multi_statements.启用mysql_real_query()mysql_query()执行包含由分号分隔的多个语句的语句字符串。此选项也可以启用client_multi_results.隐含的,所以一个旗帜争论client_multi_statements.mysql_real_connect()相当于一个论点client_multi_statements |client_multi_results.。那是,client_multi_statements.足以启用多语句执行和所有多个结果处理。

  • 在与服务器的连接建立后,您可以使用mysql_set_server_option()通过将其传递一个参数来启用或禁用多语句执行的函数mysql_option_multi_statements_on.或者mysql_option_multi_statements_off.。使用此功能启用多语句执行也可以处理简单的结果每个语句的多语句字符串产生单个结果,但是是不是足以允许处理产生结果集的存储过程。

以下过程概述了处理多个陈述的建议策略:

  1. 经过client_multi_statements.mysql_real_connect(),完全启用多语句执行和多个结果处理。

  2. 召唤后mysql_real_query()或者mysql_query()并验证它成功,输入您处理语句结果的循环。

  3. 对于循环的每个迭代,处理当前语句结果,检索结果集或受影响行计数。如果发生错误,请退出循环。

  4. 在循环结束时,呼叫mysql_next_result()检查另一个结果是否存在并为其启动检索。如果没有更多的结果,请退出循环。

下面显示了前面策略的一种可能实现。循环的最终部分可以减少到简单的测试mysql_next_result()返回非零。编写的代码在没有更多结果和错误之间区分,这使得能够为后一种发生来打印消息。

/ *使用client_multi_statements选项连接到服务器* / if(mysql_real_connect(mysql,host_name,user_name,password,db_name,port_num,socket_name,client_multi_satements)== null){printf(“mysql_real_connect()失败\ n”);mysql_close(mysql);出口(1);} / *执行多个语句* / status = mysql_query(mysql,“drop表(MySQL)如果存在test_table; \ create table test_table(id int); \插入到test_table值(10); \ update test_table set id = 20其中ID = 10; \ select * from test_table; \ drop table test_table“);if(status){printf(“无法执行语句”);mysql_close(mysql);退出(0);} / *处理每个语句结果* / do {/ *是否当前语句返回数据?* /结果= mysql_store_result(mysql);如果(结果){/ *是; 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);