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 за дополнительными сведениями о местозаполнителях и входных параметрах.