Spec-Zone .ru
спецификации, руководства, описания, API
|
По умолчанию, mysql_query()
и mysql_real_query()
интерпретируйте их строковый параметр оператора как единственный оператор, который будет выполняться, и Вы
обрабатываете результат согласно тому, производит ли оператор набор результатов (ряд строк, что касается SELECT
) или количество влиявших строк (что касается INSERT
, UPDATE
,
и т.д).
MySQL 5.7 также поддерживает выполнение строки, содержащей многократные операторы, разделенные точкой с запятой
(";
") символы. Эта
возможность включается специальными опциями, которые определяются также, когда Вы соединяетесь с сервером с mysql_real_connect()
или после
соединения, вызывая` mysql_set_server_option()
.
Выполнение строки многократного оператора может произвести многократные наборы результатов или индикаторы
количества строки. Обработка этих результатов включает другой подход чем для случая единственного оператора:
После обработки следствия первого оператора необходимо проверить, существует ли больше результатов и
обрабатывает их поочередно раз так. Чтобы поддерживать обработку многократного результата, API C включает mysql_more_results()
и mysql_next_result()
функции. Эти функции используются в конце цикла, который
выполняет итерации, пока больше результатов доступно. Отказ обработать результат этот
путь может привести к отброшенному соединению с сервером.
Многократный результат, обрабатывающий также, требуется, если Вы выполняетесь CALL
операторы для хранимых процедур. У следствий хранимой процедуры есть эти
характеристики:
Операторы в пределах процедуры могут произвести наборы результатов (например, если
она выполняется SELECT
операторы). Эти наборы результатов возвращаются в порядке, что
они производятся, поскольку процедура выполняется.
Вообще, вызывающая сторона не может знать, сколько наборов результатов процедура возвратится. Выполнение процедуры может зависеть от циклов или условных операторов, которые заставляют путь выполнения отличаться от одного звонка в следующее. Поэтому, Вы должны быть подготовлены получить многократные результаты.
Окончательным результатом из процедуры является результат состояния, который не включает набора результатов. Состояние указывает, произошла ли процедура, за которой следуют или ошибка.
Многократный оператор и возможности результата могут использоваться только с mysql_query()
или mysql_real_query()
.
Они не могут использоваться с готовым интерфейсом оператора. Готовые дескрипторы оператора определяются, чтобы
работать только со строками, которые содержат единственный оператор. См. Раздел
21.8.8, "API C Готовые Операторы".
Чтобы включить выполнению многократного оператора и обработке результата, следующие опции могут использоваться:
mysql_real_connect()
у функции есть a flags
параметр, для которого два значения опции важны:
CLIENT_MULTI_RESULTS
позволяет клиентской
программе обработать многократные результаты. Эта опция должна быть включена, если Вы выполняетесь CALL
операторы для хранимых процедур, которые производят
наборы результатов. Иначе, такие процедуры приводят к ошибке Error
1312 (0A000): PROCEDURE
. В MySQL 5.7, proc_name
can't return
a result set in the given contextCLIENT_MULTI_RESULTS
включается по умолчанию.
CLIENT_MULTI_STATEMENTS
включает mysql_query()
и mysql_real_query()
выполнить строки оператора, содержащие
многократные операторы, разделенные точками с запятой. Эта опция также включает CLIENT_MULTI_RESULTS
неявно, таким образом, a flags
параметр 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
.
Включение выполнению многократного оператора с этой функцией также позволяет обработать "простых" результатов для строки
многократного оператора, где каждый оператор приводит к единственному результату, но не достаточен, чтобы разрешить обрабатывать хранимых процедур,
которые производят наборы результатов.
Следующая процедура обрисовывает в общих чертах предложенную стратегию обработки многократных операторов:
Передача CLIENT_MULTI_STATEMENTS
к mysql_real_connect()
, полностью включать выполнению многократного
оператора и обработке многократного результата.
После вызова mysql_query()
или mysql_real_query()
и
проверка, что это успешно выполняется, вводит цикл, в пределах которого Вы обрабатываете результаты
оператора.
Для каждой итерации цикла обработайте текущий результат оператора, получая или набор результатов или количество влиявших строк. Если ошибка происходит, выйдите из цикла.
В конце цикла вызвать mysql_next_result()
проверять, существует ли другой результат и начатое
извлечение для этого раз так. Если больше результатов не доступно, выходит из цикла.
Одну возможную реализацию предыдущей стратегии показывают следующая. Заключительная часть цикла может быть
уменьшена до простого теста ли 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);