ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# 33.15\. Informix兼容模式 `ecpg`可以在所谓的 _Informix兼容模式_下运行。 如果这种模式是活跃的,它试图表现得好像Informix E/SQL的Informix预编译器。 通常所说的这将允许你使用美元符号, 而不是`EXEC SQL`原始的引入嵌入式的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; ``` > **Note:** 在`$`之间不能有任何空格和下面的预处理指令, 即`include`,`define`, `ifdef`等等。否则,预处理器将解析令牌作为宿主变量。 有两种兼容模式:`INFORMIX`, `INFORMIX_SE`。 当使用这些兼容模式连接程序时,记得要链接`libcompat`前内置于ECPG中。 除了前面所说的语法块, Informix兼容模式为输入输出和数据转换功能, 以及从E/SQL到ECPG嵌入式SQL语句提供一些函数。 Informix兼容模式紧密联系ECPG的pgtypeslib库。 pgtypeslib在C主机程序映射SQL数据类型到数据类型,并且 Informix 兼容模式的大部分附加函数允许你在那些C主机程序类型上进行操作。 但值得注意的是,兼容性的程度是有限的。它并不试图复制Informix的操作;它允许你做或多或少相同的操作,使你具有相同的名称和相同的基本行为功能,但如果你现在使用Informix,它没有下拉式功能表位置。 此外,一些数据类型是不同的。比如,PostgreSQL的 datetime和 区间类型不知道范围比如`YEAR TO MINUTE`, 因此你在ECPG的这两种类型中不会找到支持。 ## 33.15.1\. 附加类型 在不使用`typedef`的Informix模式中 现在支持为存储正确修剪字符串数据 Informix特殊"字符串"伪类型。 实际上,在Informix模式中,ECPG拒绝包含`typedef sometype string;`的过程源文件。 ``` EXEC SQL BEGIN DECLARE SECTION; string userid; /* 这个变量将包含修剪的数据 */ EXEC SQL END DECLARE SECTION; EXEC SQL FETCH MYCUR INTO :userid; ``` ## 33.15.2\. 附加的/失踪的嵌入的SQL语句 `CLOSE DATABASE` 这个语句关闭当前连接。事实上,这是ECPG的 `DISCONNECT CURRENT`的同义词: ``` $CLOSE DATABASE; /* 关闭当前连接 */ EXEC SQL CLOSE DATABASE; ``` `FREE cursor_name` 由于ECPG与Informix的ESQL/C如何运行的不同(即这个步骤是纯粹的语法转换并且依赖于底层运行时的库)在ECPG中没有 `FREE cursor_name`声明。 这是因为在ECPG中,`DECLARE CURSOR`不转化为使用游标名称调用运行时库的一个函数。 这意味着,在ECPG中运行时库中SQL游标没有运行时的记录,只有在PostgreSQL服务器上。 `FREE statement_name` `FREE statement_name`是 `DEALLOCATE PREPARE statement_name`的同义词。 ## 33.15.3\. Informix兼容SQLDA描述符区域 Informix兼容模式支持一个 比[Section 33.7.2](#calibre_link-2007)描述中的不同的结构。见下文: ``` 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` 如果结果集中包含1个以上的记录,指向下一个SQLDA结构的指针。 `reserved` 未使用指针,包含空。保持Informix兼容。 下面每个字段属性,它们被存储在`sqlvar`数组中: `sqltype` 字段类型。常量在`sqltypes.h`中。 `sqllen` 字段数据的长度。 `sqldata` 指向字段数据的指针。指针是`char *`类型, 通过它指出的数据是二进制格式。例子: ``` int intval; switch (sqldata-&gt;sqlvar[i].sqltype) { case SQLINTEGER: intval = *(int *)sqldata-&gt;sqlvar[i].sqldata; break; ... } ``` `sqlind` 指向空指针。如果通过DESCRIBE或取回后,那么它总是一个有效的指针。 如果使用`EXECUTE ... USING sqlda;` 作为输入,然后空指针值意味着该字段的值为非空。否则,一个有效的指针 和`sqlitype`必须正确设置。例子: ``` if (*(int2 *)sqldata-&gt;sqlvar[i].sqlind != 0) printf("value is NULL\n"); ``` `sqlname` 字段名称。0终止字符串。 `sqlformat` 保留在Informix中,`PQfformat()`的值为字段的值。 `sqlitype` 空指针的数据类型。当从服务器返回数据时,它总是SQLSMINT。 当`SQLDA`用于参数化查询时, 数据是根据设定的类型来处理的。 `sqlilen` 空指针数据的长度。 `sqlxid` 字段的扩展类型,结果`PQftype()`。 `sqltypename``sqltypelen` `sqlownerlen` `sqlsourcetype` `sqlownername` `sqlsourceid` `sqlflags` `sqlreserved` 未使用。 `sqlilongdata` 如果`sqllen`大于32KB。它等于`sqldata`。 例子: ``` 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); /* 主结构被free(), sqlda和sqlda->sqlvar在分配区域中*/ ``` 获取更多信息,参见`sqlda.h`头文件和 `src/interfaces/ecpg/test/compat_informix/sqlda.pgc` 回归测试。 ## 33.15.4\. 附加函数 `decadd` 增加2个decimal类型值。 ``` int decadd(decimal *arg1, decimal *arg2, decimal *sum); ``` 这个函数接受一个指向类型decimal(`arg1`)的第一个操作数的指针, 类型decimal (`arg2`)的第二个操作数的指针和包含sum (`sum`)类型decimal值的指针。成功时,函数返回0。 以免溢出返回`ECPG_INFORMIX_NUM_OVERFLOW`和在下溢的情况下返回 `ECPG_INFORMIX_NUM_UNDERFLOW`。其他错误返回-1, `errno`设置为pgtypeslib的各自的`errno`数。 `deccmp` 比较decimal类型的2个变量。 ``` int deccmp(decimal *arg1, decimal *arg2); ``` 这个函数接受一个指向第一个decimal值(`arg1`)的指针, 一个指向第二个decimal值(`arg2`)的指针并返回 一个表示这是更大值的整数值。 * 如果`arg1`指向比`var2`指向的值更大,则为1。 * 如果`arg1`指向比`arg2`指向的值更小,则为-1。 * 如果`arg1`指向和`arg2`指向的值相等,则为0。 `deccopy` 复制一个decimal值。 ``` void deccopy(decimal *src, decimal *target); ``` 这个函数接受一个指向复制为第一个参数(`src`) 的decimal值的指针和 一个指向decimal(`target`)的目标结构作为第二个参数的指针。 `deccvasc` 将一个值从ASCII表示转换为decimal类型。 ``` int deccvasc(char *cp, int len, decimal *np); ``` 这个函数接受一个指向字符串的指针, 这个字符串包含转换成和其长度一样为`len` 的(`cp`)数字的字符串表示形式。 `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`。 如果观察到尝试除以0, 函数返回`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类型变量到C char*字符串中ASCII表示。 ``` int dectoasc(decimal *np, char *cp, int len, int right) ``` 函数接收一个指向decimal(`np`)类型文本表示的变量的指针。 `cp`是保存操作结果的缓冲区。参数`right`指明小数点右边有多少位数字应该包含在输出中。结果将四舍五入小数数字位数。设置`right`到-1表明所有可用的小数位数应包含在输出中。如果由`len` 指明的输出缓冲区的长度不足以保持包含尾随NUL字符的文本表示,仅仅在结果中存储一个单一的`*`字符并且返回-1。 如果缓冲区`cp`太小,函数则返回-1,如果内存耗尽, 则返回`ECPG_INFORMIX_OUT_OF_MEMORY`。 `dectodbl` 转换一个decimal类型的变量到一个double类型。 ``` int dectodbl(decimal *np, double *dblp); ``` 函数接受一个指向decimal值转换(`np`)和 一个指向应保持操作结果(`dblp`)的double变量的指针。 成功则返回0,如果转换失败则返回一个负数。 `dectoint` 转化一个decimal类型到一个integer类型的变量。 ``` int dectoint(decimal *np, int *ip); ``` 函数接受一个指向decimal值转换(`np`)和 指向应保持操作结果(`ip`)的integer变量的指针。 成功则返回0,如果转换失败则返回一个负数。如果发生溢出, 则返回`ECPG_INFORMIX_NUM_OVERFLOW`。 注意ECPG应用不同于Informix应用。 当ECPG应用中的限制取决于(`-INT_MAX .. INT_MAX`)的结构,Informix 限制integer的范围从-32767到32767。 `dectolong` 转换一个decimal类型的变量到一个long integer类型。 ``` int dectolong(decimal *np, long *lngp); ``` 函数接受一个decimal值转换(`np`)和 一个应保持操作结果(`lngp`)的long变量的指针。 成功则返回0,如果转换失败则返回一个负数。 如果发生溢出,则返回`ECPG_INFORMIX_NUM_OVERFLOW`。 注意ECPG应用不同于Informix应用。当ECPG应用中的限制取决于(`-LONG_MAX ..LONG_MAX`)的结构,Informix限制long integer的范围从-2,147,483,647到2,147,483,647。 `rdatestr` 转换一个date类型到C char*字符串。 ``` int rdatestr(date d, char *str); ``` 这个函数接收2个参数,第一个是日期转换(`d`和第二个参数是一个指向目标字符串的指针。输出格式总是`yyyy-mm-dd`,因此你需要为字符串至少分配11个字节(包含0字节终止符)。 成功函数则返回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`)的指针。 实质上这个函数使用[_`PGTYPESdate_today`_](#calibre_link-2072)函数。 `rjulmdy` 从date类型的变量中提取一天,一个月,一年中的值。 ``` int rjulmdy(date d, short mdy[3]); ``` 这个函数接受日期`d`和一个指向3个短整型数值`mdy`数组的指针,变量名表明了相继顺序:`mdy[0]` 的设置包含了月数,`mdy[1]`的设置是一天的值, `mdy[2]`包含年的值。 函数此时总是返回0。 实质上函数使用[_`PGTYPESdate_julmdy`_](#calibre_link-2073)函数。 `rdefmtdate` 使用格式掩码转换字符串到一个date类型的值。 ``` int rdefmtdate(date *d, char *fmt, char *str); ``` 函数接受一个保持操作(`d`)结果日期值的指针。 格式掩码用于解析日期(`fmt`)和包含date(`str`)文本表示形式的C char*字符串。文本表示形式期望匹配格式掩码。然而你不需要有一个1:1字符串映射格式掩码。它仅分析相继顺序并且查找`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`_](#calibre_link-2074)函数来实现。 请参阅这儿的实例输入的表。 `rfmtdate` 转换一个date类型变量到它的一个格式掩码的文本表示。 ``` int rfmtdate(date d, char *fmt, char *str); ``` 这个函数接收一个日期转换(`d`), 格式掩码(`fmt`)和将保持日期(`str`)的文本表示形式 的字符串。 成功返回0,如果产生错误则返回一个负值。 实质上这个函数 使用[_`PGTYPESdate_fmt_asc`_](#calibre_link-2075)函数。请参阅这儿的例子。 `rmdyjul` 从指明日期中的年,月,日的3维短整型数组中创建一个日期值。 ``` int rmdyjul(short mdy[3], date *d); ``` 这个函数接收一个3维短整型(`mdy`)数组 和一个指向应保持操作结果的日期类型变量的指针。 当前这个函数总是返回0。 实质上这个函数使用[_`PGTYPESdate_mdyjul`_](#calibre_link-2076)来实现。 `rdayofweek` 返回一个数字表示的一个日期值中某一周的某一天。 ``` int rdayofweek(date d); ``` 函数接收日期变量`d`作为其唯一的参数并返回一个整数, 表示这一天是星期几。 * 0 - 星期日 * 1 - 星期一 * 2 - 星期二 * 3 - 星期三 * 4 - 星期四 * 5 - 星期五 * 6 - 星期六 实质上这个函数使用[_`PGTYPESdate_dayofweek`_](#calibre_link-2077)来实现。 `dtcurrent` 检索当前的timestamp。 ``` void dtcurrent(timestamp *ts); ``` 这个函数检索当前timestamp并且保存 它到`ts`指向的timestamp变量中。 `dtcvasc` 解析一个文本表示的timestamp到一个timestamp变量。 ``` int dtcvasc(char *str, timestamp *ts); ``` 这个函数接收解析字符串(`str`) 和一个指向应保持操作结果(`ts`)的timestamp变量的指针。 成功时函数返回0,发生错误的时候返回负数。 实质上这个函数使用 [_`PGTYPEStimestamp_from_asc`_](#calibre_link-2078)函数。 请参见这儿的实例输入的表。 `dtcvfmtasc` 使用格式掩码解析文本表示的timestamp为timestamp变量。 ``` dtcvfmtasc(char *inbuf, char *fmtstr, timestamp *dtvalue) ``` 这个函数接收解析(`inbuf`)字符串, 使用(`fmtstr`)格式掩码, 以及一个指向保持操作(`dtvalue`)结果的timestamp变量的指针。 这个函数 通过[_`PGTYPEStimestamp_defmt_asc`_](#calibre_link-2079) 函数来实现。参见文档中使用的格式说明符列表。 成功时函数返回0,发生错误的时候则返回一个负数。 `dtsub` 一个timestamp与另一个相减,并且返回一个区间类型变量。 ``` int dtsub(timestamp *ts1, timestamp *ts2, interval *iv); ``` 该函数将时间戳变量相减, 其中`ts2`指向`ts1`指向的时间戳变量, 并将结果存储在`iv`指向的区间变量中。 成功时函数返回0,如果发生错误则返回一个负数。 `dttoasc` 转换一个timestamp变量到C char*字符串。 ``` int dttoasc(timestamp *ts, char *output); ``` 这个函数接收一个指向timestamp变量转换(`ts`) 的指针和保持操作`output`结果的字符串。 根据SQL标准,转换`ts`到它的一个文本表示形式, 即`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`_](#calibre_link-2080)函数。 请参阅有关格式掩码说明的使用获取更多信息。 `intoasc` 将区间变量转换成C char*字符串。 ``` int intoasc(interval *i, char *str); ``` 这个函数接收一个指向区间 变量转换(`i`)的指针和 保持操作(`str`)结果的字符串。 它依照SQL标准将`i`转换成文本表示形式, 即`YYYY-MM-DD HH:MM:SS`。 成功时函数返回0,如果产生错误则返回负数。 `rfmtlong` 将长整型数值转换成使用格式掩码的文本表示形式。 ``` int rfmtlong(long lng_val, char *fmt, char *outbuf); ``` 这个函数接收长值`lng_val`, 格式掩码`fmt`和指向输出缓存`outbuf`的指针。 它依照格式掩码将长值转换成文本表示形式。 格式掩码由下面格式指定字符组成。 * `*`(星号) – 如果这个位置是空白的,否则,用星号填充。 * `&`(&符号) -如果这个位置是空白的,否则,用零填充。 * `#` - 将前导零转换成空格。 * `&lt;` -字符串中左对齐数字。 * `,`(逗号)–将四个或更多数字分成由逗号分隔的三个数字一组。 * `.`(句号) – 这个字符将从小数部分分离出数的整数部分。 * `-` (减号) – 如果数是负值,则出现负号。 * `+`(加号) -如果数是正值,则出现加号。 * `(` -这将替代负数前面的减号。减号将不会出现。 * `)` -这个字符替代减号,并且在负数后面输出。 * `$` - 货币符号。 `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`字节到新的位置(至少如果源字符串有尾随空格) 和添加空终止符。 `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` 设置一个变量为空。 ``` 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` 如果变量是空,测试: ``` int risnull(int t, char *ptr); ``` 这个函数接收测试(`t`)变量的类型以及 一个指向这个变量(`ptr`)的指针。 注意后者需要映射到一个char*。 参见函数[_`rsetnull`_](#calibre_link-2081)获取可能变量类型的列表。 这儿是如何使用这个函数的一个例子: ``` $char c[] = "abc "; $short s = 17; $int i = -74874; risnull(CCHARTYPE, (char *) c); risnull(CSHORTTYPE, (char *) &s); risnull(CINTTYPE, (char *) &i); ``` ## 33.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定义)。