36.15. Режим совместимости с Informix #
Препроцессор ecpg
может работать в так называемом режиме совместимости с Informix. Если этот режим включён, ecpg
старается работать как предкомпилятор Informix для кода Informix E/SQL. Вообще говоря, это позволяет записывать встраиваемые команды SQL, используя знак доллара вместо слов EXEC SQL
:
$int j = 3; $CONNECT TO :dbname; $CREATE TABLE test(i INT PRIMARY KEY, j INT); $INSERT INTO test(i, j) VALUES (7, :j); $COMMIT;
Примечание
Между $
и последующей директивой препроцессора (в частности, include
, define
, ifdef
и т. п.) не должно быть пробельных символов. В противном случае препроцессор воспримет следующее слово как имя переменной среды.
Поддерживаются два режима совместимости: INFORMIX
и INFORMIX_SE
При компоновке программ, использующих этот режим совместимости, обязательно подключите библиотеку libcompat
, поставляемую с ECPG.
Помимо ранее упомянутого синтаксического сахара, режим совместимости с Informix приносит из E/SQL в ECPG набор функций для ввода, вывода и преобразования данных, а также встраиваемые операторы SQL.
Режим совместимости с Informix тесно связан с библиотекой pgtypeslib из ECPG. Библиотека pgtypeslib сопоставляет типы данных SQL с типами данных в ведущей программе на C, а большинство дополнительных функций режима совместимости с Informix позволяют работать с этими типами C. Заметьте, однако, что степень совместимости ограничена. ECPG не пытается копировать поведение Informix; вы можете выполнять примерно те же операции и пользоваться функции с теми же именами и с тем же поведением, но если вы используете Informix, просто заменить одно средство другим на данный момент нельзя. Более того, есть различия и в типах данных. В частности, типы даты и интервала в Postgres Pro не воспринимают диапазоны, как например, YEAR TO MINUTE
, так что и в ECPG это не будет поддерживаться.
36.15.1. Дополнительные типы #
Теперь в режиме Informix без указания typedef
поддерживается специальный псевдотип Informix "string" для хранения символьной строки, обрезаемой справа. На самом деле, в режиме Informix ECPG откажется обрабатывать исходные файлы, содержащие определение типа typedef некоторый_тип string;
EXEC SQL BEGIN DECLARE SECTION; string userid; /* эта переменная будет содержать обрезанные данные */ EXEC SQL END DECLARE SECTION; EXEC SQL FETCH MYCUR INTO :userid;
36.15.2. Дополнительные/недостающие операторы встраиваемого SQL #
CLOSE DATABASE
#Этот оператор закрывает текущее подключение. Фактически это синоним команды
DISCONNECT CURRENT
в ECPG:$CLOSE DATABASE; /* закрыть текущее подключение */ EXEC SQL CLOSE DATABASE;
FREE имя_курсора
#Из-за различий в подходах ECPG и ESQL/C Informix (а именно другого разделения на чисто грамматические преобразования и вызовы нижележащей библиотеки времени выполнения) в ECPG нет оператора
FREE имя_курсора
. Это связано с тем, что в ECPG командаDECLARE CURSOR
не сводится к вызову функции в библиотеке времени выполнения, которая бы принимала имя курсора. Это значит, что курсоры SQL в библиотеке ECPG не требуют обслуживания, оно требуется только на уровне сервера Postgres Pro.FREE имя_оператора
#Команда
FREE имя_оператора
является синонимом командыDEALLOCATE PREPARE имя_оператора
.
36.15.3. Области дескрипторов SQLDA, совместимые с Informix #
Режим совместимости с Informix поддерживает структуру, отличную от описанной в Подразделе 36.7.2. См. ниже:
struct sqlvar_compat { short sqltype; int sqllen; char *sqldata; short *sqlind; char *sqlname; char *sqlformat; short sqlitype; short sqlilen; char *sqlidata; int sqlxid; char *sqltypename; short sqltypelen; short sqlownerlen; short sqlsourcetype; char *sqlownername; int sqlsourceid; char *sqlilongdata; int sqlflags; void *sqlreserved; }; struct sqlda_compat { short sqld; struct sqlvar_compat *sqlvar; char desc_name[19]; short desc_occ; struct sqlda_compat *desc_next; void *reserved; }; typedef struct sqlvar_compat sqlvar_t; typedef struct sqlda_compat sqlda_t;
Глобальные свойства:
sqld
#Число полей в дескрипторе
SQLDA
.sqlvar
#Указатель на свойства по полям.
desc_name
#Не используется, заполняется нулями.
desc_occ
#Размер структуры в памяти.
desc_next
#Указатель на следующую структуру SQLDA, если набор результатов содержит больше одной записи.
reserved
#Неиспользуемый указатель, содержит NULL. Сохраняется для совместимости с Informix.
Свойства, относящиеся к полям, описаны ниже, они хранятся в массиве sqlvar
:
sqltype
#Тип поля. Соответствующие константы представлены в
sqltypes.h
sqllen
#Длина данных поля.
sqldata
#Указатель на данные поля. Этот указатель имеет тип
char *
, но он указывает на данные в двоичном формате. Например:int intval; switch (sqldata->sqlvar[i].sqltype) { case SQLINTEGER: intval = *(int *)sqldata->sqlvar[i].sqldata; break; ... }
sqlind
#Указатель на индикатор NULL. Если возвращается командами DESCRIBE или FETCH, это всегда действительный указатель. Если передаётся на вход команде
EXECUTE ... USING sqlda;
, NULL вместо указателя означает, что значение этого поля отлично от NULL. Чтобы обозначить NULL в поле, необходимо корректно установить этот указатель иsqlitype
. Например:if (*(int2 *)sqldata->sqlvar[i].sqlind != 0) printf("value is NULL\n");
sqlname
#Имя поля, в виде строки с завершающим 0.
sqlformat
#Зарезервировано в Informix, значение
PQfformat
для данного поля.sqlitype
#Тип данных индикатора NULL. При получении данных с сервера это всегда SQLSMINT. Когда
SQLDA
используется в параметризованном запросе, данные индикатора обрабатываются в соответствии с указанным здесь типом.sqlilen
#Длина данных индикатора NULL.
sqlxid
#Расширенный тип поля, результат функции
PQftype
.sqltypename
sqltypelen
sqlownerlen
sqlsourcetype
sqlownername
sqlsourceid
sqlflags
sqlreserved
#Не используются.
sqlilongdata
#Совпадает с
sqldata
, еслиsqllen
превышает 32 Кбайта.
Например:
EXEC SQL INCLUDE sqlda.h; sqlda_t *sqlda; /* Это объявление не обязательно должно быть внутри DECLARE SECTION */ EXEC SQL BEGIN DECLARE SECTION; char *prep_stmt = "select * from table1"; int i; EXEC SQL END DECLARE SECTION; ... EXEC SQL PREPARE mystmt FROM :prep_stmt; EXEC SQL DESCRIBE mystmt INTO sqlda; printf("# of fields: %d\n", sqlda->sqld); for (i = 0; i < sqlda->sqld; i++) printf("field %d: \"%s\"\n", sqlda->sqlvar[i]->sqlname); EXEC SQL DECLARE mycursor CURSOR FOR mystmt; EXEC SQL OPEN mycursor; EXEC SQL WHENEVER NOT FOUND GOTO out; while (1) { EXEC SQL FETCH mycursor USING sqlda; } EXEC SQL CLOSE mycursor; free(sqlda); /* Освобождать нужно только основную структуру, * sqlda и sqlda->sqlvar находятся в одной выделенной области. */
36.15.4. Дополнительные функции #
decadd
#Складывает два значения типа decimal.
int decadd(decimal *arg1, decimal *arg2, decimal *sum);
Эта функция получает указатель на первый операнд типа decimal (
arg1
), указатель на второй операнд типа decimal (arg2
) и указатель на переменную типа decimal, в которую будет записана сумма (sum
). В случае успеха эта функция возвращает 0.ECPG_INFORMIX_NUM_OVERFLOW
возвращается в случае переполнения, аECPG_INFORMIX_NUM_UNDERFLOW
в случае антипереполнения. При любых других ошибках возвращается -1, а вerrno
устанавливается кодerrno
из pgtypeslib.deccmp
#Сравнивает два значения типа decimal.
int deccmp(decimal *arg1, decimal *arg2);
Эта функция получает указатель на первое значение типа decimal (
arg1
), указатель на второе значение типа decimal (arg2
) и возвращает целое, отражающее результат сравнения этих чисел.1, если значение, на которое указывает
arg1
, больше значения, на которое указываетvar2
-1, если значение, на которое указывает
arg1
, меньше значения, на которое указываетarg2
0, если значение, на которое указывает
arg1
, равно значению, на которое указываетarg2
deccopy
#Копирует значение типа decimal.
void deccopy(decimal *src, decimal *target);
Функция принимает в первом аргументе (
src
) указатель на значение decimal, которое должно быть скопировано, а во втором аргументе (target
) принимает указатель на структуру типа decimal для скопированного значения.deccvasc
#Преобразует значение из представления ASCII в тип decimal.
int deccvasc(char *cp, int len, decimal *np);
Эта функция получает указатель на строку, содержащую строковое представление числа, которое нужно преобразовать, (
cp
), а также его длинуlen
. Вnp
передаётся указатель на переменную типа decimal, в которую будет помещён результат преобразования.Допустимыми являются, например следующие форматы:
-2
,.794
,+3.44
,592.49E07
или-32.84e-4
.В случае успеха эта функция возвращает 0. При переполнении или антипереполнении возвращается
ECPG_INFORMIX_NUM_OVERFLOW
илиECPG_INFORMIX_NUM_UNDERFLOW
, соответственно. Если разобрать ASCII-представление не удаётся, возвращаетсяECPG_INFORMIX_BAD_NUMERIC
илиECPG_INFORMIX_BAD_EXPONENT
, если не удаётся разобрать компонент экспоненты.deccvdbl
#Преобразует значение double в значение типа decimal.
int deccvdbl(double dbl, decimal *np);
Данная функция принимает в первом аргументе (
dbl
) переменную типа double, которая должна быть преобразована. Во втором аргументе (np
) она принимает указатель на переменную decimal, в которую будет помещён результат операции.Эта функция возвращает 0 в случае успеха, либо отрицательное значение, если выполнить преобразование не удалось.
deccvint
#Преобразует значение int в значение типа decimal.
int deccvint(int in, decimal *np);
Данная функция принимает в первом аргументе (
in
) переменную типа int, которая должна быть преобразована. Во втором аргументе (np
) она принимает указатель на переменную decimal, в которую будет помещён результат операции.Эта функция возвращает 0 в случае успеха, либо отрицательное значение, если выполнить преобразование не удалось.
deccvlong
#Преобразует значение long в значение типа decimal.
int deccvlong(long lng, decimal *np);
Данная функция принимает в первом аргументе (
lng
) переменную типа long, которая должна быть преобразована. Во втором аргументе (np
) она принимает указатель на переменную decimal, в которую будет помещён результат операции.Эта функция возвращает 0 в случае успеха, либо отрицательное значение, если выполнить преобразование не удалось.
decdiv
#Делит одну переменную типа decimal на другую.
int decdiv(decimal *n1, decimal *n2, decimal *result);
Эта функция получает указатели на переменные (
n1
иn2
) и вычисляет частноеn1
/n2
. Вresult
передаётся указатель на переменную, в которую будет помещён результат операции.В случае успеха возвращается 0, а при ошибке — отрицательное значение. В случае переполнения или антипереполнения данная функция возвращает
ECPG_INFORMIX_NUM_OVERFLOW
илиECPG_INFORMIX_NUM_UNDERFLOW
, соответственно. При попытке деления на ноль возвращаетсяECPG_INFORMIX_DIVIDE_ZERO
.decmul
#Перемножает два значения типа decimal.
int decmul(decimal *n1, decimal *n2, decimal *result);
Эта функция получает указатели на переменные (
n1
иn2
) и вычисляет произведениеn1
*n2
. Вresult
передаётся указатель на переменную, в которую будет помещён результат операции.В случае успеха возвращается 0, а при ошибке — отрицательное значение. В случае переполнения или антипереполнения данная функция возвращает
ECPG_INFORMIX_NUM_OVERFLOW
илиECPG_INFORMIX_NUM_UNDERFLOW
, соответственно.decsub
#Вычитает одно значение типа decimal из другого.
int decsub(decimal *n1, decimal *n2, decimal *result);
Эта функция получает указатели на переменные (
n1
иn2
) и вычисляет разностьn1
-n2
. Вresult
передаётся указатель на переменную, в которую будет помещён результат операции.В случае успеха возвращается 0, а при ошибке — отрицательное значение. В случае переполнения или антипереполнения данная функция возвращает
ECPG_INFORMIX_NUM_OVERFLOW
илиECPG_INFORMIX_NUM_UNDERFLOW
, соответственно.dectoasc
#Преобразует переменную типа decimal в представление ASCII (в строку C char*).
int dectoasc(decimal *np, char *cp, int len, int right)
Эта функция получает указатель на переменную типа decimal (
np
), которая будет преобразована в текстовое представление. Аргументcp
указывает на буфер, в который будет помещён результат операции. Аргументright
определяет, сколько должно выводиться цифр правее десятичной точки. Результат будет округлён до этого числа десятичных цифр. Значениеright
, равное -1, указывает, что выводиться должны все имеющиеся десятичные цифры. Если длина выходного буфера, которую задаётlen
, недостаточна для помещения в него текстового представления, включая завершающий нулевой байт, в буфере сохраняется один знак*
и возвращается -1.Эта функция возвращает -1, если буфер
cp
слишком мал, либоECPG_INFORMIX_OUT_OF_MEMORY
при нехватке памяти.dectodbl
#Преобразует переменную типа decimal в тип double.
int dectodbl(decimal *np, double *dblp);
Эта функция получает указатель (
np
) на значение decimal, которое нужно преобразовать, и указатель (dblp
) на переменную double, в которую будет помещён результат операции.В случае успеха возвращается 0, или отрицательное значение, если выполнить преобразование не удалось.
dectoint
#Преобразует переменную типа decimal в тип integer.
int dectoint(decimal *np, int *ip);
Эта функция получает указатель (
np
) на значение decimal, которое нужно преобразовать, и указатель (ip
) на целочисленную переменную, в которую будет помещён результат операции.В случае успеха возвращается 0, или отрицательное значение, если выполнить преобразование не удалось. В случае переполнения возвращается
ECPG_INFORMIX_NUM_OVERFLOW
.Заметьте, что реализация ECPG отличается от реализации Informix. В Informix целое ограничивается диапазоном -32767 .. 32767, тогда как в ECPG ограничение зависит от архитектуры (
INT_MIN .. INT_MAX
).dectolong
#Преобразует переменную типа decimal в тип long.
int dectolong(decimal *np, long *lngp);
Эта функция получает указатель (
np
) на значение decimal, которое нужно преобразовать, и указатель (lngp
) на переменную типа long, в которую будет помещён результат операции.В случае успеха возвращается 0, или отрицательное значение, если выполнить преобразование не удалось. В случае переполнения возвращается
ECPG_INFORMIX_NUM_OVERFLOW
.Заметьте, что реализация ECPG отличается от реализации Informix. В Informix длинное целое ограничено диапазоном -2 147 483 647 .. 2 147 483 647, тогда как в ECPG ограничение зависит от архитектуры (
-LONG_MAX .. LONG_MAX
).rdatestr
#Преобразует дату в строку C char*.
int rdatestr(date d, char *str);
Эта функция принимает два аргумента. В первом (
d
) передаётся дата, которую нужно преобразовать, а во втором указатель на целевую строку. Результат всегда выводится в форматеyyyy-mm-dd
, так что для этой строки нужно выделить минимум 11 байт (включая завершающий нулевой байт).Эта функция возвращает 0 в случае успеха, а в случае ошибки — отрицательное значение.
Заметьте, что реализация ECPG отличается от реализации Informix. В Informix формат вывода можно изменить переменными окружения, а в ECPG он фиксирован.
rstrdate
#Разбирает текстовое представление даты.
int rstrdate(char *str, date *d);
Эта функция получает текстовое представление (
str
) даты, которую нужно преобразовать, и указатель на переменную типа date (d
). Для данной функции нельзя задать маску формата. Она использует стандартную маску формата Informix, а именно:mm/dd/yyyy
. Внутри эта функция вызываетrdefmtdate
. Таким образом,rstrdate
не будет быстрее, и если у вас есть выбор, используйте функциюrdefmtdate
, которая позволяет явно задать маску формата.Эта функция возвращает те же значения, что и
rdefmtdate
.rtoday
#Выдаёт текущую дату.
void rtoday(date *d);
Эта функция получает указатель на переменную (
d
) типа date, в которую будет записана текущая дата.Внутри эта функция вызывает
PGTYPESdate_today
.rjulmdy
#Извлекает значения дня, месяца и года из переменной типа date.
int rjulmdy(date d, short mdy[3]);
Эта функция получает дату
d
и указатель на 3 коротких целочисленных значенияmdy
. Имя переменной указывает на порядок значений: вmdy[0]
записывается номер месяца, вmdy[1]
— номер дня, а вmdy[2]
— год.В текущем состоянии эта функция всегда возвращает 0.
Внутри эта функция вызывает
PGTYPESdate_julmdy
.rdefmtdate
#Преобразует символьную строку в значение типа date по маске формата.
int rdefmtdate(date *d, char *fmt, char *str);
Эта функция принимает указатель на переменную типа date (
d
), в которую будет помещён результат операции, маску формата для разбора даты (fmt
) и строку C char*, содержащую текстовое представление даты (str
). Ожидается, что текстовое представление будет соответствовать маске формата. Однако это соответствие не обязательно должно быть точным. Данная функция анализирует только порядок элементов и ищет в нём подстрокиyy
илиyyyy
, обозначающие позицию года, подстрокуmm
, обозначающую позицию месяца, иdd
, обозначающую позицию дня.Эта функция возвращает следующие значения:
0 — Функция выполнена успешно.
ECPG_INFORMIX_ENOSHORTDATE
— Дата не содержит разделителей между днём, месяцем и годом. С таким форматом входная строка должна быть длиной ровно 6 или 8 байт, но это не так.ECPG_INFORMIX_ENOTDMY
— Строка формата не определяет корректно последовательный порядок года, месяца и дня.ECPG_INFORMIX_BAD_DAY
— Во входной строке отсутствует корректное указание дня.ECPG_INFORMIX_BAD_MONTH
— Во входной строке отсутствует корректное указание месяца.ECPG_INFORMIX_BAD_YEAR
— Во входной строке отсутствует корректное указание года.
В реализации этой функции вызывается
PGTYPESdate_defmt_asc
. Примеры вводимых строк приведены в таблице в её описании.rfmtdate
#Преобразует переменную типа date в текстовое представление по маске формата.
int rfmtdate(date d, char *fmt, char *str);
Эта функция принимает дату для преобразования (
d
), маску формата (fmt
) и строку, в которую будет помещено текстовое представление даты (str
).В случае успеха возвращается 0, а в случае ошибки — отрицательное значение.
Внутри эта функция вызывает
PGTYPESdate_fmt_asc
, примеры форматов можно найти в её описании.rmdyjul
#Образует значение даты из массива 3 коротких целых, задающих день, месяц и год даты.
int rmdyjul(short mdy[3], date *d);
Эта функция получает в первом аргументе массив из 3 коротких целых (
mdy
), а во втором указатель на переменную типа date, в которую будет помещён результат операции.В настоящее время эта функция всегда возвращает 0.
В реализации этой функции вызывается
PGTYPESdate_mdyjul
.rdayofweek
#Возвращает число, представляющее день недели для заданной даты.
int rdayofweek(date d);
Эта функция принимает в единственном аргументе переменную
d
типа date и возвращает целое число, выражающее день недели для этой даты.0 — Воскресенье
1 — Понедельник
2 — Вторник
3 — Среда
4 — Четверг
5 — Пятница
6 — Суббота
В реализации этой функции вызывается
PGTYPESdate_dayofweek
.dtcurrent
#Получает текущее время.
void dtcurrent(timestamp *ts);
Эта функция получает текущее время и сохраняет его в переменной типа timestamp, на которую указывает
ts
.dtcvasc
#Разбирает время из текстового представления в переменную типа timestamp.
int dtcvasc(char *str, timestamp *ts);
Эта функция получает строку (
str
), которую нужно разобрать, и указатель на переменную типа timestamp, в которую будет помещён результат операции (ts
).Эта функция возвращает 0 в случае успеха, а в случае ошибки — отрицательное значение.
Внутри эта функция вызывает
PGTYPEStimestamp_from_asc
. Примеры вводимых строк приведены в таблице в её описании.dtcvfmtasc
#Разбирает время из текстового представления в переменную типа timestamp по маске формата.
dtcvfmtasc(char *inbuf, char *fmtstr, timestamp *dtvalue)
Эта функция получает строку (
inbuf
), которую нужно разобрать, маску формата (fmtstr
) и указатель на переменную timestamp, в которой будет содержаться результат операции (dtvalue
).В реализации этой функции используется
PGTYPEStimestamp_defmt_asc
. Список допустимых кодов формата приведён в её описании.Эта функция возвращает 0 в случае успеха, а в случае ошибки — отрицательное значение.
dtsub
#Вычитает одно значение времени из другого и возвращает переменную типа interval.
int dtsub(timestamp *ts1, timestamp *ts2, interval *iv);
Эта функция вычитает значение timestamp, на которое указывает
ts2
, из значения timestamp, на которое указываетts1
, и сохраняет результат в переменной типа interval, на которую указываетiv
.В случае успеха возвращается 0, а в случае ошибки — отрицательное значение.
dttoasc
#Преобразует переменную типа timestamp в строку C char*.
int dttoasc(timestamp *ts, char *output);
Эта функция получает указатель (
ts
) на переменную типа timestamp, которую нужно преобразовать, и строку (output
) для сохранения результата операции. Она преобразуетts
в текстовое представление согласно стандарту SQL, то есть по маскеYYYY-MM-DD HH:MM:SS
.В случае успеха возвращается 0, а в случае ошибки — отрицательное значение.
dttofmtasc
#Преобразует переменную типа timestamp в строку C char* по маске формата.
int dttofmtasc(timestamp *ts, char *output, int str_len, char *fmtstr);
Эта функция получает в первом аргументе (
ts
) указатель на переменную типа timestamp, а в последующих указатель на буфер вывода (output
), максимальную длину строки, которую может принять буфер (str_len
), и маску формата, с которой будет выполняться преобразование (fmtstr
).В случае успеха возвращается 0, а в случае ошибки — отрицательное значение.
Внутри эта функция использует
PGTYPEStimestamp_fmt_asc
. Примеры допустимых масок формата можно найти в её описании.intoasc
#Преобразует переменную типа interval в строку C char*.
int intoasc(interval *i, char *str);
Эта функция получает указатель (
i
) на переменную типа interval, которую нужно преобразовать, и строку (str
) для сохранения результата операции. Она преобразуетi
в текстовое представление согласно стандарту SQL, то есть по маскеYYYY-MM-DD HH:MM:SS
.В случае успеха возвращается 0, а в случае ошибки — отрицательное значение.
rfmtlong
#Преобразует длинное целое в текстовое представление по маске формата.
int rfmtlong(long lng_val, char *fmt, char *outbuf);
Эта функция принимает значение типа long (
lng_val
), маску формата (fmt
) и указатель на выходной буфер (outbuf
). Она преобразует длинное целое в его текстовое представление согласно заданной маске формата.Маску формата можно составить из следующих символов, определяющих формат:
*
(звёздочка) — если в данной позиции будет пусто, заполнить её звёздочкой.&
(амперсанд) — если в данной позиции будет пусто, заполнить её нулём.#
— заменить ведущие нули пробелами.<
— выровнять число в строке по левой стороне.,
(запятая) — сгруппировать числа, содержащие четыре и более цифр, в группы по три цифры через запятую..
(точка) — этот символ отделяет целую часть числа от дробной.-
(минус) — с отрицательным числом должен выводиться знак минус.+
(плюс) — с положительным числом должен выводиться знак плюс.(
— это символ заменяет знак минус перед отрицательным числом. Сам знак минус выводиться не будет.)
— этот символ заменяет минус и выводится после отрицательного числа.$
— символ денежной суммы.
rupshift
#Приводит строку к верхнему регистру.
void rupshift(char *str);
Эта функция получает указатель на строку и приводит в ней каждый символ в нижнем регистре к верхнему регистру.
byleng
#Возвращает число символов в строке, не считая завершающих пробелов.
int byleng(char *str, int len);
Эта функция принимает в первом аргументе (
str
) строку фиксированной длины, а во втором (len
) её длину. Она возвращает число значимых символов, то есть длину строки без завершающих пробелов.ldchar
#Копирует строку фиксированной длины в строку с завершающим нулём.
void ldchar(char *src, int len, char *dest);
Эта функция принимает строку фиксированной длины (
src
), которую нужно скопировать, её длину (len
) и указатель на целевой буфер в памяти (dest
). Учтите, что для буфера, на который указываетdest
, необходимо выделить как минимумlen+1
байт. Данная функция копирует в новую область не большеlen
байт (меньше, если в исходной строке есть завершающие пробелы) и добавляет завершающий 0.rgetmsg
#int rgetmsg(int msgnum, char *s, int maxsize);
Эта функция определена, но не реализована на данный момент!
rtypalign
#int rtypalign(int offset, int type);
Эта функция определена, но не реализована на данный момент!
rtypmsize
#int rtypmsize(int type, int len);
Эта функция определена, но не реализована на данный момент!
rtypwidth
#int rtypwidth(int sqltype, int sqllen);
Эта функция определена, но не реализована на данный момент!
rsetnull
#Присваивает переменной NULL.
int rsetnull(int t, char *ptr);
Эта функция получает целое, определяющее тип переменной, и указатель на саму переменную, приведённый к указателю C char*.
Определены следующие типы:
CCHARTYPE
— для переменной типаchar
илиchar*
CSHORTTYPE
— для переменной типаshort int
CINTTYPE
— для переменной типаint
CBOOLTYPE
— для переменной типаboolean
CFLOATTYPE
— для переменной типаfloat
CLONGTYPE
— для переменной типаlong
CDOUBLETYPE
— для переменной типаdouble
CDECIMALTYPE
— для переменной типаdecimal
CDATETYPE
— для переменной типаdate
CDTIMETYPE
— для переменной типаtimestamp
Примеры вызова этой функции:
$char c[] = "abc "; $short s = 17; $int i = -74874; rsetnull(CCHARTYPE, (char *) c); rsetnull(CSHORTTYPE, (char *) &s); rsetnull(CINTTYPE, (char *) &i);
risnull
#Проверяет содержимое переменной на NULL.
int risnull(int t, char *ptr);
Эта функция получает тип проверяемой переменной (
t
), а также указатель на неё (ptr
). Заметьте, что этот указатель нужно привести к char*. Список возможных типов переменных приведён в описании функцииrsetnull
.Примеры использования этой функции:
$char c[] = "abc "; $short s = 17; $int i = -74874; risnull(CCHARTYPE, (char *) c); risnull(CSHORTTYPE, (char *) &s); risnull(CINTTYPE, (char *) &i);
36.15.5. Дополнительные константы #
Заметьте, что все эти константы относятся к ошибкам и все они представлены отрицательными значениями. Из описаний различных констант вы также можете узнать, какими именно числами они представлены в текущей реализации. Однако полагаться на эти числа не следует. Тем не менее вы можете рассчитывать на то, что все эти значения будут отрицательными.
ECPG_INFORMIX_NUM_OVERFLOW
#Функции возвращают это значение, если при вычислении происходит переполнение. Внутри оно представляется числом -1200 (определение Informix).
ECPG_INFORMIX_NUM_UNDERFLOW
#Функции возвращают это значение, если при вычислении происходит антипереполнение. Внутри оно представляется числом -1201 (определение Informix).
ECPG_INFORMIX_DIVIDE_ZERO
#Функции возвращают это значение при попытке деления на ноль. Внутри оно представляется числом -1202 (определение Informix).
ECPG_INFORMIX_BAD_YEAR
#Функции возвращают это значение, если при разборе даты встретилось некорректное указание года. Внутри оно представляется числом -1204 (определение Informix).
ECPG_INFORMIX_BAD_MONTH
#Функции возвращают это значение, если при разборе даты встретилось некорректное указание месяца. Внутри оно представляется числом -1205 (определение Informix).
ECPG_INFORMIX_BAD_DAY
#Функции возвращают это значение, если при разборе даты встретилось некорректное указание дня. Внутри оно представляется числом -1206 (определение Informix).
ECPG_INFORMIX_ENOSHORTDATE
#Функции возвращают это значение, если процедуре разбора даты требуется короткая запись даты, но строка даты имеет неподходящую длину. Внутри оно представляется числом -1209 (определение Informix).
ECPG_INFORMIX_DATE_CONVERT
#Функции возвращают это значение, если при форматировании даты происходит ошибка. Внутри оно представляется числом -1210 (определение Informix).
ECPG_INFORMIX_OUT_OF_MEMORY
#Функции возвращают это значение, если им не хватает памяти для выполнения операций. Внутри оно представляется числом -1211 (определение Informix).
ECPG_INFORMIX_ENOTDMY
#Функции возвращают это значение, если процедура разбора должна была получить маску формата (например,
mmddyy
), но не все поля были записаны правильно. Внутри оно представляется числом -1212 (определение Informix).ECPG_INFORMIX_BAD_NUMERIC
#Функции возвращают это значение, если процедура разбора не может получить числовое значение из текстового представления, потому что оно некорректно, либо если процедура вычисления не может произвести операцию с числовыми переменными из-за недопустимого значения минимум одной из этих переменных. Внутри оно представляется числом -1213 (определение Informix).
ECPG_INFORMIX_BAD_EXPONENT
#Функции возвращают это значение, если процедура разбора не может воспринять экспоненту в числе. Внутри оно представляется числом -1216 (определение Informix).
ECPG_INFORMIX_BAD_DATE
#Функции возвращают это значение, если процедура разбора не может разобрать дату. Внутри оно представляется числом -1218 (определение Informix).
ECPG_INFORMIX_EXTRA_CHARS
#Функции возвращают это значение, если процедуре разбора передаются посторонние символы, которая она не может разобрать. Внутри оно представляется числом -1264 (определение Informix).