初期設定によって、mysql_query()及びmysql_real_query()は自分のステートメントストリング引数を、実行すべきシングルステートメントとして解釈し、あなたは結果を、ステートメントが結果セット(SELECTについては一組の列またはINSERT、UPDATE等に関する影響された列カウント)を生成するか否かに基づいて処理します。
MySQL
5.1はセミコロン(‘;’)文字によって隔離されたマルチプルステートメントを含むストリングの実行をもサポートしています。この能力は、あなたがmysql_real_connect()を使ってサーバに接続するとき、もしくはmysql_set_server_option()を呼び出すことによる接続後、規定される特別オプションによって有効化されます。.
マルッチプルステートメント・ストリングを実行するとことによって、マルチプル結果セットまたは列カウント・インジケータを生成させることができます。これらの結果処理には、シングルステートメントの処理の場合と異なる方法が関与します。最初のステートメントから結果を処理した後、もっと多くの結果が存在するかどうか調べて、もしあった場合、それらを順番に処理することが必要です。マルチ結果の処理をサポートするため、C
API
には、mysql_more_results()機能とmysql_next_result()機能が含まれています。これらの機能は一般に、もっと多くの結果が得られる場合に限り、反復するループの終わりに使われます。結果の処理に失敗すると、この方法は、サーバへの接続をドロップさせる結果を生む恐れがあります。
CALLステートメントを記憶された手順に対して実行する場合、マルチ結果処理も必要です。記憶された手順は、終わるとき状態結果を戻しますが、運転(例えば、SELECTステートメントの実行)するとき結果セットを生成します。最終ステータスに加え、結果セットを生成する記憶された手順のために、マルチ結果を復元するよう準備しなければなりません。
マルチステートメント機能とマルチ結果機能はmysql_query()またはmysql_real_query()と一緒にだけ使うことができます。それらは準備されたステートメント・インタフェースと一緒に使うことができません。準備されたステートメントハンドルは一つのステートメントを含むストリングだけを使って働くハンドルと定義されます。項23.2.4. 「準備されたC APIステートメント。」を参照してください。
マルチステートメントの実行と結果の処理を有効にするには、次のオプションを使うことができます:
mysql_real_connect()機能には、2つのオプション値が関連する
flags引数が含まれています。
CLIENT_MULTI_RESULTSはクライアントプログラムがマルチ結果を処理することを可能にします。このオプションmustは、結果セットを生成する記憶された手順のためにCALLステートメントを実行する場合有効化されます。さもなければ、このような手順はエラー
Error 1312 (0A000): PROCEDURE
.
proc_name can't return a
result set in the given context
CLIENT_MULTI_STATEMENTSはmysql_query()およびmysql_real_query()にセミコロンで仕切られたマルチステートメントを含むステートメントストリングを実行することを可能にします。このオプションは、暗黙にCLIENT_MULTI_RESULTSを有効にするので、mysql_real_connect()に対するCLIENT_MULTI_STATEMENTSのflags引数は、CLIENT_MULTI_STATEMENTS
|
CLIENT_MULTI_RESULTSの引数と同等になります。即ち、CLIENT_MULTI_STATEMENTSはマルチステートメントの実行とマルチ結果の処理を十分に有効化します。
サーバに対する接続が確立された後、それをMYSQL_OPTION_MULTI_STATEMENTS_ONまたはMYSQL_OPTION_MULTI_STATEMENTS_OFFの引数に渡すことによって、マルチステートメントの実行を可能もしくは不能にするため、mysql_set_server_option()機能を使用することができます。この機能を使ってマルチステートメントの実行を有効にすると、各ステートメントが1個の結果を生成するマルチステートメントストリングに対する「simple」結果の処理も有効化されまが、notは結果セットを生成する記憶された手順を許すに十分です。
次の手順はマルチステートメントの取り扱いに対して示唆された戦略を概説したものです。
CLIENT_MULTI_STATEMENTSをmysql_real_connect()に渡して,マルチステートメントの実行とマルチ結果の処理を有効化してください。
mysql_query()またはmysql_real_query()を呼び出し、それが成功したことを確認した後、ステートメントの結果を処理するループを入力してください。
ループを繰り返して入力するたびに、現在のステートメントの結果を処理して、結果セット又は影響された列カウントを復元してください。エラーが起こったら、ループを終了してください。
ループの終わりに、他の結果が存在するかどうか調べ、もしある場合、修正を先導するため、mysql_next_result()を呼び出してください。それ以上結果が得られなくなったら、ループを終了してください。
戦略に関して、実行可能な1つの例を以下で紹介します。
/* connect to server with option 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() 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_next_result()が非ゼロを戻すかどうかの単純なテストに縮小することができます。書き込まれたコードは、更なる結果とエラーを区別し、これによって、メッセージに後者
の発生をプリントすることを許します。
