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