×
Мы обрабатываем cookies, чтобы сделать наш сайт удобнее и персонализированнее для вас. Подробнее: политика использования «cookies» и «политики конфиденциальности».

Для самостоятельной настройки ознакомьтесь с инструкцией

Дополнительные настройки cookies в браузерах

Файлы cookie автоматически загружаются в ваш браузер при посещении веб-сайта. У вас есть возможность управлять этими файлами. Если Вы не согласны с использованием файлов cookies, запретите их сохранение на своём устройстве, удалите уже имеющиеся файлы cookies через настройки браузера или прекратите использование сайта.

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

Инструкция по отключению cookies
Принять
Настроить
Отклонить

ДОКУМЕНТАЦИЯ

Выберите версию, форк и язык для СУБД Digital Q.DataBase, чтобы прочитать или скачать всю документацию.
Техподдержка
Документация
Диасофт
Авторские права © 2016–2025 ООО "Диасофт Экосистема"
Скачать всю документацию:

4.3.7. Использование областей дескрипторов

4.3.7.1. Именованные области дескрипторов SQL
4.3.7.2. Области дескрипторов SQLDA

Область дескрипторов SQL представляет собой более совершенный метод обработки результата выполнения оператора SELECT, FETCH или оператора DESCRIBE statement. Область дескрипторов SQL группирует данные одной строки вместе с метаданными в единую структуру данных. Метаданные особенно полезны при выполнении динамических операторов SQL, когда структура результирующих столбцов может быть неизвестна заранее. PostgreSQL предоставляет два способа использования областей дескрипторов (Descriptor Areas): именованные области дескрипторов SQL и структуры SQLDA на языке C.

4.3.7.1. Именованные области дескрипторов SQL #

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

Перед использованием области дескрипторов SQL ее необходимо инициализировать (выделить память):

EXEC SQL ALLOCATE DESCRIPTOR идентификатор;

Данный идентификатор служит в качестве «имени переменной» области дескриптора. Когда дескриптор больше не требуется, его следует удалить:

EXEC SQL DEALLOCATE DESCRIPTOR идентификатор;

Чтобы использовать область дескриптора, укажите её в качестве цели сохранения данных в предложение INTO предложении, вместо перечисления главных переменных:

EXEC SQL FETCH NEXT FROM mycursor INTO SQL DESCRIPTOR mydesc;

Если результирующий набор пуст, область дескриптора всё равно будет содержать метаданные запроса, то есть имена полей.

Для еще не выполненных подготовленных запросов DESCRIBE оператор может быть использован для получения метаданных результирующего набора:

EXEC SQL BEGIN DECLARE SECTION;
char *sql_stmt = "SELECT * FROM table1";
EXEC SQL END DECLARE SECTION;

EXEC SQL PREPARE stmt1 FROM :sql_stmt;
EXEC SQL DESCRIBE stmt1 INTO SQL DESCRIPTOR mydesc;

До версии PostgreSQL 9.0 ключевое слово SQL было необязательным, поэтому использование DESCRIPTOR и SQL DESCRIPTOR создавало именованные области дескрипторов SQL. Теперь оно является обязательным; пропуск этого ключевого слова SQL приводит к созданию областей дескрипторов SQLDA, см. Раздел 4.3.7.2.

В DESCRIBE и FETCH операторах ключевые слова предложение INTO и USING могут использоваться аналогичным образом: они помещают результирующий набор и метаданные в область дескриптора.

Как же извлечь данные из области дескриптора? Область дескриптора можно представить как структуру с именованными полями. Для получения значения поля из заголовка и его сохранения в главной переменной используйте следующую команду:

EXEC SQL GET DESCRIPTOR имя :hostvar = field;

В настоящее время определено только одно поле заголовка: COUNT, которое указывает количество существующих областей дескрипторов элементов (то есть количество столбцов в полученном результате). Главная переменная должна иметь целочисленный тип. Для получения значения поля из области дескрипторов элементов используйте следующую команду:

EXEC SQL GET DESCRIPTOR имя VALUE num :hostvar = field;

num может представлять собой целочисленный литерал или главную переменную, содержащую целое число. Доступные поля:

CARDINALITY (целое число) #

количество строк в результирующем наборе

DATA #

фактический элемент данных (следовательно, тип данных этого поля зависит от запроса)

DATETIME_INTERVAL_CODE (целое число) #

Когда TYPE имеет значение 9, DATETIME_INTERVAL_CODE будет иметь значение 1 для DATE, 2 для TIME, 3 для TIMESTAMP, 4 для TIME WITH TIME ZONE, или 5 для TIMESTAMP WITH TIME ZONE.

DATETIME_INTERVAL_PRECISION (целое число) #

не реализовано

INDICATOR (целое число) #

индикатор (указывающий на значение NULL или усечение значения)

KEY_MEMBER (целое число) #

не реализовано

LENGTH (целое число) #

длина данных в символах

NAME (строка) #

имя столбца

NULLABLE (целое число) #

не реализовано

OCTET_LENGTH (целое число) #

длина символьного представления данных в байтах

PRECISION (целое число) #

точность (для типа тип numeric)

RETURNED_LENGTH (целое число) #

длина данных в символах

RETURNED_OCTET_LENGTH (целое число) #

длина символьного представления данных в байтах

SCALE (целое число) #

масштаб (для типа тип numeric)

TYPE (целое число) #

числовой код типа данных столбца

В EXECUTE, DECLARE и OPEN инструкций, эффект предложение INTO и USING ключевые слова различаются. Область дескрипторов также может быть создана вручную для передачи входных параметров в запрос или курсор, и USING SQL DESCRIPTOR имя — это способ передачи входных параметров в параметризованный запрос. Оператор для создания именованной области дескрипторов SQL приведен ниже:

EXEC SQL SET DESCRIPTOR имя VALUE num field = :hostvar;

PostgreSQL поддерживает извлечение нескольких записей с помощью одной FETCH команды; в этом случае сохранение данных в главные переменные предполагает, что переменная является массивом. Например:

EXEC SQL BEGIN DECLARE SECTION;
int id[5];
EXEC SQL END DECLARE SECTION;

EXEC SQL FETCH 5 FROM mycursor INTO SQL DESCRIPTOR mydesc;

EXEC SQL GET DESCRIPTOR mydesc VALUE 1 :id = DATA;

4.3.7.2. Области дескрипторов SQLDA #

Область дескрипторов SQLDA представляет собой структуру на языке C, которую также можно использовать для получения результирующего набора и метаданных запроса. Одна структура хранит одну запись из набора результатов.

EXEC SQL include sqlda.h;
sqlda_t         *mysqlda;

команда EXEC SQL FETCH 3 предложение FROM mycursor предложение INTO DESCRIPTOR mysqlda;

Обратите внимание, что SQL ключевое слово опущено. Абзацы, описывающие варианты использования предложение INTO и USING ключевых слов в Раздел 4.3.7.1 также применимы здесь с одним дополнением. В DESCRIBE операторе DESCRIPTOR ключевое слово может быть полностью опущено, если используется предложение INTO ключевое слово:

команда EXEC SQL DESCRIBE prepared_statement предложение INTO mysqlda;

Общий алгоритм работы программы, использующей SQLDA, следующий:

  1. Подготовка запроса и объявление курсора для него.

  2. Объявление структуры SQLDA для строк результата.

  3. Объявление структуры SQLDA для входных параметров и их инициализация (выделение памяти, настройка параметров).

  4. Открытие курсора оператором OPEN с использованием входной структуры SQLDA.

  5. Извлечение строк из курсора и их сохранение в выходную структуру SQLDA.

  6. Чтение значений из выходной структуры SQLDA в главные переменные (с преобразованием при необходимости).

  7. Закрыть курсор.

  8. Освободить область памяти, выделенную для входной структуры SQLDA.

4.3.7.2.1. Структура данных SQLDA #

SQLDA использует три типа структур данных: sqlda_t, sqlvar_t, и struct sqlname.

Подсказка

SQLDA в PostgreSQL имеет структуру данных, аналогичную используемой в IBM DB2 Universal Database, поэтому техническая информация о SQLDA в DB2 может помочь лучше понять реализацию SQLDA в PostgreSQL.

4.3.7.2.1.1. Структура sqlda_t #

Тип структуры sqlda_t является типом фактической структуры SQLDA. Она содержит одну запись. При этом две или более sqlda_t структуры могут быть объединены в связный список с помощью указателя в desc_next поле, представляя, таким образом, упорядоченную коллекцию строк. Таким образом, при выборке двух или более строк приложение может прочитать их, следуя по desc_next указателю в каждом sqlda_t узле.

Определение sqlda_t следующее:

struct sqlda_struct
{
    char            sqldaid[8];
    long            sqldabc;
    short           sqln;
    short           sqld;
    struct sqlda_struct *desc_next;
    struct sqlvar_struct sqlvar[1];
};

typedef struct sqlda_struct sqlda_t;

Значения полей следующие:

sqldaid #

Поле содержит строковый литерал "SQLDA ".

sqldabc #

Поле содержит размер выделенной области памяти в байтах.

sqln #

Поле содержит количество входных параметров для параметризованного запроса в случае передачи в OPEN, DECLARE или EXECUTE операторы, использующие USING ключевое слово. В случае использования в качестве выходных данных для SELECT, EXECUTE или FETCH операторы, его значение совпадает со значением sqld оператор

sqld #

Данный параметр содержит количество полей в результирующем наборе.

desc_next #

Если запрос возвращает более одной записи, возвращается несколько связанных структур SQLDA, а поле desc_next содержит указатель на следующий элемент в списке.

sqlvar #

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

4.3.7.2.1.2. Структура sqlvar_t #

Тип структуры sqlvar_t содержит значение столбца и метаданные, такие как тип и длина. Определение данного типа выглядит следующим образом:

struct sqlvar_struct
{
    short          sqltype;
    short          sqllen;
    тип данных char          *sqldata;
    short         *sqlind;
    struct sqlname sqlname;
};

typedef struct sqlvar_struct sqlvar_t;

Поля имеют следующее значение:

sqltype #

Содержит идентификатор типа поля. Список значений см. в перечислении ECPGttype в ecpgtype.h.

sqllen #

Содержит бинарную длину поля, например, 4 байта для ECPGt_int.

sqldata #

Указывает на данные. Формат данных описан в в Раздел 4.3.4.4.

sqlind #

Указывает на индикатор null. Значение 0 означает NOT NULL, -1 означает NULL.

sqlname #

Имя поля.

4.3.7.2.1.3. Структура struct sqlname #

A struct sqlname структура содержит имя столбца. Она используется как член sqlvar_t структуры. Определение структуры следующее:

#define NAMEDATALEN 64

struct sqlname
{
        short           length;
        тип данных char            data[NAMEDATALEN];
};

Описание полей:

length #

Содержит длину имени поля.

data #

Содержит фактическое имя поля.

4.3.7.2.2. Получение набора результатов с использованием SQLDA #

Основные этапы получения набора результатов запроса через SQLDA:

  1. Объявите параметр sqlda_t структура для получения результирующего набора.

  2. Оператор EXECUTE FETCH/EXECUTE/DESCRIBE команды для обработки запроса с указанием объявленной структуры SQLDA.

  3. Проверьте количество записей в результирующем наборе, обратившись к полю sqln, являющемуся членом структуры sqlda_t структура.

  4. Получите значения каждого столбца из полей sqlvar[0], sqlvar[1]и последующих, являющихся членами структуры sqlda_t структура.

  5. Перейдите к следующей строке (sqlda_t структура), следуя по указателю desc_next pointer, члену структуры sqlda_t структура.

  6. Повторяйте вышеописанные действия по мере необходимости.

Ниже приведен пример получения результирующего набора с использованием структуры SQLDA.

Сначала объявите переменную типа sqlda_t структура для получения результирующего набора.

sqlda_t *sqlda1;

Затем укажите структуру SQLDA в операторе. Это FETCH пример команды.

команда EXEC SQL FETCH NEXT FROM предложение FROM имя курсора cur1 предложение INTO DESCRIPTOR sqlda1;

Запустите цикл по связанному списку для извлечения строк.

sqlda_t *cur_sqlda;

for (cur_sqlda = sqlda1;
     cur_sqlda != NULL;
     cur_sqlda = cur_sqlda->desc_next)
{
    ...
}

Внутри цикла запустите еще один цикл для извлечения данных каждого столбца (sqlvar_t структуры) строки.

for (i = 0; i < cur_sqlda->sqld; i++)
{
    sqlvar_t v = cur_sqlda->sqlvar[i];
    тип данных char *sqldata = v.sqldata;
    short sqllen  = v.sqllen;
    ...
}

Чтобы получить значение столбца, проверьте sqltype значение, являющееся членом sqlvar_t структуры. Затем выберите подходящий способ, в зависимости от типа столбца, для копирования данных из sqlvar поле в главную переменную.

char var_buf[1024];

switch (v.sqltype)
{
    case ECPGt_char:
        memset(&var_buf, 0, sizeof(var_buf));
        memcpy(&var_buf, sqldata, (sizeof(var_buf) <= sqllen ? sizeof(var_buf) - 1 : sqllen));
        break;

    case ECPGt_int: /* integer */
        memcpy(&intval, sqldata, sqllen);
        snprintf(var_buf, sizeof(var_buf), "%d", intval);
        break;

    ...
}

4.3.7.2.3. Передача параметров запроса с использованием структуры SQLDA #

Основные этапы использования структуры SQLDA для передачи входных параметров в подготовленный запрос:

  1. Создание подготовленного запроса (подготовленного оператора)

  2. Объявление структуры sqlda_t в качестве входной структуры SQLDA.

  3. Выделение области памяти (как структуры sqlda_t) для входной структуры SQLDA.

  4. Задание (копирование) входных значений в выделенной области памяти.

  5. Открытие курсора с указанием входной структуры SQLDA.

Ниже приведен пример.

Сначала создайте подготовленный оператор.

EXEC SQL BEGIN DECLARE SECTION;
char query[1024] = "SELECT d.oid, * FROM pg_database d, pg_stat_database s WHERE d.oid = s.datid AND (d.datname = ? OR d.oid = ?)";
EXEC SQL END DECLARE SECTION;

EXEC SQL PREPARE stmt1 FROM :query;

Затем выделите память для структуры SQLDA и установите количество входных параметров в поле sqln, являющемся переменной-членом структуры sqlda_t структуры. Если для подготовленного запроса требуется два или более входных параметра, приложение должно выделить дополнительный объем памяти, который рассчитывается по формуле: (количество параметров - 1) * sizeof(sqlvar_t). В данном примере выделяется объем памяти, необходимый для двух входных параметров.

sqlda_t *sqlda2;

sqlda2 = (sqlda_t *) malloc(sizeof(sqlda_t) + sizeof(sqlvar_t));
memset(sqlda2, 0, sizeof(sqlda_t) + sizeof(sqlvar_t));

sqlda2->sqln = 2; /* количество входных переменных */

После выделения памяти сохраните значения параметров в sqlvar[] массиве. (Этот же массив используется для извлечения значений столбцов, когда структура SQLDA принимает результирующий набор.) В данном примере входными параметрами являются "postgres", имеющий строковый тип, и 1, имеющий целочисленный тип.

sqlda2->sqlvar[0].sqltype = ECPGt_char;
sqlda2->sqlvar[0].sqldata = "postgres";
sqlda2->sqlvar[0].sqllen  = 8;

int intval = 1;
sqlda2->sqlvar[1].sqltype = ECPGt_int;
sqlda2->sqlvar[1].sqldata = (char *) &intval;
sqlda2->sqlvar[1].sqllen  = sizeof(intval);

При открытии курсора и указании предварительно настроенной структуры SQLDA входные параметры передаются в подготовленный оператор.

команда EXEC SQL OPEN имя курсора cur1 USING DESCRIPTOR sqlda2;

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

free(sqlda2);

4.3.7.2.4. Пример приложения, использующего структуру SQLDA #

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

Данное приложение объединяет две системные таблицы — системный каталог pg_database и системную таблицу pg_stat_database по значению тип oid базы данных, а также получает и отображает статистику базы данных, извлеченную по двум входным параметрам (база данных postgres, и тип oid 1).

Сначала объявите структуру SQLDA для ввода и структуру SQLDA для вывода.

EXEC SQL include sqlda.h;

sqlda_t *sqlda1; /* дескриптор вывода */
sqlda_t *sqlda2; /* дескриптор ввода  */

Далее установите соединение с базой данных, подготовьте оператор и объявите курсор для подготовленного оператора.

int
main(void)
{
    оператор EXEC SQL BEGIN DECLARE SECTION;
    тип данных char query[1024] = "SELECT d.oid,* FROM pg_database d, pg_stat_database s WHERE d.oid=s.datid AND ( d.datname=? OR d.oid=? )";
    оператор EXEC SQL END DECLARE SECTION;

    оператор EXEC SQL CONNECT TO testdb AS имя соединения con1 USER testuser;
    оператор EXEC SQL SELECT функция pg_catalog.set_config('search_path', '', false); оператор EXEC SQL COMMIT;

    EXEC SQL PREPARE stmt1 предложение FROM :query;
    EXEC SQL DECLARE имя курсора cur1 CURSOR FOR stmt1;

Затем поместите значения во входную структуру SQLDA для входных параметров. Выделите память для входной структуры SQLDA и установите количество входных параметров в значение sqln. Сохраните тип, значение и длину значения в предложение sqltype, sqldata, а также sqllen в sqlvar структуре.

    /* Создание структуры SQLDA для входных параметров. */
    sqlda2 = (sqlda_t *) malloc(sizeof(sqlda_t) + sizeof(sqlvar_t));
    функция memset(sqlda2, 0, sizeof(sqlda_t) + sizeof(sqlvar_t));
    sqlda2->sqln = 2; /* число входных переменных */

    sqlda2->sqlvar[0].sqltype = ECPGt_char;
    sqlda2->sqlvar[0].sqldata = "postgres";
    sqlda2->sqlvar[0].sqllen  = 8;

    intval = 1;
    sqlda2->sqlvar[1].sqltype = ECPGt_int;
    sqlda2->sqlvar[1].sqldata = (char *)&intval;
    sqlda2->sqlvar[1].sqllen  = sizeof(intval);

После настройки входной структуры SQLDA откройте курсор с использованием данной структуры SQLDA.

    /* Открытие курсора с входными параметрами. */
    EXEC SQL OPEN cur1 USING DESCRIPTOR sqlda2;

Выполните выборку строк в выходную структуру SQLDA из открытого курсора. (Как правило, необходимо выполнять вызов FETCH повторно в цикле, чтобы извлечь все строки из результирующего набора.)

    while (1)
    {
        sqlda_t *cur_sqlda;

        /* Назначение дескриптора курсору */
        EXEC SQL FETCH NEXT FROM cur1 INTO DESCRIPTOR sqlda1;

Затем извлеките полученные записи из структуры SQLDA, следуя по связанному списку sqlda_t структуры.

    for (cur_sqlda = sqlda1 ;
         cur_sqlda != NULL ;
         cur_sqlda = cur_sqlda->desc_next)
    {
        ...

Считайте каждый столбец в первой записи. Количество столбцов хранится в sqld, а фактические данные первого столбца хранятся в sqlvar[0], оба элемента структуры sqlda_t структуре.

        /* Вывод каждого столбца в строке. */
        for (i = 0; i < sqlda1->sqld; i++)
        {
            sqlvar_t v = sqlda1->sqlvar[i];
            char *sqldata = v.sqldata;
            short sqllen  = v.sqllen;

            strncpy(name_buf, v.sqlname.data, v.sqlname.length);
            name_buf[v.sqlname.length] = '\0';

Теперь данные столбца сохранены в переменной v. Скопируйте все данные в главные переменные, проверяя v.sqltype для определения типа столбца.

            switch (v.sqltype) {
                int intval;
                double doubleval;
                unsigned long long int longlongval;

                case ECPGt_char:
                    memset(&var_buf, 0, sizeof(var_buf));
                    memcpy(&var_buf, sqldata, (sizeof(var_buf) <= sqllen ? sizeof(var_buf)-1 : sqllen));
                    break;

                case ECPGt_int: /* integer */
                    memcpy(&intval, sqldata, sqllen);
                    snprintf(var_buf, sizeof(var_buf), "%d", intval);
                    break;

                ...

                default:
                    ...
            }

            printf("%s = %s (type: %d)\n", name_buf, var_buf, v.sqltype);
        }

Закройте курсор после обработки всех записей и отключитесь от базы данных.

    EXEC SQL CLOSE cur1;
    EXEC SQL COMMIT;

    EXEC SQL DISCONNECT ALL;

Полный текст программы приведён в Пример 4.3.1.

Пример 4.3.1. Пример программы с использованием SQLDA

#include 
#include 
#include 
#include 
#include 

EXEC SQL include sqlda.h;

sqlda_t *sqlda1; /* дескриптор для вывода */
sqlda_t *sqlda2; /* дескриптор для ввода */

EXEC SQL WHENEVER NOT FOUND DO BREAK;
EXEC SQL WHENEVER SQLERROR STOP;

int
main(void)
{
    оператор EXEC SQL BEGIN DECLARE SECTION;
    тип данных char query[1024] = "SELECT d.oid,* FROM pg_database d, pg_stat_database s WHERE d.oid=s.datid AND ( d.datname=? OR d.oid=? )";

    int intval;
    unsigned long long int longlongval;
    оператор EXEC SQL END DECLARE SECTION;

    оператор EXEC SQL CONNECT TO uptimedb AS con1 USER uptime;
    оператор EXEC SQL SELECT функция pg_catalog.set_config('search_path', '', false); оператор COMMIT;

    EXEC SQL PREPARE stmt1 предложение FROM :query;
    EXEC SQL DECLARE cur1 CURSOR FOR stmt1;

    /* Создание структуры SQLDA для входного параметра */
    sqlda2 = (sqlda_t *)malloc(sizeof(sqlda_t) + sizeof(sqlvar_t));
    функция memset(sqlda2, 0, sizeof(sqlda_t) + sizeof(sqlvar_t));
    sqlda2->sqln = 2; /* количество входных переменных */

    sqlda2->sqlvar[0].sqltype = ECPGt_char;
    sqlda2->sqlvar[0].sqldata = "postgres";
    sqlda2->sqlvar[0].sqllen  = 8;

    intval = 1;
    sqlda2->sqlvar[1].sqltype = ECPGt_int;
    sqlda2->sqlvar[1].sqldata = (char *) &intval;
    sqlda2->sqlvar[1].sqllen  = sizeof(intval);

    /* Открытие курсора с входными параметрами. */
    EXEC SQL OPEN cur1 USING DESCRIPTOR sqlda2;

    while (1)
    {
        sqlda_t *cur_sqlda;

        /* Назначение дескриптора курсору */
        EXEC SQL FETCH NEXT FROM cur1 INTO DESCRIPTOR sqlda1;

        for (cur_sqlda = sqlda1 ;
             cur_sqlda != NULL ;
             cur_sqlda = cur_sqlda->desc_next)
        {
            int i;
            char name_buf[1024];
            char var_buf[1024];

            /* Вывод каждого столбца в строке. */
            for (i=0 ; isqld ; i++)
            {
                sqlvar_t v = cur_sqlda->sqlvar[i];
                char *sqldata = v.sqldata;
                short sqllen  = v.sqllen;

                strncpy(name_buf, v.sqlname.data, v.sqlname.length);
                name_buf[v.sqlname.length] = '\0';

                switch (v.sqltype)
                {
                    case ECPGt_char:
                        memset(&var_buf, 0, sizeof(var_buf));
                        memcpy(&var_buf, sqldata, (sizeof(var_buf)<=sqllen ? sizeof(var_buf)-1 : sqllen) );
                        break;

                    case ECPGt_int: /* integer */
                        memcpy(&intval, sqldata, sqllen);
                        snprintf(var_buf, sizeof(var_buf), "%d", intval);
                        break;

                    case ECPGt_long_long: /* bigint */
                        memcpy(&longlongval, sqldata, sqllen);
                        snprintf(var_buf, sizeof(var_buf), "%lld", longlongval);
                        break;

                    default:
                    {
                        int i;
                        memset(var_buf, 0, sizeof(var_buf));
                        for (i = 0; i < sqllen; i++)
                        {
                            char tmpbuf[16];
                            snprintf(tmpbuf, sizeof(tmpbuf), "%02x ", (unsigned char) sqldata[i]);
                            strncat(var_buf, tmpbuf, sizeof(var_buf));
                        }
                    }
                        break;
                }

                printf("%s = %s (type: %d)\n", name_buf, var_buf, v.sqltype);
            }

            printf("\n");
        }
    }

    EXEC SQL CLOSE cur1;
    EXEC SQL COMMIT;

    EXEC SQL DISCONNECT ALL;

    return 0;
}

Результат выполнения данного примера должен выглядеть примерно следующим образом (некоторые значения могут отличаться).

oid = 1 (type: 1)
datname = template1 (type: 1)
datdba = 10 (type: 1)
encoding = 0 (type: 5)
datistemplate = t (type: 1)
datallowconn = t (type: 1)
dathasloginevt = f (type: 1)
datconnlimit = -1 (type: 5)
datfrozenxid = 379 (type: 1)
dattablespace = 1663 (type: 1)
datconfig =  (type: 1)
datacl = {=c/uptime,uptime=CTc/uptime} (type: 1)
datid = 1 (type: 1)
datname = template1 (type: 1)
numbackends = 0 (type: 5)
xact_commit = 113606 (type: 9)
xact_rollback = 0 (type: 9)
blks_read = 130 (type: 9)
blks_hit = 7341714 (type: 9)
tup_returned = 38262679 (type: 9)
tup_fetched = 1836281 (type: 9)
tup_inserted = 0 (type: 9)
tup_updated = 0 (type: 9)
tup_deleted = 0 (type: 9)

oid = 11511 (type: 1)
datname = postgres (type: 1)
datdba = 10 (type: 1)
encoding = 0 (type: 5)
datistemplate = f (type: 1)
datallowconn = t (type: 1)
dathasloginevt = f (type: 1)
datconnlimit = -1 (type: 5)
datfrozenxid = 379 (type: 1)
dattablespace = 1663 (type: 1)
datconfig =  (type: 1)
datacl =  (type: 1)
datid = 11511 (type: 1)
имя базы данных datname = postgres (type: 1)
numbackends = 0 (type: 5)
xact_commit = 221069 (type: 9)
xact_rollback = 18 (type: 9)
blks_read = 1176 (type: 9)
blks_hit = 13943750 (type: 9)
tup_returned = 77410091 (type: 9)
tup_fetched = 3253694 (type: 9)
tup_inserted = 0 (type: 9)
tup_updated = 0 (type: 9)
tup_deleted = 0 (type: 9)

Наверх
свяжитесь
с нами
контакты
Для прямой связи с нами вы можете использовать контакты ниже, либо оставить заявку через форму обратной связи, и мы обязательно свяжемся с вами

*поля обязательные к заполнению