Spec-Zone .ru
спецификации, руководства, описания, API
|
Хранимую процедуру можно вызвать, используя a Statement
или PreparedStatement
объект. Этот раздел показывает, как вызвать использование хранимых процедур Statement
объекты. Видеть, как использовать PreparedStatement
объекты, см. Раздел 21.4.7.3,
"Вызывая Хранимые процедуры с PreparedStatement
Объекты".
Можно создать и вызвать различные типы хранимых процедур:
Хранимая процедура, которая не возвращает результата. Например, такая хранимая процедура может зарегистрировать некритическую информацию, или изменить данные базы данных прямым способом.
Хранимая процедура, которая возвращает одно или более значений, используя выходные параметры. Например, такая процедура может указать на успех или провал, или получить и возвратить элементы данных.
Хранимая процедура, которая возвращает один или более наборов результатов. Процедура может выполнить один или более запросов, каждый из которых возвращает произвольное число строк. Ваши циклы приложения через каждый набор результатов, чтобы вывести на экран, преобразуйте, или иначе обработайте каждую строку в этом.
Следующие хранимые процедуры иллюстрируют каждый из этих сценариев.
Следующая процедура добавляет страну к world
база данных, но не возвращает
результат. Это соответствует Сценарию 1, описанному ранее.
CREATE PROCEDURE add_country (IN country_code CHAR(3), IN country_name CHAR(52), IN continent_name CHAR(30))BEGIN INSERT INTO Country(Code, Name, Continent) VALUES (country_code, country_name, continent_name);END;
Следующие процедуры используют выходной параметр, чтобы возвратить совокупность указанной страны или континента, или всего мира. Они соответствуют Сценарию 2, описанному ранее.
CREATE PROCEDURE get_pop (IN country_name CHAR(52), OUT country_pop BIGINT)BEGIN SELECT Population INTO country_pop FROM Country WHERE Name = country_name;END;
CREATE PROCEDURE get_pop_continent (IN continent_name CHAR(30), OUT continent_pop BIGINT)BEGIN SELECT SUM(Population) INTO continent_pop FROM Country WHERE Continent = continent_name;END;
CREATE PROCEDURE get_pop_world (OUT world_pop BIGINT)BEGIN SELECT SUM(Population) INTO world_pop FROM Country;END;
Следующая процедура возвращает несколько наборов результатов. Это соответствует Сценарию 3, описанному ранее.
CREATE PROCEDURE get_data ()BEGIN SELECT Code, Name, Population, Continent FROM Country WHERE Continent = 'Oceania' AND Population < 10000; SELECT Code, Name, Population, Continent FROM Country WHERE Continent = 'Europe' AND Population < 10000; SELECT Code, Name, Population, Continent FROM Country WHERE Continent = 'North America' AND Population < 10000;END;
Введите и протестируйте хранимые процедуры вручную, чтобы гарантировать, что они будут доступны Вашим
приложениям C++. (Выберите world
как база данных значения по умолчанию прежде, чем
Вы создадите их.) Вы теперь готовы начать писать приложения, используя Соединитель/C++ тот вызов хранимые
процедуры.
Statement
для Хранимой
процедуры, Которая Не Возвращает РезультатаЭтот пример показывает, как вызвать хранимую процедуру, которая не возвращает набора результатов.
Сделайте копию учебного кода платформы:
shell> cp framework.cpp
sp_scenario1.cpp
Добавьте следующий код к try
блок учебной платформы:
sql::Driver* driver = get_driver_instance();std::auto_ptr<sql::Connection> con(driver->connect(url, user, pass));con->setSchema(database);std::auto_ptr<sql::Statement> stmt(con->createStatement());// We need not check the return value explicitly. If it indicates// an error, Connector/C++ generates an exception.stmt->execute("CALL add_country('ATL', 'Atlantis', 'North America')");
Скомпилируйте программу как описано в Разделе 21.4.7.1, "Предпосылки и Вводная информация".
Выполните программу:
shell> ./sp_scenario1
Используя mysql клиент командной строки или другую подходящую
программу, проверьте world
база данных, чтобы решить, что это было
обновлено правильно. Можно использовать этот запрос:
mysql> SELECT Code, Name, Continent FROM
Country WHERE Code='ATL';
+------+----------+---------------+| Code | Name | Continent |+------+----------+---------------+| ATL | Atlantis | North America |+------+----------+---------------+
Код в этом приложении просто вызывает execute
метод, передавая к этому оператор,
который вызывает хранимую процедуру. Сама процедура не возвращает значения, хотя важно отметить, что всегда есть
возвращаемое значение от CALL
оператор; это execute
состояние. MySQL,
Connector/C ++, обрабатывает это состояние для Вас, таким образом, Вы не должны обработать это явно. Если execute
вызовите сбои по некоторым причинам, это повышает исключение что catch
блочные дескрипторы.
Statement
для Хранимой
процедуры, Которая Возвращает Выходной ПараметрЭтот пример показывает, как обработать хранимую процедуру, которая возвращает выходной параметр.
Сделайте копию учебного кода платформы:
shell> cp framework.cpp
sp_scenario2.cpp
Добавьте следующий код к try
блок учебной платформы:
sql::Driver* driver = get_driver_instance();std::auto_ptr<sql::Connection> con(driver->connect(url, user, pass));con->setSchema(database);std::auto_ptr<sql::Statement> stmt(con->createStatement());stmt->execute("CALL get_pop('Uganda', @pop)");std::auto_ptr<sql::ResultSet> res(stmt->executeQuery("SELECT @pop AS _reply"));while (res->next()) cout << "Population of Uganda: " << res->getString("_reply") << endl;stmt->execute("CALL get_pop_continent('Asia', @pop)");res.reset(stmt->executeQuery("SELECT @pop AS _reply"));while (res->next()) cout << "Population of Asia: " << res->getString("_reply") << endl;stmt->execute("CALL get_pop_world(@pop)");res.reset(stmt->executeQuery("SELECT @pop AS _reply"));while (res->next()) cout << "Population of World: " << res->getString("_reply") << endl;
Скомпилируйте программу как описано в Разделе 21.4.7.1, "Предпосылки и Вводная информация".
Выполните программу:
shell> ./sp_scenario2
Connector/C++ tutorial framework...Population of Uganda: 21778000Population of Asia: 3705025700Population of World: 6078749450Done.
В этом сценарии каждая хранимая процедура устанавливает значение выходного параметра. Это не возвращается
непосредственно к execute
метод, но потребности, которые будут получены, используя
последующий запрос. Если бы Вы выполняли SQL-операторы непосредственно, то Вы могли бы использовать операторы,
подобные им:
CALL get_pop('Uganda', @pop);SELECT @pop;CALL get_pop_continent('Asia', @pop);SELECT @pop;CALL get_pop_world(@pop);SELECT @pop;
В коде C++ подобная последовательность выполняется для каждого вызова процедуры:
Выполнитесь CALL
оператор.
Получите выходной параметр, выполняя дополнительный запрос. Запрос производит a
ResultSet
объект.
Получите данные, используя a while
цикл. Самый простой
способ сделать это должно использовать a getString
метод на ResultSet
, передача имени переменной к доступу. В этом примере _reply
используется в качестве заполнителя для переменной и поэтому
используется в качестве ключа, чтобы получить доступ к корректному элементу словаря результата.
Хотя запрос, используемый, чтобы получить выходной параметр, возвращает только единственную строку,
важно использовать while
цикл, чтобы поймать больше чем одну строку,
избежать возможности соединения, становящегося нестабильным.
Statement
для Хранимой
процедуры, Которая Возвращает Набор результатовЭтот пример показывает, как обработать наборы результатов, произведенные хранимой процедурой.
Этот сценарий требует MySQL 5.5.3 или выше. Клиент-серверный протокол не поддерживает выбирающие многократные наборы результатов из хранимых процедур до 5.5.3.
Сделайте копию учебного кода платформы:
shell> cp framework.cpp
sp_scenario3.cpp
Добавьте следующий код к try
блок учебной платформы:
sql::Driver* driver = get_driver_instance();std::auto_ptr<sql::Connection> con(driver->connect(url, user, pass));con->setSchema(database);std::auto_ptr<sql::Statement> stmt(con->createStatement());stmt->execute("CALL get_data()");std::auto_ptr< sql::ResultSet > res;do { res.reset(stmt->getResultSet()); while (res->next()) { cout << "Name: " << res->getString("Name") << " Population: " << res->getInt("Population") << endl; }} while (stmt->getMoreResults());
Скомпилируйте программу как описано в Разделе 21.4.7.1, "Предпосылки и Вводная информация".
Выполните программу:
shell> ./sp_scenario3
Connector/C++ tutorial framework...Name: Cocos (Keeling) Islands Population: 600Name: Christmas Island Population: 2500Name: Norfolk Island Population: 2000Name: Niue Population: 2000Name: Pitcairn Population: 50Name: Tokelau Population: 2000Name: United States Minor Outlying Islands Population: 0Name: Svalbard and Jan Mayen Population: 3200Name: Holy See (Vatican City State) Population: 1000Name: Anguilla Population: 8000Name: Atlantis Population: 0Name: Saint Pierre and Miquelon Population: 7000Done.
Код подобен примерам, показанным ранее. Особенно интересный код здесь:
do { res.reset(stmt->getResultSet()); while (res->next()) { cout << "Name: " << res->getString("Name") << " Population: " << res->getInt("Population") << endl; }} while (stmt->getMoreResults());
CALL
выполняется как прежде, но на сей раз результаты возвращаются в многократный ResultSet
объекты, потому что хранимая процедура выполняется многократный SELECT
операторы. В этом примере вывод показывает, что три набора результатов
обрабатываются, потому что есть три SELECT
операторы в хранимой процедуре. Каждый
набор результатов возвращает больше чем одну строку.
Результаты обрабатываются, используя эту кодовую комбинацию:
do { Get Result Set while (Get Result) { Process Result }} while (Get More Result Sets);
Используйте этот образец, даже если хранимая процедура выполняет только сингл SELECT
и производит только один набор результатов. Это - требование базового
протокола.