11ESQLC程序中使用DECIMAL数据类型.docx
《11ESQLC程序中使用DECIMAL数据类型.docx》由会员分享,可在线阅读,更多相关《11ESQLC程序中使用DECIMAL数据类型.docx(15页珍藏版)》请在冰豆网上搜索。
![11ESQLC程序中使用DECIMAL数据类型.docx](https://file1.bdocx.com/fileroot1/2022-10/29/ef5e9d2d-b18e-4c3a-8e8c-152502b3f649/ef5e9d2d-b18e-4c3a-8e8c-152502b3f6491.gif)
11ESQLC程序中使用DECIMAL数据类型
第十一章
ESQL/C程序中使用
DECIMAL数据类型
本章介绍DECIMAL数据类型的概貌,并给出了几个使用该类型的例子。
学完本章,你将能够:
●知道把宿主变量定义为C的何种数据类型,来存放SQL数据类型DECIMAL的值。
●理解该数据类型的存储要求。
●使用ESQL/C的库函数把数据转换成DECIMAL类型或从DECIMAL类型转换成别的类型。
DECIMAL值:
●依赖于机器
●可以多达32为有效数字
●可以有小数点,或没有
●可以有范围在-128到+126之间的指数
象下面这样定义DECIMAL字段:
ColumnNameDECIMAL[(m[,n])]
这里,m是精度(有效数字的数目),n是有效位数(小数点右边的数字的位数)。
在定义时,省略有效位数,则是浮点DECIMAL类型;声明有效位数,则是定点DECIMAL。
SQL的MONEY类型值以定点DECIMAL类型存储,ESQL/C不区分MONEY类型值和DECIMAL类型值;两者都是DECIMAL。
同样,DATETIME和INTERVAL类型都有一个DECIMAL部分。
为使用DECIMAL类型,在代码中包含进来头文件decimal.h。
$includedecimal;
定义在decimal.h文件中的dec_t结构存放这些值:
dec_exp
数字的指数,基数是100
dec_pos
数字的符号:
1当它大于或等于0
0当它小于0
-1当它是空值
dec_ndgts
有效数字的数目,基数是100
dec_dgts
实际的有效数字,基数是100
当操作DECIMAL类型的时候,应当使用ESQL/C库中提供的DECIMAL函数,将在后续页中讨论它们。
任何其它的操作、修改或分析可能导致不可预测的结果。
在ESQL/C库中有四个函数可以把C的数据类型转换成DECIMAL值:
deccvasc(from,len,to)
把ASCII字符串转换成DECIMAL值。
char*from;
指向ASCII源字符串的指针。
intlen;
ASCII源字符串的字节数。
dec_t*to;
指向目的DECIMAL结构的指针。
返回值
-1200产生上溢-1201产生下溢
-1213存在非数值字符-1216存在坏的指数
deccvint(from,to)
把C的整数转换成DECIMAL值。
intfrom;
要转换的整数值。
dec_t*to;
指向目的DECIMAL结构的指针。
deccvlong(from,to)
把C的长整数转换成DECIMAL值。
longfrom;
要转换的长整数值。
dec_t*to;
指向目的DECIMAL结构的指针。
deccvdbl(from,to)
把C的双精度数转换成DECIMAL值。
intfrom;
要转换的双精度数值。
dec_t*to;
指向目的DECIMAL结构的指针。
所有的四个函数返回:
0当转换成功时
<0当转换失败时
在上面的例子中,包含进decimal.h头文件,使我们可以操作dec_t结构。
在使用仅由数值字符组成的ASCII字符串初始化DecString之后,使用deccvasc()函数把字符串转换成一个DECIMAL值,存放到DECIMAL结构DecValue中。
注意到我们还检测了deccvasc()的返回值。
此时,如果愿意的话,可以把DecValue插入到一个DECIMAL字段。
我们需要DECIMAL值时,不必非做这种显示的转换。
可以直接使用字符串,而让数据库服务器做隐含的转换。
在ESQL/C库中有四个函数可以把DECIMAL值转换成ASCII字符串。
每个函数在小数点的位置和格式上稍有不同。
dectoasc(from,to,len,rt)
把DECIMAL值转换成ASCII字符串。
dec_t*from;
指向源DECIMAL值的指针。
char*to;
指向存放ASCII字符串的目的缓冲。
intlen;
目的缓冲的字节数。
intrt;
小数点右边的数字的数目。
char*dececvt(from,ndgt,decpt,sign)
把DECIMAL值转换成ASCII字符串。
dec_t*from;
指向源DECIMAL值的指针。
intndgt;
目的缓冲里的字节数。
int*decpt;
指向小数点的偏移值的指针。
int*sign
指向符号的指针(!
=0是负;=0是正)。
char*decfcvt(from,ndgt,decpt,sign)
把DECIMAL值转换成ASCII字符串。
dec_t*from;
指向源DECIMAL值的指针。
intndgt;
小数点右边的数字的数目。
int*decpt;
指向小数点的偏移值的指针。
int*sign
指向符号的指针(!
=0是负;==0是正)。
rfmtdec(from,format,to)
把DECIMAL值转换成格式化的字符串。
dec_t*from;
指向源DECIMAL值的指针。
char*format;
指向格式字符串的指针。
char*to;
指向用于ASCII字符串的目的缓冲的指针。
所有的四个函数返回:
0当转换成功时
<0当转换失败时
在上面的例子中,我们先使用函数deccvasc()把字符串转换成DECIMAL值,把结果存放到DecValue中。
然后,使用函数dectoasc()把值转换成另一个ASCII字符串,把结果存放到DecASCII中。
因为dectoasc()不会以空值来结束DecASCII中的值,所以在显示结果之前要在末尾加上空值。
字符串函数ldchar()正好完成该功能。
(参见在ESQL/C中使用简单变量一章。
)
在ESQL/C库中有三个函数可以把DECIMAL值转换成C的数值类型:
dectoint(from,to)
把DECIMAL值转换成C的整数值。
dec_t*from;
指向源DECIMAL结构的指针。
int*to;
指向目的整数的指针。
dectolong(from,to)
把DECIMAL值转换成C的长整数值。
dec_t*from;
指向源DECIMAL结构的指针。
int*to;
指向目的长整数的指针。
dectodbl(from,to)
把DECIMAL值转换成C的双精度数值。
dec_t*from;
指向源DECIMAL结构的指针。
int*to;
指向目的双精度数的指针。
使用dectodbl()函数时,可能丢失一些有效数字,依赖于宿主计算机的浮点格式。
另外,把DECIMAL值转换成整数或长整数时,相应函数返回值-1200,当:
dectoint()DECIMAL值>32,767
dectolong()DECIMAL值>2,147,647
所有的三个函数也返回:
0当转换成功时
<0当转换失败时
在上面的例子中,我们再次先使用函数deccvasc()把字符串转换成DECIMAL值,把结果存放到DecValue中。
然后,使用函数dectodbl()把DECIMAL值转换成C的双精度类型,把结果存放到DblValue中。
一旦转换完成,使用printf()函数直接显示它。
在ESQL/C库中有四个函数可以对DECIMAL值进行算术运算:
decadd(op1,op2,result)
把两个DECIMAL值加到一起(op1+op2)。
dec_t*op1;
指向头一个操作数的指针。
dec_t*op2;
指向第二个操作数的指针。
dec_t*result;
指向和的指针。
decsub(op1,op2,result)
从一个DECIMAL值减去另一个DECIMAL值(op1-op2)。
dec_t*op1;
指向头一个操作数的指针。
dec_t*op2;
指向第二个操作数的指针。
dec_t*result;
指向差的指针。
decmul(op1,op2,result)
计算两个DECIMAL值的乘积(op1*op2)。
dec_t*op1;
指向头一个操作数的指针。
dec_t*op2;
指向第二个操作数的指针。
dec_t*result;
指向积的指针。
decdiv(op1,op2,result)
用一个DECIMAL值去除另一个DECIMAL值(op1/op2)。
dec_t*op1;
指向头一个操作数的指针。
dec_t*op2;
指向第二个操作数的指针。
dec_t*result;
指向商的指针。
所有的四个函数返回:
0当转换成功时
-1200发生上溢
-1201发生下溢
-1202被零除
在该例子中,我们假定两个DECIMAL值已经被装入。
使用decmul()求两个DECIMAL值的乘积,并把结果存放到DecMult中。
然后,使用dectoasc()把乘积从DECIMAL值转换成ASCII字符串。
一旦转换完成,使用ldchar()给字符串加上空值结束符,然后使用printf()函数显示它。
在ESQL/C库中有四个函数可以操作DECIMAL值:
deccmp(dec1,dec2)
比较两个DECIMAL值的大小。
dec_t*op1;
指向第一个DECIMAL值的指针。
dect_t*op2;
指向第二个DECIMAL值的指针。
返回值
-1第一个值<第二个值
0两个值相同
1第一个值>第二个值
DECUNKNOW第一个值或第二个值是SQL的空值
deccopy(dec1,dec2)
拷贝DECIMAL值。
dec_t*op1;
指向源DECIMAL结构的指针。
dect_t*op2;
指向目的DECIMAL结构的指针。
decround(dec1,scale)
圆整DECIMAL值。
dec_t*op1;
指向源DECIMAL结构的指针。
intscale;
舍入后小数点右边的有效位数。
dectrunc(dec1,scale)
截断DECIMAL值。
dec_t*op1;
指向源DECIMAL结构的指针。
intscale;
截断后小数点右边的有效位数。
所有的四个函数返回:
0当操作成功时
<0当操作失败时
改变代码以使用DECIMAL值。
1.修改全局结构stock的定义,把unit_price域从double类型修改为dec_t。
不要忘了包含进头文件decimal.h。
2.修改初始化全局记录为空值的函数,把修改过的域初始化为适当值。
3.修改InputStock()函数,把输入的单价转换成DECIMAL值。
4.重新生成程序。
5.运行程序,并插入一个记录。
6.运行DBAccess以验证DECIMAL值插入正确。