37.3. Запуск команд SQL #
В приложении со встраиваемым SQL можно запустить любую команду SQL. Ниже приведены несколько примеров, показывающих как это делать.
37.3.1. Выполнение SQL-операторов #
Создание таблицы:
EXEC SQL CREATE TABLE foo (number integer, ascii char(16)); EXEC SQL CREATE UNIQUE INDEX num1 ON foo(number); EXEC SQL COMMIT;
Добавление строк:
EXEC SQL INSERT INTO foo (number, ascii) VALUES (9999, 'doodad'); EXEC SQL COMMIT;
Удаление строк:
EXEC SQL DELETE FROM foo WHERE number = 9999; EXEC SQL COMMIT;
Изменение:
EXEC SQL UPDATE foo
SET ascii = 'foobar'
WHERE number = 9999;
EXEC SQL COMMIT;Операторы SELECT, возвращающие одну строку результата, также могут выполняться непосредственно командой EXEC SQL. Чтобы обработать наборы результатов с несколькими строками, приложение должно использовать курсоры; см. Подраздел 37.3.2 ниже. (В отдельных случаях приложение может выбрать сразу несколько строк в переменную массива; см. Подраздел 37.4.4.3.1.)
Выборка одной строки:
EXEC SQL SELECT foo INTO :FooBar FROM table1 WHERE ascii = 'doodad';
Так же можно получить параметр конфигурации командой SHOW:
EXEC SQL SHOW search_path INTO :var;
Идентификаторы вида : воспринимаются как переменные среды, то есть они ссылаются на переменные программы C. Они рассматриваются в Разделе 37.4.имя
37.3.2. Использование курсоров #
Чтобы получить набор результатов, содержащий несколько строк, приложение должно объявить курсор и выбирать каждую строку через него. Использование курсора подразумевает следующие шаги: объявление курсора, открытие его, выборку строки через курсор, повторение предыдущего шага, и наконец, закрытие курсора.
Выборка с использованием курсоров:
EXEC SQL DECLARE foo_bar CURSOR FOR
SELECT number, ascii FROM foo
ORDER BY ascii;
EXEC SQL OPEN foo_bar;
EXEC SQL FETCH foo_bar INTO :FooBar, DooDad;
...
EXEC SQL CLOSE foo_bar;
EXEC SQL COMMIT;Более подробно объявление курсора описывается в DECLARE, а выборка строк через курсор — в FETCH.
Примечание
Команда DECLARE в ECPG на самом деле не передаёт этот оператор серверу Postgres Pro. Курсор открывается на сервере (командой сервера DECLARE) в момент, когда выполняется команда OPEN.
37.3.3. Управление транзакциями #
В режиме по умолчанию операторы фиксируются только когда выполняется EXEC SQL COMMIT. Интерфейс встраиваемого SQL также поддерживает автофиксацию транзакций (так работает libpq по умолчанию); она включается аргументом командной строки -t программы ecpg (см. ecpg) либо оператором EXEC SQL SET AUTOCOMMIT TO ON. В режиме автофиксации каждая команда фиксируется автоматически, если только она не помещена в явный блок транзакции. Этот режим можно выключить явным образом, выполнив EXEC SQL SET AUTOCOMMIT TO OFF.
Поддерживаются следующие команды управления транзакциями:
EXEC SQL COMMIT#Зафиксировать текущую транзакцию.
EXEC SQL ROLLBACK#Откатить текущую транзакцию.
EXEC SQL PREPARE TRANSACTIONид_транзакции#Подготовить текущую транзакцию для двухфазной фиксации.
EXEC SQL COMMIT PREPAREDид_транзакции#Зафиксировать транзакцию в подготовленном состоянии.
EXEC SQL ROLLBACK PREPAREDид_транзакции#Откатить транзакцию в подготовленном состоянии.
EXEC SQL SET AUTOCOMMIT TO ON#Включить режим автофиксации.
EXEC SQL SET AUTOCOMMIT TO OFF#Отключить режим автофиксации. По умолчанию он отключён.
37.3.4. Подготовленные операторы #
Когда значения, передаваемые SQL-оператору, неизвестны во время компиляции, или один и тот же оператор будет использоваться многократно, могут быть полезны подготовленные операторы.
Оператор подготавливается командой PREPARE. Вместо значений, которые ещё неизвестны, вставляются местозаполнители «?»:
EXEC SQL PREPARE stmt1 FROM "SELECT oid, datname FROM pg_database WHERE oid = ?";
Если оператор возвращает одну строку, приложение может вызвать EXECUTE после PREPARE для выполнения этого оператора, указав фактические значения для местозаполнителей в предложении USING:
EXEC SQL EXECUTE stmt1 INTO :dboid, :dbname USING 1;
Если оператор возвращает несколько строк, приложение может использовать курсор, объявленный на базе подготовленного оператора. Чтобы привязать входные параметры, курсор нужно открыть с предложением USING:
EXEC SQL PREPARE stmt1 FROM "SELECT oid,datname FROM pg_database WHERE oid > ?";
EXEC SQL DECLARE foo_bar CURSOR FOR stmt1;
/* по достижении конца набора результатов прервать цикл while */
EXEC SQL WHENEVER NOT FOUND DO BREAK;
EXEC SQL OPEN foo_bar USING 100;
...
while (1)
{
EXEC SQL FETCH NEXT FROM foo_bar INTO :dboid, :dbname;
...
}
EXEC SQL CLOSE foo_bar;Когда подготовленный оператор больше не нужен, его следует освободить:
EXEC SQL DEALLOCATE PREPARE имя;Подробнее оператор PREPARE описан в PREPARE. Также обратитесь к Разделу 37.5 за дополнительными сведениями о местозаполнителях и входных параметрах.