34.9. Препроцессорные директивы#

34.9. Препроцессорные директивы

34.9. Препроцессорные директивы

Доступно несколько директив препроцессора, которые изменяют способ, как препроцессор ecpg разбирает и обрабатывает файл.

34.9.1. Включая файлы

Чтобы включить внешний файл в вашу встроенную программу SQL, используйте:

EXEC SQL INCLUDE filename;
EXEC SQL INCLUDE <filename>;
EXEC SQL INCLUDE "filename";

Встроенный SQL-препроцессор будет искать файл с именем filename.h, предварительно обрабатывать его и включать его в полученный C-код. Таким образом, встроенные SQL-запросы включенного файла обрабатываются правильно.

Препроцессор ecpg будет искать файл в нескольких каталогах в следующем порядке:

  • текущий каталог
  • /usr/local/include
  • Каталог PostgreSQL include, определенный во время сборки (например, /usr/local/pgsql/include)
  • /usr/include

Но когда используется EXEC SQL INCLUDE "filename", происходит поиск только в текущем каталоге.

В каждом каталоге препроцессор сначала будет искать файл с указанным именем, и если не найдет, то добавит суффикс .h к имени файла и попытается снова (если указанное имя файла уже имеет такой суффикс).

Обратите внимание, что EXEC SQL INCLUDE не является тем же самым, что и:

#include <filename.h>

потому что этот файл не будет подвергаться предварительной обработке SQL-команд. Естественно, вы можете продолжать использовать директиву C #include для включения других заголовочных файлов.

Примечание

Имя включаемого файла чувствительно к регистру, даже если остальная часть команды EXEC SQL INCLUDE следует обычным правилам регистрозависимости SQL.

34.9.2. Директивы define и undef

Аналогично директиве #define, известной из языка C, встроенный SQL имеет аналогичную концепцию:

EXEC SQL DEFINE name;
EXEC SQL DEFINE name value;

Таким образом, вы можете определить имя:

EXEC SQL DEFINE HAVE_FEATURE;

И вы также можете определить константы:

EXEC SQL DEFINE MYNUMBER 12;
EXEC SQL DEFINE MYSTRING 'abc';

Используйте тег undef, чтобы удалить предыдущее определение:

EXEC SQL UNDEF MYNUMBER;

Конечно, вы можете продолжать использовать версии на C #define и #undef в своей встроенной программе SQL. Разница заключается в том, где выполняются ваши определенные значения. Если вы используете EXEC SQL DEFINE, то препроцессор ecpg выполняет определения и подставляет значения. Например, если вы напишете:

EXEC SQL DEFINE MYNUMBER 12;
...
EXEC SQL UPDATE Tbl SET col = MYNUMBER;

тогда ecpg уже выполнит подстановку, и ваш компилятор C никогда не увидит никакого имени или идентификатора MYNUMBER. Обратите внимание, что вы не можете использовать #define для константы, которую вы собираетесь использовать во встроенном SQL-запросе, потому что в этом случае прекомпилятор встроенного SQL не сможет увидеть это объявление.

34.9.3. ifdef, ifndef, elif, else, and endif Директивы

Вы можете использовать следующие директивы для условной компиляции кода:

EXEC SQL ifdef name;

Проверяет name и обрабатывает последующие строки, если name было определено с помощью EXEC SQL define name.

EXEC SQL ifndef name;

Проверяет name и обрабатывает последующие строки, если name не было определено с помощью EXEC SQL define name.

EXEC SQL elif name;

Начинает необязательный альтернативный раздел после директивы EXEC SQL ifdef name или EXEC SQL ifndef name. Может быть любое количество разделов elif. Строки, следующие после elif, будут обработаны, если name было определено и ни один предыдущий раздел того же конструкта ifdef/ifndef...endif не был обработан.

EXEC SQL else;

Начинает необязательный, последний альтернативный раздел после директивы EXEC SQL ifdef name или EXEC SQL ifndef name. Последующие строки будут обработаны, если ни один предыдущий раздел того же конструкта ifdef/ifndef...endif не был обработан.

EXEC SQL endif;

Завершает конструкцию ifdef/ifndef...endif. Последующие строки обрабатываются нормально.

ifdef/ifndef...endif конструкции могут быть вложены друг в друга, до 127 уровней глубины.

Этот пример скомпилирует ровно одну из трех команд SET TIMEZONE:

EXEC SQL ifdef TZVAR;
EXEC SQL SET TIMEZONE TO TZVAR;
EXEC SQL elif TZNAME;
EXEC SQL SET TIMEZONE TO TZNAME;
EXEC SQL else;
EXEC SQL SET TIMEZONE TO 'GMT';
EXEC SQL endif;