数据类型

数据库类型

数据库类型 数据库存储长度 数据库类型ID
CHAR, NCHAR 8000(字符) 1042
VARCHAR2, NVARCHAR2 8000(字符) 1043
TEXT 16M(字节) 25
CLOB 4GB(字节) 3001
XML 16M(字节) 3300
XMLTYPE(XML类型别名) 16M(字节) 33451/可能会变化
TINYINT 1(字节) 972
SAMLLINT 2(字节) 21
INT/SERAIL 4(字节) 23
BIGINT,BIGSERIAL 8(字节) 20
DECIMAL,NUMBER 8(字节) 2315
REAL 4(字节) 700
FLOAT 4(字节) 2275
DOUBLE PRECISION, FLOAT8 8(字节) 701
BINARY 8000(字节) 1365
VARBINARY,RAW 8000(字节) 3100
BLOB,LONG RAW 4GB(字节) 3000
DATE 8(字节) 1082
TIME 8(字节) 1083
TIMESTAMP,DATETIME 8(字节) 1114
TIMESTAMP WITH TIME ZONE 8(字节) 1184
INTERVAL YEAR TO MONTH 8(字节) 1186
INTERVAL DAY TO SECOND 8(字节) 1188
BOOLEAN 1(字节) 16
BIT 8000(字节) 1560
JSON 16M(字节) 3304
BFILE 系统文件最大值UB8MAXVAL 3002

ACI数据类型

数据库类型 ACI类型编码 ACI类型名称(宏定义) 备注
CHAR, NCHAR 96 SQLT_AFC  
VARCHAR2, NVARCHAR2 1 SQLT_CHAR  
TEXT 5 SQLT_STR  
CLOB 112 SQLT_CLOB  
XMLTYPE(XML类型别名) 33451 —— 返回原生类型:33451
TINYINT 2 SQLT_NUM  
SAMLLINT 2 SQLT_NUM 所有数值类型都返回SQLT_NUM类型,需要根据类型长度,来决定在程序中用什么类型进行获取
INT/SERAIL 2 SQLT_NUM 所有数值类型都返回SQLT_NUM类型,需要根据类型长度,来决定在程序中用什么类型进行获取
BIGINT,BIGSERIAL 2 SQLT_NUM 所有数值类型都返回SQLT_NUM类型,需要根据类型长度,来决定在程序中用什么类型进行获取
DECIMAL,NUMBER 2 SQLT_NUM 所有数值类型都返回SQLT_NUM类型,需要根据类型长度,来决定在程序中用什么类型进行获取
REAL 2 SQLT_NUM 所有数值类型都返回SQLT_NUM类型,需要根据类型长度,来决定在程序中用什么类型进行获取
FLOAT 2 SQLT_NUM 所有数值类型都返回SQLT_NUM类型,需要根据类型长度,来决定在程序中用什么类型进行获取
DOUBLE PRECISION, FLOAT8 2 SQLT_NUM 所有数值类型都返回SQLT_NUM类型,需要根据类型长度,来决定在程序中用什么类型进行获取
BINARY 23 SQLT_BIN  
VARBINARY,RAW 24 SQLT_LBI  
BLOB,LONG RAW 113 SQLT_BLOB  
DATE 12 SQLT_DAT  
TIME 183 SQLT_TIME  
TIMESTAMP,DATETIME 187 SQLT_TIMESTAMP  
TIMESTAMP WITH TIME ZONE 188 SQLT_TIMESTAMP_TZ  
INTERVAL YEAR TO MONTH 189 SQLT_INTERVAL_YM  
INTERVAL DAY TO SECOND 190 SQLT_INTERVAL_DS  
BOOLEAN —— —— 返回原生类型:16
BIT —— —— 返回原生类型:1560
JSON 119 SQLT_JSON  
BFILE 114 SQLT_BFILEE  
VARCHAR,CHAR 155 SQLT_VST  

ACI绑定类型

绑定类型 类型ID 绑定变量 变量长度
SQLT_CHR 1 char(n) n
SQLT_NUM 2 ACINumber sizeof(ACINumber)
SQLT_INT 3 short sizeof(short)
SQLT_INT 3 int sizeof(int)
SQLT_INT 3 long long/int64 sizeof(long long)
SQLT_FLT 4 double sizeof(double)
SQLT_FLT 4 float sizeof(float)
SQLT_STR 5 char(n) n+1
SQLT_VNU 6 ACINumber sizeof(ACINumber)
SQLT_LNG 8 char(n) n
SQLT_VCS 9 char(n) n
SQLT_DAT 12 char[7] 7
SQLT_VBI 15 unsigned char[n+sizeof(short integer)] n+sizeof(short)
SQLT_BFLOAT 21 float sizeof(float)
SQLT_BDOUBLE 22 double sizeof(double)
SQLT_BIN 23 unsigned char[n] n
SQLT_LBI 24 unsigned char[n] n
SQLT_UIN 68 unsigned int sizeof(int)
SQLT_LVC 94 char[n+sizeof(integer)] n+sizeof(int)
SQLT_LVB 95 unsigned char[n+sizeof(integer)] ACIRaw n+sizeof(int)
SQLT_AFC 96 char(n) n
SQLT_CLOB 112 ACILobLocator sizeof(ACILobLocator*)
SQLT_BLOB 113 ACILobLocator sizeof(ACILobLocator*)
SQLT_BFILE SQLT_BFILEE 114 ACILobLocator sizeof(ACILobLocator*)
SQLT_RSET 116 ACIStmt* sizeof(ACIStmt*)
SQLT_TIME 185 ACIDateTime* sizeof(ACIDateTime)
SQLT_TIME_TZ 186 ACIDateTime* sizeof(ACIDateTime)
SQLT_ODT 156 ACIDateTime* sizeof(ACIDateTime)
SQLT_DATE 184 ACIDateTime* sizeof(ACIDateTime*)
SQLT_TIMESTAMP 187 ACIDateTime* sizeof(ACIDateTime*)
SQLT_TIMESTAMP_TZ 188 ACIDateTime* sizeof(ACIDateTime*)
SQLT_INTERVAL_YM 189 ACIDateTime* sizeof(ACIDateTime*)
SQLT_INTERVAL_DS 190 ACIDateTime* sizeof(ACIDateTime*)
SQLT_TIMESTAMP_LTZ 232 ACIDateTime* sizeof(ACIDateTime*)
SQLT_JSON 119 ACIJson* sizeof(ACIJson*)
SQLT_VST 155 ACIString* sizeof(ACIString*)

SQLT_CHR

定长字符串绑定;

Bind:绑定固定长度字符串, ACIBindByPos / ACIBindByPos2 的value_sz变量指定长度数据入库,如果value_sz小于数据库类型长度,数据库会自动补全空格;value_sz必须小于等于实际数据长度,否则会出现越界访问,会插入错误的数据。

Define:返回无0结束的定长字符串,需要通过 ACIDefineByPos / ACIDefineByPos2 的rlenp获得真实数据长度,返回的长度为给定的绑定变量长度,实际数据不足时,会用空格(0x20)补全。

SQLT_NUM

通过ACINumber类型进行数值的绑定,可以读写任意数值类型。SQLT_NUM不能绑定其他基础数值类型,比如int、double等。

ACINumber为一个22个字节长度的一个内存块:

#define ACI_NUMBER_SIZE 22
struct ACINumber
{
    ub1 ACINumberPart[ACI_NUMBER_SIZE];
};

SQLT_INT

绑定有符号整型数值,支持short、int、int64/longlong类型的define和bind。与SQLT_UIN类似,只是SQLT_UIN按无符号数值进行处理。

SQLT_FLT

绑定浮点数据库,支持float、double类型的define和bind。

SQLT_STR

有0字符串绑定:

Bind:必须是有0结束的字符串变量, ACIBindByPos / ACIBindByPos2 的value_sz参数需要传入n+1个长度;或者value_sz传入0,驱动会用strlen自动计算绑定变量长度。

Define:返回有0结束的字符串, ACIDefineByPos / ACIDefineByPos2 的rlenp获得真实数据长度,也可以通过strlen计算绑定变量长度。

SQLT_VNU

与SQLT_NUM相同。

SQLT_LNG

用于绑定数据的CLOB或者LANG类型,用法与SQLT_CHR相同。

SQLT_VCS

用于绑定字符串类型数据,可以用于define和bind数据库的char、varchar、text、clob、xmltype类型。绑定的内存块,前2个字节用于保存数据长度,后面紧跟数据内容,因此SQLT_VCS的绑定对应内存块长度大于等于2.对于 ACIDefineByPos / ACIDefineByPos2 ,rlen参数返回的值应该与获取到数据的前两个字节存储的数据长度一致。

SQLT_DAT

获取timestamp ltz类型,用一个char[7]类型进行绑定。取值范围是公元前4712年1月1日至公元9999年12月31日;7个字节分别表示世纪、年、月、日、时、分和秒。

由于不会出现0的情况,月和日都是按照原值存储的,月的范围是1~12,日的范围是1~31。

由于时、分、秒都会出现0的情况,因此存储时采用原值加1的方式。0时保存为1,13时保存为14,23时保存为24。分和秒的情况与小时类似。小时的范围是0~23,在数据库中以1~24保存。分和秒的范围都是0~59,在数据库中以1~60保存。

年和世纪的情况相对比较复杂,可分为公元前和公元后两种情况。由于最小的世纪的值是-47(公元前4712年),最大值是99(公元9999年)。为了避免负数的产生,把世纪加100保存在数据库中。公元2000年,世纪保存为120,公元9999年,世纪保存为199,公元前101年,世纪保存为99 (100+(-1)),公元前4712年,世纪保存为53(100+(-47))。

年的保存与世纪的保存方式类似,也把年的值加上100进行保存。对于公元2000年,年保持为100,公元1年保存为101,公元2004年保存为104,公元9999 年保存为199,公元前1年,保存为99(100+(-1)),公元前101年,保存为99(100+(-1)),公元前4712年保存为88(100+(-12))。对于公元前的年,保存的值总是小于等于100,对于公元后的年,保存的值总是大于等于100。年的范围是0~99,保存的值是1~199。

注意:一般的世纪,都包含了100年,而对于0世纪,由于包含公元前和公元后两部分且不包含0年,因此包含了198年。

SQLT_VBI

用于绑定二进制数据,可以用于define和bind数据库的binary、varbianry、blob类型。绑定的内存块,前两个字节用于保存数据长度,后面紧跟数据内容,因此SQLT_VBI的绑定对应内存块长度大于等于2.对于 ACIDefineByPos ,rlen参数返回的值应该与获取到数据的前两个字节存储的数据长度一致。

SQLT_BFLOAT

神通数据库中BINARY_FLOAT和float类型是一样的,BINARY_FLOAT类型只是与Oracle保持兼容所建立,因此BINARY_FLOAT类型的获取与SQLT_FLT一致。

SQLT_BDOUBLE

神通数据库中BINARY_DOUBLE和double类型是一样的,BINARY_DOUBLE类型只是与Oracle保持兼容所建立,因此BINARY_DOUBLE类型的获取与SQLT_FLT一致。

SQLT_BIN

绑定短二进制类型,可以用于define和bind数据库的binary、varbianry、blob类型

SQLT_LBI

绑定长二进制类型,可以用于define和bind数据库的binary、varbianry、blob类型

SQLT_UIN

绑定无符号整型数值,支持short、int、int64/longlong类型的define和bind。

SQLT_LVC

用于绑定字符串类型数据,可以用于define和bind数据库的char、varchar、text、clob、xmltype类型。绑定的内存块,前4个字节用于保存数据长度,后面紧跟数据内容,因此SQLT_LVC的绑定对应内存块长度大于等于4.对于 ACIDefineByPos ,rlen参数返回的值应该与获取到数据的前4个字节存储的数据长度一致。

SQLT_LVB

用于绑定字符串类型数据,可以用于define和bind数据库的binary(raw)、varbinary(long raw)、blob类型。绑定的内存块,前4个字节用于保存数据长度,后面紧跟数据内容,因此SQLT_LVB的绑定对应内存块长度大于等于4.对于 ACIDefineByPos ,rlen参数返回的值应该与获取到数据的前4个字节存储的数据长度一致。

绑定时可以用ACIRaw类型进行绑定,ACIRaw其实是一个结构,结构中有数据长度变量和数据内存地址,用于简化编码。ACIRaw的类似结构为:

struct ACIRaw
{
      ub4 size; //数据长度
      ub1 data[1]; //数据内存
};

用SQLT_LVB进行bind操作,将忽略 ACIBindByPos / ACIBindByPos2 / ACIBindByName / ACIBindByName2 的value_sz参数。

SQLT_AFC

用于绑定数据的CLOB或者LANG类型,用法与SQLT_CHR相同。

SQLT_CLOB

用于绑定CLOB类型数据,绑定变量类型只能为ACILobLocator,且ACILobLocator是需要通过接口( ACIDescriptorAlloc )进行分配后才能进行绑定。

SQLT_BLOB

用于绑定BLOB类型数据,绑定变量类型只能为ACILobLocator,且ACILobLocator是需要通过接口( ACIDescriptorAlloc )进行分配后才能进行绑定。

SQLT_JSON

用于绑定JSON类型数据,绑定变量类型只能为ACIJson,且ACIJson是需要通过接口( ACIDescriptorAlloc )进行分配后才能进行绑定。

SQLT_BFILE

用于绑定BFILE类型数据,绑定变量类型只能为ACILobLocator,且ACILobLocator是需要通过接口( ACIDescriptorAlloc )进行分配后才能进行绑定。

SQLT_REST

用于绑定在PL存储过程返回的out参数为refcursor/sys_refcursor类型,绑定的类型变量为一个ACIStmt结构,其实返回了一个结果集,通过对返回的ACIStmt结构进行define绑定,ACIStmt对象需要通过 ACIHandleAlloc 可获取对于的数据库。

SQLT_TIME

SQLT_TIME为SQLT_TIMESTAMP的一个子类,只能处理时分秒数据,在Oracle中用于往一个timestmap类型(Oracle没有time类型)中只写入时间的一个时间戳数据,在神通数据库中,有time类型,因此可以用SQLT_TIME往time类型中写入数据,也可以往timestamp类型中写入数据。绑定采用ACIDateTime结构来进行。

struct ACITime
{
  ub1 ACITimeHH;                          /* 小时; 范围是 0 <= hours <=23 */
  ub1 ACITimeMI;                     /* 分钟; 范围是 0 <= minutes <= 59 */
  ub1 ACITimeSS;                     /* 秒钟; 范围是 0 <= seconds <= 59 */
};

SQLT_TIME_TZ

用法与SQLT_TIME相同,都是采用ACIDateTime结构来进行绑定

SQLT_ODT

SQLT_ODT为SQLT_TIMESTAMP的一个子类,能处理年月日和时分秒,不能处理带毫秒的时间戳数据,在神通数据库中,可以用来define或者bind绑定date、timestamp、time类型。绑定采用ACIDate结构来进行。

struct ACIDate
{
  sb2 ACIDateYYYY;         /* 公元年; 范围是 -4712 <= year <= 9999 */
  ub1 ACIDateMM;           /* 月份; 范围是 1 <= month < 12 */
  ub1 ACIDateDD;           /* day; 范围是 1 <= day <= 31 */
  ACITime ACIDateTime;      /* time :ACITime 结构*/
};

SQLT_DATE

SQLT_DATE用于define或者bind绑定date、timestamp、time类型,绑定结构为ACIDateTime,ACIDateTime需要通过 ACIDescriptorAlloc 进行分配后才能进行绑定使用。

SQLT_TIMESTAMP

SQLT_TIMESTAMP用于define或者bind绑定date、timestamp、time类型,绑定结构为ACIDateTime,ACIDateTime需要通过 ACIDescriptorAlloc 进行分配后才能进行绑定使用。相对于SQLT_DATE,SQLT_TIMESTAMP能支持更高精度的实际处理,支持纳秒级的数据处理能力。

SQLT_TIMESTAMP_TZ

SQLT_TIMESTAMP_TZ用于define或者bind绑定date、timestamp、time类型,绑定结构为ACIDateTime,ACIDateTime需要通过 ACIDescriptorAlloc 进行分配后才能进行绑定使用。相对于SQLT_TIMESTAMP,SQLT_TIMESTAMP_TZ时区的处理。

SQLT_INTERVAL_YM

SQLT_INTERVAL_YM用于define或者bind绑定interval year to month类型,绑定结构为ACIInterval,ACIInterval需要通过 ACIDescriptorAlloc 进行分配后才能进行绑定使用。

SQLT_INTERVAL_DS

SQLT_INTERVAL_DS用于define或者bind绑定interval day to second类型,绑定结构为ACIInterval,ACIInterval需要通过 ACIDescriptorAlloc 进行分配后才能进行绑定使用。

SQLT_TIMESTAMP_LTZ

SQLT_TIMESTAMP_LTZ用于define或者bind绑定timestamp witch local time zone类型,绑定结构为ACIDateTime,ACIDateTime需要通过 ACIDescriptorAlloc 进行分配后才能进行绑定使用。相对于SQLT_TIMESTAMP,SQLT_TIMESTAMP_LTZ为本地时区的处理。

数据转换

在程序中define或者bind绑定的变量,设置了绑定类型后,是否可以实现相互之间转换。

I/O:代表读写都可以转换

NA:代表不支持转换

普通数据类型

../../../../_images/image615.png

时间类型

../../../../_images/image711.png

大对象类型

../../../../_images/image813.png

游标类型

处理在PL中通过out参数返回的ref cursor类型的值,采用SQLT_RSET进行绑定。绑定生成一个ACIStmt对象,再通过define定义进行数据的获取。

Oracle的Long类型迁移处理

用户在使用Oracle数据库的时候部分应用存在误解,将Oracle的long类型当成数值类型来使用,其实long类型为一个字符型的大字段类型,在Oracle中可以存储2GB,long类型迁移到神通后,会变成clob类型,用户通过数值类型去获取clob的数据,原始神通不支持,但由于用户有此类误使用,Oracle也支持容错,因此神通数据库也支持了这种容错处理。