Spec-Zone .ru
спецификации, руководства, описания, API

22.4.7.2. Вызов Хранимых процедур с Statement Объекты

Хранимую процедуру можно вызвать, используя a Statement или PreparedStatement объект. Этот раздел показывает, как вызвать использование хранимых процедур Statement объекты. Видеть, как использовать PreparedStatement объекты, см. Раздел 22.4.7.3, "Вызывая Хранимые процедуры с PreparedStatement Объекты".

Можно создать и вызвать различные типы хранимых процедур:

  1. Хранимая процедура, которая не возвращает результата. Например, такая хранимая процедура может зарегистрировать некритическую информацию, или изменить данные базы данных прямым способом.

  2. Хранимая процедура, которая возвращает одно или более значений, используя выходные параметры. Например, такая процедура может указать на успех или провал, или получить и возвратить элементы данных.

  3. Хранимая процедура, которая возвращает один или более наборов результатов. Процедура может выполнить один или более запросов, каждый из которых возвращает произвольное число строк. Ваши циклы приложения через каждый набор результатов, чтобы вывести на экран, преобразуйте, или иначе обработайте каждую строку в этом.

Следующие хранимые процедуры иллюстрируют каждый из этих сценариев.

Следующая процедура добавляет страну к 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++ тот вызов хранимые процедуры.

Сценарий 1: Используя a Statement для Хранимой процедуры, Которая Не Возвращает Результата

Этот пример показывает, как вызвать хранимую процедуру, которая не возвращает набора результатов.

  1. Сделайте копию учебного кода платформы:

    shell> cp framework.cpp
                        sp_scenario1.cpp
  2. Добавьте следующий код к 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')");
  3. Скомпилируйте программу как описано в Разделе 22.4.7.1, "Предпосылки и Вводная информация".

  4. Выполните программу:

    shell> ./sp_scenario1
  5. Используя 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 блочные дескрипторы.

Сценарий 2: Используя a Statement для Хранимой процедуры, Которая Возвращает Выходной Параметр

Этот пример показывает, как обработать хранимую процедуру, которая возвращает выходной параметр.

  1. Сделайте копию учебного кода платформы:

    shell> cp framework.cpp
                        sp_scenario2.cpp
  2. Добавьте следующий код к 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;
  3. Скомпилируйте программу как описано в Разделе 22.4.7.1, "Предпосылки и Вводная информация".

  4. Выполните программу:

    shell> ./sp_scenario2Connector/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++ подобная последовательность выполняется для каждого вызова процедуры:

Сценарий 3: Используя a Statement для Хранимой процедуры, Которая Возвращает Набор результатов

Этот пример показывает, как обработать наборы результатов, произведенные хранимой процедурой.

Отметить

Этот сценарий требует MySQL 5.5.3 или выше. Клиент-серверный протокол не поддерживает выбирающие многократные наборы результатов из хранимых процедур до 5.5.3.

  1. Сделайте копию учебного кода платформы:

    shell> cp framework.cpp
                        sp_scenario3.cpp
  2. Добавьте следующий код к 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());
  3. Скомпилируйте программу как описано в Разделе 22.4.7.1, "Предпосылки и Вводная информация".

  4. Выполните программу:

    shell> ./sp_scenario3Connector/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 и производит только один набор результатов. Это - требование базового протокола.