デフォルトで,mysql_query ()
とmysql_real_query ()
はそれらのステートメント文字列引数を,実行すべき単一のステートメントとして解釈し,ユーザーはステートメントが結果セット(行のセット,选择
の場合)を生成するか,または影響を受ける行カウント(插入
、更新
などの場合)を生成するかに従って,結果を処理します。
MySQL 5.6はセミコロン(「;
」)文字によって区切られた複数のステトメントを格納する文字列の実行もサポトします。この機能は,mysql_real_connect ()
によってサバに接続するとき,またはmysql_set_server_option ()
の呼び出しによる接続後のいずれかに指定される特別なオプションによって有効化されます。
複数ステトメント文字列を実行すると,複数の結果セットまたは行カウントタを生成できます。これらの結果の処理には,単一ステトメントの場合と異なるアプロチが必要です。最初のステートメントからの結果の処理後,それ以上の結果が存在するかどうかをチェックし,存在する場合は,それらを順番に処理する必要があります。複数結果の処理をサポトするため,c APIには,mysql_more_results ()
関数とmysql_next_result ()
関数が含まれています。これらの関数は,それ以上の結果があるかぎり反復するルプの最後で使用します。結果をこのように処理できないと,サバへの接続が切断される可能性があります。
複数結果の処理は,ストアドプロシジャに対して调用
ステトメントを実行する場合にも必要です。ストアドプロシジャの結果にはこれらの特性があります。
プロシジャ内のステトメントは結果セットを生成することがあります(たとえば,それが
选择
ステトメントを実行する場合など)。これらの結果セットは,プロシジャ,の実行とともに,それらが生成された順番で返されます。一般に,呼び出し元はプロシジャが返す結果セットの数を知ることができません。プロシージャーの実行は,呼び出しごとに実行パスが異なるループや条件ステートメントによって異なることがあります。そのため,複数の結果を取得するように準備しておく必要があります。
プロシジャからの最終結果は,結果セットを含まないステタス結果です。このステタスはプロシジャが成功したか,エラ。
複数ステトメントおよび結果機能は,mysql_query ()
またはmysql_real_query ()
と一緒にのみ使用できます。それらはプリペアドステトメントスと一緒に使用できません。プリペアドステートメントハンドルは単一のステートメントを含む文字列のみを操作するように定義されます。セクション23.7.8 " c APIプリペアドステトメント"を参照してください。
複数ステトメントの実行と結果の処理を有効にするには,次のオプションを使うことができます。
mysql_real_connect ()
関数には2のオプション値が関連する旗帜
引数があります。CLIENT_MULTI_RESULTS
により、クラ以及アントプログラムは複数の結果を処理できます。結果セットを生成するストアドプロシジャに対して,调用
ステトメントを実行する場合,このオプションを有効にする必要があります。そうしないと,そのようなプロシジャはエラエラ1312 (0a000):过程
を生成します。MySQL 5.6では;proc_name
は指定されたコンテキストで結果セットを返すことができません”CLIENT_MULTI_RESULTS
はデフォルトで有効にされています。CLIENT_MULTI_STATEMENTS
により,mysql_query ()
およびmysql_real_query ()
はセミコロンで区切られた複数のステトメントを含むステトメント文字列を実行できます。このオプションにより,CLIENT_MULTI_RESULTS
も暗黙的に有効になるため,mysql_real_connect ()
へのCLIENT_MULTI_STATEMENTS
の旗帜
引数は,CLIENT_MULTI_STATEMENTS | CLIENT_MULTI_RESULTS
の引数と同等になります。まり,CLIENT_MULTI_STATEMENTS
は複数ステトメントの実行とすべての複数結果の処理を有効にするのに十分です。
サバへの接続が確立されたあと,
mysql_set_server_option ()
関数を使用して,それをMYSQL_OPTION_MULTI_STATEMENTS_ON
またはMYSQL_OPTION_MULTI_STATEMENTS_OFF
の引数に渡すことによって,複数ステトメントの実行を有効または無効にできます。この関数によって複数ステトメントの実行を有効にすると,複数ステトメント文字列の「簡単な」結果の処理も有効になります。そこでは,各ステートメントが単一の結果を生成しますが,結果セットを生成するストアドプロシージャーの処理を許可するには十分でありません。
次の手順に,複数ステトメントの処理の推奨される戦略の概要を示します。
CLIENT_MULTI_STATEMENTS
をmysql_real_connect ()
に渡して,複数ステトメントの実行と複数結果の処理を完全に有効にします。mysql_query ()
またはmysql_real_query ()
を呼び出し,それが成功したことを確認したあとに,ステ,トメント結果を処理するル,プに入ります。ループの反復ごとに,現在のステートメント結果を処理し,結果セットまたは影響を受けた行カウントを取得します。エラが発生したら,ルプを終了します。
ルプの終わりに,
mysql_next_result ()
を呼び出して,ほかの結果が存在するかどうかをチェックし,その場合は,取得を開始します。それ以上の結果がなくなったら,ルプを終了します。
先述の戦略の1の可能な実装を次に示します。ルプの最終部分は,mysql_next_result ()
がゼロ以外を返すかどうかの簡単なテストに単純化できます。示されているコードは,それ以上の結果がないこととエラーを区別し,それによって,後者の発生でメッセージを出力させることができます。
/*连接到服务器的CLIENT_MULTI_STATEMENTS选项*/ if (mysql_real_connect (mysql, host_name, user_name, password, db_name, port_num, socket_name, CLIENT_MULTI_STATEMENTS) == NULL) {printf("mysql_real_connect()失败\n");mysql_close (mysql);退出(1);\ 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("无法执行语句");mysql_close (mysql);退出(0);} /*处理每个语句的结果*/ do{/*当前语句是否返回数据?*/ 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);