OCI接口
1.概述
OCI(全称Open Call Interface)是为C语言访问数据库提供的接口,编译和连接一个OCI程序不需要独立的预处理或者预编译步骤。
若使用OCI接口,则使用-DOCI_EXPORT进行指定。
2.安装与配置
2.1.安装
-
确保已经安装uxdb。
-
解压安装包。
tar -xf uxdb-oci-12-2.0.tar.gz -
执行install.sh安装。
执行如下命令。
cd uxdb-oci-12-2.0 ./install.sh [uxdb@localhost uxdb-oci-12-2.0]$ ./install.sh input UXDB_HOME[/opt/uxdbinstall]: INSTALL_HOME:/opt/uxdbinstall installation complete!当提示input UXDB_HOME[/opt/uxdbinstall]:时,请输入数据库安装目录后回车,如果直接回车数据库会被安装在默认路径:/opt/uxdbinstall/下。
2.2.配置
-
配置文件路径
数据库安装目录下dbsql/lib/oci/config.ini。
-
配置项
-
IsAutoCommit:代表是否自动提交,默认为0。
-
IsAllowNullParam:是否允许参数为空,默认为1。
-
IsFetchOnExecute:在StmtExecute里面是否执行fetch操作,默认0为不执行。
-
uxdbPort:数据库端口,如果配置项错误或者没有配置,默认是52025。
-
uxdbName:数据库名称,默认uxdb。
-
-
参数含义
-
IsAutoCommit:当此参数设置为0时,不会对执行语句进行提交,操作只在当前事务可见;如果设置为1时,代表会自动提交,操作对所有事务可见。
-
IsAllowNullParam:当此参数设置为0时,代表接口的错误句柄参数和以下表格中的参数不允许为空,为空时会返回错误;如果设置为1时,代表接口的错误句柄参数和以下表格中的参数允许为空,为空时不会返回错误。
其他参数
接口 参数 OCIDefineByPos valuep rlenp OCIBindByPos valuep OCIIntervalGetDaySecond dy hr mm ss fsec OCIIntervalGetYearMonth yr mnth OCIIntervalToText resultlen OCIDateTimeGetDate yr mnth dy OCIDateTimeGetTime hr mm ss fsec -
IsFetchOnExecute:当此参数设置为0时,代表在执行StmtExecute函数处理查询语句后不会往缓冲区存放查询数据。为1时,代表在执行StmtExecute函数处理查询语句后,根据参数items不用执行fetch就会有items条数据被放到缓冲区。
-
uxdbPort:数据库端口,oci连接接口如果没有传入数据库端口,就使用配置文件里面的配置参数,如果配置文件里面也没有配置就使用默认端口52025。
-
uxdbName:数据库名称,oci连接接口如果没有传入数据库名称,就使用配置文件里面的配置参数,如果配置文件里面也没有配置就使用默认名称uxdb。
-
-
错误文件
如果读取配置文件参数有错误,在跟config.ini文件同目录的地方会生成错误文件err.log,可以根据错误文件检查配置文件内容哪里有问题。
3.接口介绍
3.1.句柄
3.1.1.OCIEnvCreate
-
功能
创建并初始化OCI函数的环境句柄以在其下工作。
-
函数
sword OCIEnvCreate(OCIEnv **envhpp, ub4 mode, CONST dvoid *ctxp, CONST dvoid *(*malocfp)(dvoid *ctxp, size_t size), CONST dvoid *(*ralocfp)(dvoid *ctxp, dvoid *memptr, size_t newsize), CONST void (*mfreefp)(dvoid *ctxp, dvoid *memptr), size_t xtramemsz, dvoid **usrmempp) -
参数
OCIEnvCreate 参数说明
名称 描述 envhpp(输出) 指向环境句柄的指针。 mode(输入) 指定模式的初始化。 OCI_DEFAULT:默认值。
ctxp(输入) 为内存回调例程指定用户定义的上下文。 malocfp(输入) 保留参数。 ralocfp(输入) 保留参数。 mfreefp(输入) 保留参数。 xtramemsz(输入) 保留参数。 usrmempp(输出) 返回一个指针,指向xtramemsz由调用为用户分配的大小的用户内存。 -
注意
此调用使用用户指定的模式为所有OCI调用创建环境,应在任何其他OCI调用之前调用,常用来代替OCIInitialize()和OCIEnvInit()的调用。*envhpp本来就指向一个可用的环境句柄会拒绝分配新的环境句柄并返回OCI_ERROR。仅可以申请一个环境句柄,重复申请环境句柄会拒绝分配新的环境句柄并返回OCI_ERROR。
-
示例
OCIEnvCreate(&envhpp, OCI_DEFAULT, NULL, NULL, NULL, NULL, 0, NULL);
3.1.2.OCIHandleAlloc
-
功能
分配和初始化句柄。
-
函数
sword OCIHandleAlloc(dvoid *parenth, dvoid **hndlpp, CONST ub4 type, CONST size_t xtramem_sz, dvoid **usrmempp) -
参数
OCIHandleAlloc 参数说明
名称 描述 parenth(输入) 环境句柄。 hndlpp(输出) 返回句柄。 type(输入) 从环境句柄上分配的句柄类型。可以分配的句柄类型如下所示。 OCI_HTYPE_SERVER:分配一个OCIServer 结构句柄(连接句柄),该句柄上存放建立的连接句柄。
OCI_HTYPE_SESSION:分配一OCISession结构句柄(连接信息句柄),该句柄上存放建立连接所用的登录信息,比如登录的口令和密码。
OCI_HTYPE_SVCCTX:分配一个OCISvcCtx 结构句柄(上下文句柄),该句柄上存放的 是连接句柄和其他类型句柄的关联信息。 当该句柄调用OCITransCommit或OCITransRollback函数提交或回滚时将会 影响该句柄所在环境句柄上的所有语句句柄SQL操作。
OCI_HTYPE_STMT:分配一个OCIStmt结构 句柄(语句句柄),分配该句柄时,环境句柄上必须已经分配了连接句柄并已经建立 了连接。可以在一个环境句柄上分配多个语句句柄,每个语句句柄可以进行独立的 SQL操作。
OCI_HTYPE_DESCRIBE:分配一个OCIDescribe结构句柄(描述对象句柄), 该句柄可以用来描述某个数据库中的对 象,如表,存贮过程等。通过这个句柄,可以得到对象的具体信息,如表结构中的每个列信息,存贮过程中的每个参数信息。
OCI_HTYPE_ERROR:分配一个OCIError结 构句柄(错误描述句柄),该句柄存放每次 OCI操作失败的原因,通过调用OCIErrorGet函数可以获取到这些信息。
OCI_HTYPE_DIRPATH_CTX:分配一个OCIDirPathCtx结构句柄(直接文件操作句柄),该句柄用于直接文件操作接口。
OCI_HTYPE_DIRPATH_COLUMN_ARRAY:分配一个OCIDirPathColArray结构句柄(直接路径列数组句柄),该句柄用于直接文件操作接口。
OCI_HTYPE_DIRPATH_STREAM:分配一个OCIDirPathStream结构句柄(数据流描述句柄),该句柄用于直接文件操作接口。
xtramem_sz(输入) 保留参数。 usrmempp(输出) 保留参数。 -
注意
此函数调用,错误时没有可用分析的错误诊断信息。*hndlpp本来就指向一个可用且类型匹配的句柄会拒绝分配新的句柄并返回错误。例如:需要分配一个新的语句句柄时,如果 *hndlpp本来就指向一个语句句柄则会分配失败。
-
示例
OCIHandleAlloc((dvoid *)envhpp, (dvoid **)&usrhpp, (ub4)OCI_HTYPE_SESSION, (size_t)0, (dvoid **)0);
3.1.3.OCIHandleFree
-
功能
显式地释放一个句柄。
-
函数
sword OCIHandleFree(void *hndlp, ub4 type) -
参数
OCIHandleFree 参数说明
名称 描述 hndlp(输入) 由OCIHandleAlloc分配的句柄。 type(输入) 要释放的句柄类型。 -
返回值
如果释放成功,返回OCI_SUCCESS,失败返回OCI_ERROR,如果hndlp指向的句柄无效,返回OCI_INVALID_HANDLE。
-
注意
此调用释放与句柄关联的存储空间,对应于type参数中指定的类型。此调用返回OCI_SUCCESS,OCI_INVALID_HANDLE或OCI_ERROR。所有句柄都可以显式释放。释放环境句柄时,会自动释放环境句柄的子句柄(释放除去define句柄、bind句柄、param句柄、环境句柄以外的其它所有句柄)。
-
示例
OCIHandleFree((dvoid *)servhpp, OCI_HTYPE_SERVER);
3.1.4.OCIInitialize
-
功能
初始化OCI应用环境。
-
函数
sword OCIInitialize(ub4 mode, dvoid *ctxp, dvoid *(*malocfp)(dvoid *ctxp, size_t size), dvoid *(*ralocfp)(dvoid *ctxp, dvoid *memptr, size_t newsize), void (*mfreefp)(dvoid *ctxp, dvoid *memptr)) -
参数
OCIInitialize 参数说明
名称 描述 ctxp(输入/输出) 用户定义上下文。 mode(输入) 初始化模式。取值如下: OCI_DEFAULT:缺省模式。
malocfp(输入) 保留参数。 ralocfp(输入) 保留参数。 mfreefp(输入) 保留参数。 memptr(输入/输出) 内存块的指针。 -
示例
OCIInitialize((ub4)OCI_DEFAULT, (dvoid *)0, (dvoid * (*)(dvoid *, size_t))0, (dvoid * (*) (dvoid *, dvoid *, size_t))0, (void (*)(dvoid *, dvoid *))0);
3.1.5.OCIEnvInit
-
功能
分配并初始化环境句柄。
-
函数
sword OCIEnvInit((OCIEnv **envhp, ub4 mode, size_t xtramem_sz, dvoid **usrmempp) -
参数
OCIEnvInit 参数说明
名称 描述 mode(输入) 初始化模式,如下所示。 OCI_DEFAULT:缺省模式。
OCI_ENV_NO_UCB:在环境初始化时,禁止使用动态回调函数OCIEnvCallback()。
xtramem_sz(输入) 指定要在环境持续时间内分配的用户内存大小。 envhp(输出) 指向环境句柄的指针。 usrmempp(输出) 返回一个指向用户内存的指针,该内存大小xtramemsz由用户在环境持续时间内为用户分配。 -
注意
当调用该函数初始化一个环境句柄以后,必须调用OCIHandleFree来释放这个句柄。当环境句柄分配以后,只允许在这个句柄上分配一个上下文句柄,并只允许建立一个连接。*envhpp本来就指向一个可用的环境句柄会拒绝分配新的环境句柄并返回OCI_ERROR。仅可以申请一个环境句柄,重复申请环境句柄会拒绝分配新的环境句柄并返回OCI_ERROR。
-
示例
OCIEnvInit(&env, (ub4)OCI_DEFAULT, (size_t)0, (dvoid **)0);
3.1.6.OCIDescriptorAlloc
-
功能
分配空间以保存描述符或者LOB定位符。
-
函数
sword OCIDescriptorAlloc(CONST dvoid *parenth, dvoid **descpp, CONST ub4 type, CONST size_t xtramem_sz, dvoid **usrmempp) -
参数
OCIDescriptorAlloc 参数说明
名称 描述 parenth(输入) 环境句柄。 descpp(输出) 返回所需类型的描述符或LOB定位器。 type(输入) 描述符类型,如下所示。 OCI_DTYPE_LOB:大字段描述。
OCI_DTYPE_NUMBER:数字描述。
OCI_DTYPE_INTERVAL_YM:年月类型时间间隔。
OCI_DTYPE_INTERVAL_DS:天秒类型时间间隔。
OCI_DTYPE_DATE:日期。
OCI_DTYPE_TIME:不带时区的时间。
OCI_DTYPE_TIME_TZ:带时区的时间。
OCI_DTYPE_TIMESTAMP:不带时区的时间戳。
OCI_DTYPE_TIMESTAMP_TZ:带时区的时间戳。
OCI_DTYPE_TIMESTAMP_LTZ:本地时区的时间戳。
xtramem_sz(输入) 保留参数。 usrmempp(输入) 保留参数。 -
注意
错误时没有可用的诊断,成功:OCI_SUCCESS,发生内存不足错误:OCI_ERROR。*descpp本来就指向一个可用的描述句柄会拒绝分配新的描述句柄并返回错误。
-
示例
OCIDescriptorAlloc(envhp, (dvoid **)lobsrc, (ub4)OCI_DTYPE_LOB, (size_t)0, (dvoid **)0);
3.1.7.OCIDescriptorFree
-
功能
释放之前分配的描述符。
-
函数
sword OCIDescriptorFree(dvoid *descp, CONST ub4 type); -
参数
OCIDescriptorFree 参数说明
名称 描述 descp(输入) 分配的描述符。 type(输入) 描述符类型,如下所示。 OCI_DTYPE_LOB:大字段描述。
OCI_DTYPE_NUMBER:数字描述。
OCI_DTYPE_INTERVAL_YM:年月类型时间间隔。
OCI_DTYPE_INTERVAL_DS:天秒类型时间间隔。
OCI_DTYPE_DATE:日期。
OCI_DTYPE_TIME:不带时区的时间。
OCI_DTYPE_TIME_TZ:带时区的时间。
OCI_DTYPE_TIMESTAMP:不带时区的时间戳。
OCI_DTYPE_TIMESTAMP_TZ:带时区的时间戳。
OCI_DTYPE_TIMESTAMP_LTZ:本地时区的时间戳。
-
注意
此调用释放与描述符关联的存储。返回OCI_SUCCESS或OCI_INVALID_HANDLE。所有描述符都可以显式释放。
-
示例
OCIDescriptorFree((dvoid *) lobp[0], (ub4)OCI_DTYPE_LOB);
3.2.属性
3.2.1.OCIAttrSet
-
功能
设置句柄或者描述符的属性。
-
函数
sword OCIAttrSet(dvoid *trgthndlp, ub4 trghndltyp, dvoid *attributep, ub4 size, ub4 attrtype, OCIError *errhp) -
参数
OCIAttrSet 参数说明
名称 描述 trgthndlp(输入) 指向属性被修改的句柄的指针。 trghndltyp(输入) trgthndlp参数句柄的类型,类型如下所示。 OCI_HTYPE_SVCCTX:上下文句柄。
OCI_HTYPE_SESSION:连接信息句柄。
OCI_HTYPE_DIRPATH_CTX:直接文件操作句柄。
OCI_DTYPE_PARAM:参数句柄。
attributep(输入) 指向属性值的指针。属性值被复制到目标句柄中。如果属性值是指针,则只复制指针,而不复制指针的内容。具体如下文所示。 size(输入) attributep参数的大小,如果attributep参数指针是一个字符串类型指针,那么size就是该字符串的实际长度;如果attributep参数是其他类型指针,则忽略该参数。 attrtype(输入) 要设置的句柄属性。不同类型的句柄有这不同的属性,具体如下文所示。 errhp(输入/输出) 出现错误时可以传递给OCIErrorGet()诊断信息的错误句柄。 attributep指要设置的属性值指针,如下所示是各种属性情况下的数据值类型。
OCIAttrSet-attributep 参数说明
属性值 可选值 OCI_HTYPE_SVCCTX OCI_ATTR_SERVER:OCIServer结构句柄(连接句柄)。
OCI_ATTR_SESSION:OCISession结构句柄(连接信息句柄)。
OCI_HTYPE_SESSION OCI_ATTR_USERNAME:字符串指针(char*)。
OCI_ATTR_PASSWORD:字符串指针(char*)。
OCI_HTYPE_STMT OCI_ATTR_PREFETCH_ROWS:无符号整形指针(ub4*)。
OCI_HTYPE_DIRPATH_CTX OCI_ATTR_NAME: 字符串指针(char*)。
OCI_ATTR_SCHEMA_NAME: 字符串指针(char*)。
OCI_ATTR_DIRPATH_INPUT: 无符号整形指针(ub1*)。
OCI_ATTR_BUF_SIZE: 无符号整形指针(ub4*)。
OCI_DTYPE_PARAM OCI_ATTR_NAME: 字符串指针(char*)。
OCI_ATTR_DATA_TYPE: 无符号整形指针(ub2*)。
OCI_ATTR_PREFETCH_ROWS:无符号整形指针(ub4*)。
attrtype不同类型的句柄有着不同的属性,如下所示。
OCIAttrSet-attrtype 参数说明
属性值 可选值 OCI_HTYPE_SVCCTX OCI_ATTR_SERVER:在上下文句柄上附加一个连接句柄。
OCI_ATTR_SESSION:在上下文句柄上附加一个连接信息句柄。
OCI_HTYPE_SESSION OCI_ATTR_USERNAME:在连接信息句柄上设置登录的用户名。
OCI_ATTR_PASSWORD:在连接信息句柄上设置登录的口令。
OCI_HTYPE_STMT OCI_ATTR_PREFETCH_ROWS:设置预取值,如果设置的预取值大于执行语句结果的总条数,最多只能取出执行语句结果的总条数;如果设置预取值小于执行语句结果的总条数,最多只能取出设置的预取值大小的条数,当再去取得时候会返回OCI_NO_DATA。
OCI_HTYPE_DIRPATH_CTX OCI_ATTR_NAME: 在直接文件操作句柄上设置操作的表名。
OCI_ATTR_SCHEMA_NAME: 在直接文件操作句柄上设置模式名。
OCI_ATTR_DIRPATH_INPUT: 在直接文件操作句柄上设置输入类型。
OCI_ATTR_BUF_SIZE: 在直接文件操作句柄上设置缓冲区大小。
OCI_DTYPE_PARAM OCI_ATTR_NAME: 在参数句柄上设置操作的列名。
OCI_ATTR_DATA_TYPE: 在参数句柄上设置操作的列类型。
OCI_ATTR_DATA_SIZE: 在参数句柄上设置操作的列取值范围。
-
注意
OCI_ATTR_PREFETCH_ROWS属性只能在OCIStmtPrepare和OCIStmtExecute之间进行设置,否则会返回OCI_ERROR。
-
示例
OCIAttrSet((dvoid *)usrhpp, (ub4)OCI_HTYPE_SESSION, (dvoid *)user, (ub4)strlen(user), (ub4)OCI_ATTR_USERNAME, errhpp);
3.2.2.OCIParamGet
-
功能
返回一个描述句柄或语句句柄中指定位置的参数描述符。
-
函数
sword OCIParamGet(CONST dvoid *hndlp, ub4 htype, OCIError *errhp, dvoid **parmdpp, ub4 pos) -
参数
OCIParamGet 参数说明
名称 描述 hndlp(输入) 语句句柄或描述句柄。OCIParamGet()函数返回此句柄的参数描述符。 htype(输入) hndlp参数句柄的类型,支持以下两种类型。 OCI_HTYPE_STMT:语句句柄。
OCI_DTYPE_PARAM:参数句柄。
pos(输入) 语句句柄或描述句柄中的位置编号,为该位置返回一个参数描述符。 errhp(输入) 出现错误时可以传递给OCIErrorGet()诊断信息的错误句柄。 parmdpp(输出) 输出的描述符句柄,通过该句柄调用OCIAttrGet 函数就可以得到指定位置上的描述信息。 -
示例
OCIParamGet((void *)ph->phOCIstmt, OCI_HTYPE_STMT, ph->phOCIErr, (void **)¶m, 1);
3.2.3.OCIAttrGet
-
功能
获取一个句柄的属性。
-
函数
sword OCIAttrGet(CONST dvoid *trgthndlp, ub4 trghndltyp, dvoid *attributep, ub4 *size, ub4 attrtype, OCIError *errhp) -
参数
OCIAttrGet 参数说明
名称 描述 trgthndlp(输入) 指向句柄类型的指针。实际句柄可以是语句句柄、会话句柄等,当此调用用于获取编码时,允许用户检查环境或语句句柄。 trghndltyp(输入) trgthndlp参数中的句柄类型,类型如下所示。 OCI_DTYPE_PARAM:参数句柄。
OCI_HTYPE_STMT:语句句柄。
OCI_HTYPE_DESCRIBE:描述句柄。
OCI_HTYPE_DIRPATH_CTX:直接文件操作句柄。
attributep(输出) 指向属性值存储的指针。 size(输出) 仅兼容,无实际意义。 attrtype(输入) 属性类型。不同类型的句柄有不同属性可以获取。具体如下文所示。 errhp(输入/输出) 出现错误时可以传递给OCIErrorGet()诊断信息的错误句柄。 attrtype在不同的输入句柄上的属性取值,如下所示。
OCIAttrGet-attrtype 参数说明
属性值 可选值 OCI_DTYPE_PARAM OCI_HTYPE_RESULT_COL_ATTR
OCI_ATTR_DATA_SIZE:列的数据类型大小(ub2)。
OCI_ATTR_DATA_TYPE:列的数据类型(ub2)。
OCI_ATTR_NAME:列名(char*)。
OCI_ATTR_PRECISION:列的精度(ub2)。
OCI_ATTR_SCALE:列的刻度(ub1)。
OCI_ATTR_IS_NULL:列是否允许为空(ub1)。
OCI_PTYPE_TABLE
OCI_ATTR_OBJID:表的ID号(ub4)。
OCI_ATTR_NUM_COLS:表中的列数(ub2)。
OCI_ATTR_LIST_COLUMNS:表中列信息的描述参数句柄(void*)。
OCI_ATTR_LIST_COLUMNS
同OCI_HTYPE_RESULT_COL_ATTR属性
OCI_PTYPE_PROC
OCI_ATTR_DATA_SIZE:参数的数据类型大小(ub2)。
OCI_ATTR_DATA_TYPE:参数的数据类型(ub2)。
OCI_ATTR_NAME:参数名(char*)。
OCI_ATTR_PRECISION:参数的精度(ub1)。
OCI_ATTR_SCALE:参数的刻度(ub1)。
OCI_ATTR_NUM_PARAMS:参数的个数(ub2)。
OCI_ATTR_LIST_ARGUMENTS:参数的描述参数句柄(void*)。
OCI_PTYPE_FUNC
同OCI_PTYPE_PROC
OCI_PTYPE_VIEW
OCI_ATTR_OBJID:视图的ID号(ub4)。
OCI_ATTR_NUM_COLS:视图中的列数(ub2)。
OCI_ATTR_LIST_COLUMNS:视图中列信息的描述参数句柄(void*)。
OCI_PTYPE_TYPE
OCI_ATTR_OBJID:类型的ID号(ub4)。
OCI_PTYPE_SCHEMA
OCI_ATTR_OBJID:模式的ID号(ub4)。
OCI_PTYPE_DATABASE
OCI_ATTR_OBJID:数据库的ID号(ub4)。
OCI_HTYPE_STMT OCI_ATTR_NUM_COLS:结果集中列的个数(ub2)。
OCI_ATTR_ROW_COUNT:已经返回记录的总行数(ub4)。
OCI_HTYPE_DESCRIBE OCI_ATTR_PARAM:获取参数句柄。
OCI_HTYPE_DIRPATH_CTX OCI_ATTR_LIST_COLUMNS: 在直接文件操作句柄上获取参数句柄(OCIParam*)。
-
注意
此调用用于获取句柄的特定属性。OCI_DTYPE_PARAM用于进行隐式和显式描述。参数描述符也用于直接路径加载。对于隐式描述,参数描述符具有每个选择列表的列描述。对于显式描述,参数描述符具有描述的每个模式对象的描述信息。
-
示例
OCIAttrGet(param, OCI_DTYPE_PARAM, &colname, &size, OCI_ATTR_NAME, ph- >phOCIErr);
3.2.4.OCIDescribeAny
-
功能
连续写入内容到一个大字段存储描述符中。
-
函数
sword OCIDescribeAny (OCISvcCtx *svchp, OCIError *errhp, dvoid *objptr, ub4 objptr_len, ub1objptr_typ, ub1 info_level, ub1 objtyp, OCIDescribe *dschp); -
参数
OCIDescribeAny 参数说明
名称 描述 svchp(输入) 上下文句柄指针。 errhp(输入/输出) 错误信息句柄。 objptr(输入) 要被描述的对象指针,目前只支持字符串类型指针。 objnm_len(输入) objptr参数中字符串的长度。 objptr_typ(输入) objptr指针类型,目前只支持OCI_OTYPE_NAME–对象名称类型指针。 info_level(输入) 保留参数。 objtyp(输入) objtyp参数所指的对象类型,可以为下面几种对象。 OCI_PTYPE_TABLE:表
OCI_PTYPE_PROC:过程
OCI_PTYPE_FUNC:函数
OCI_PTYPE_VIEW:视图
OCI_PTYPE_TYPE:类型
OCI_PTYPE_SCHEMA:模式
OCI_PTYPE_DATABASE:数据库
dschp(输入/输出) 一个描述符句柄,该句柄可以通过使用OCI_HTYPE_DESCRIBE。作为参数调用 OCIHandleAlloc分配得到。 -
返回值
成功返回OCI_SUCCESS,失败返回OCI_ERROR。
-
注意
OCI支持对象描述
句柄 描述 OCI_PTYPE_TABLE 表 OCI_PTYPE_PROC 存储过程 OCI_PTYPE_FUNC 函数 OCI_PTYPE_VIEW 视图 OCI_PTYPE_TYPE 类型 OCI_PTYPE_SCHEMA 模式 OCI_PTYPE_DATABASE 数据库 -
示例
OCIDescribeAny(ph->phOCISvctx, ph->phOCIErr, (dvoid *)objptr, objp_len, OCI_OTYPE_NAME, 0, OCI_PTYPE_TABLE, dschp);
3.2.5.OCIServerVersion
-
功能
获取版本信息。
-
函数
sword OCIServerVersion(dvoid *hndlp, OCIError *errhp, text *bufp, ub4 bufsz, ub1 hndltype) -
参数
OCIServerVersion 参数说明
名称 描述 hndlp(输入) 服务上下文句柄或服务器上下文句柄。 bufsz(输入) 缓冲区的长度(以字节数为单位)。 hndltype(输入) 传递给函数的句柄类型。 errhp(输入) 出现错误时可以传递给OCIErrorGet()诊断信息的错误句柄。 bufp(输入) 返回版本信息的缓冲区。 -
示例
OCIServerVersion(ph->phOCISvctx, ph->phOCIErr, buff, BUFF_SIZE, OCI_HTYPE_SVCCTX);
3.3.连接
3.3.1.OCIServerAttach
-
功能
将一个数据库服务挂载到一个指定的连接句柄上。
-
函数
sword OCIServerAttach(OCIServer *srvhp, OCIError *errhp, CONST OCIText *dblink, sb4 dblink_len, ub4 mode) -
参数
OCIServerAttach 参数说明
名称 描述 srvhp(输入) 一个未初始化的服务器句柄,由此处初始化。 errhp(输入) 出现错误时可以传递给OCIErrorGet()诊断信息的错误句柄。 dblink(输入) 指定要使用的数据库服务器。此参数指向指定连接字符串或服务点的字符串。如果连接字符串是NULL,返回OCI_ERROR。 dblink_len(输入) dblink的长度,对于有效的连接字符串名称或别名,dblink_len必须非零。它的值以字节数为单位。 mode(输入) 指定操作模式。仅支持OCI_DEFAULT。 -
示例
OCIServerAttach(srvhp, errhp, (text *)dbname, strlen(dbname), OCI_DEFAULT);
3.3.2.OCIServerDetach
-
功能
删除OCI操作对一个数据源的访问。
-
函数
sword OCIServerDetach(OCIServer *srvhp, OCIError *errhp, ub4 mode) -
参数
OCIServerDetach 参数说明
名称 描述 srvhp(输入) 初始化服务器上下文的句柄,它被重置为未初始化状态。 errhp(输入/输出) 出现错误时可以传递给OCIErrorGet()诊断信息的错误句柄。 mode(输入) 附加模式。仅支持OCI_DEFAULT。 -
示例
OCIServerDetach(servhpp, errhpp, OCI_DEFAULT);
3.3.3.OCISessionBegin
-
功能
创建并开始一个用户会话。
-
函数
sword OCISessionBegin(OCISvcCtx *svchp, OCIError *errhp, OCISession *usrhp, ub4 credt, ub4 mode) -
参数
OCISessionBegin 参数说明
名称 描述 svchp(输入) 服务上下文的句柄,必须设置且需有效。 credt(输入) 登录的方式,OCI_CRED_RDBMS:通过用户名和口令与数据库服务建立起连接。 mode(输入) 指定操作模式,有效模式如下所示。 OCI_DEFAULT:在此模式下,返回的用户会话上下文只能使用svchp指定的服务器上下文进行设置。
errhp(输入) 出现错误时可以传递给OCIErrorGet()诊断信息的错误句柄。 usrhp(输入) 用户会话上下文的句柄,由此调用初始化。 -
示例
OCISessionBegin(svchpp, errhpp, usrhpp, OCI_CRED_RDBMS, (ub4)OCI_DEFAULT);
3.3.4.OCISessionEnd
-
功能
终止OCISessionBegin() 函数所创建的用户会话。
-
函数
sword OCISessionEnd(OCISvcCtx *svchp, OCIError *errhp, OCISession *usrhp, ub4 mode) -
参数
OCISessionEnd 参数说明
名称 描述 usrhp(输入) 取消对该用户的身份验证。如果此参数作为NULL传递,则返回OCI_INVALID_HANDLE。 mode(输入) 连接模式,取值如下: OCI_DEFAULT:缺省模式。
svchp(输入) 服务上下文句柄。必须有一个与关联的有效服务器句柄和用户会话句柄。 errhp(输入) 出现错误时可以传递给OCIErrorGet()诊断信息的错误句柄。 -
示例
OCISessionEnd(svchp, errhp, authp, (ub4) 0);
3.3.5.OCILogon
-
功能
根据用户名和密码,登录到一个指定的数据库服务上,并初始化相关的上下文句柄。当连接建立以后,需要通过调用OCILogoff来断开连接。
-
函数
sword OCILogon(OCIEnv *envhp, OCIError *errhp, OCISvcCtx **svchp, const OCIText *username, ub4 uname_len, const OCIText *password, ub4 passwd_len, const OCIText *dbname, ub4 dbname_len) -
参数
OCILogon 参数说明
名称 描述 envhp(输入) OCI环境句柄。 username(输入) 用户名。 uname_len(输入) 用户名长度。 password(输入) 用户密码。 passwd_len(输入) 密码长度。 dbname(输入) 要连接的数据库名称。其形式为ip:port/databasename或ip:port或ip。 dbname_len(输入) 数据库名称长度。 errhp(输入/输出) 出现错误时可以传递给OCIErrorGet()诊断信息的错误句柄。 svchp(输入/输出) 服务上下文指针。如果指定的上下文句柄非空,那么在登录以后,会自动设置相关的连接句柄到该句柄上。如果指定的上下文句柄为空,那么 OCI 会自动分配一个上下文句柄输出,该上下文句柄不需调用 OCIHandleFree 释放;当应用调用 OCILogoff 以后,OCI会自动释放这个句柄。 -
注意
此函数用于为应用程序创建一个简单的登录会话。
-
示例
OCILogon(env, error, &hdbc, usname, sizeof(dbname), pwd, sizeof(pwd), dbname, sizeof(dbname));
3.3.6.OCILogoff
-
功能
断开通过OCILogon与服务器建立的连接。
-
函数
sword OCILogoff(OCISvcCtx *svchp, OCIError *errhp) -
参数
OCILogoff 参数说明
名称 描述 svchp(输入) 服务上下文句柄。 errhp(输入/输出) 出现错误时可以传递给OCIErrorGet()诊断信息的错误句柄。 -
注意
在默认情况下,此函数关闭会话或连接。
-
示例
OCILogoff(hdbc, 0);
3.4.错误
3.4.1.OCIErrorGet
-
功能
获取OCI操作失败产生的错误信息。
-
函数
sword OCIErrorGet(dvoid *hndlp, ub4 recordno, OCIText *sqlstate, sb4 *errcodep, OCIText *bufp, ub4 bufsiz, ub4 type) -
参数
OCIErrorGet 参数说明
名称 描述 hndlp(输入) 错误信息句柄或环境信息句柄。 recordno(输入) 指示应用程序从中寻求信息的状态记录。从1开始。 sqlstate(输出) SQL语句执行状态。 errcodep(输出) 返回的错误代码。 bufp(输出) 返回的错误消息文本。 bufsiz(输入) 为错误消息提供的缓冲区的大小,以字节数为单位。 type(输入) 句柄的类型(OCI_HTYPE_ERROR或OCI_HTYPE_ENV)。 -
示例
OCIErrorGet(ph->phOCIErr, 1, sqlstate, &errcodep, (OCIText *)buff, BUFF_SIZE,OCI_HTYPE_ERROR);
3.5.语句
3.5.1.OCIStmtPrepare
-
功能
执行SQL语句而做准备。
-
函数
sword OCIStmtPrepare(OCIStmt *stmtp, OCIError *errhp, OCIText *stmt, ub4 stmt_len, ub4 language, ub4 mode) -
参数
OCIStmtPrepare 参数说明
名称 描述 stmtp(输入) 与要执行的语句关联的语句句柄。 errhp(输入) 出现错误时可以传递给OCIErrorGet()诊断信息的错误句柄。 stmt(输入) 要执行的SQL语句。若准备多条SQL语句,则语句之间用分号隔开。 stmt_len(输入) 语句的长度,以字符或字节数表示,具体取决于编码,不得为0。 language(输入) 保留参数。 mode(输入) 准备模式,取值如下: OCI_DEFAULT:缺省模式。
-
示例
OCIStmtPrepare(stmthpp, errhpp, (text *)sql1, strlen(sql1), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT);
3.5.2.OCIStmtExecute
-
功能
执行通过OCIStmtPrepare准备后的语句。
-
函数
sword OCIStmtExecute(OCISvcCtx *svchp, OCIStmt *stmtp, OCIError *errhp, ub4 iters, ub4 rowoff, const OCISnapshot *snap_in, OCISnapshot *snap_out, ub4 mode) -
参数
OCIStmtExecute 参数说明
名称 描述 svchp(输入) 服务上下文句柄。 stmtp(输入) 一个语句句柄。它定义了要在服务器上执行的语句和相关数据。 errhp(输入) 出现错误时可以传递给OCIErrorGet()诊断信息的错误句柄。 iters(输入) 执行后影响的行数。对非查询语句,该参数表明一次性向服务器发送的数据行数,这个时候,该值必须大于等于1;对于查询语句,如果配置文件的IsFetchOnExecute值为0,此参数被忽略,如果IsFetchOnExecute值为1,将会有iters条数据被放入缓冲区。 rowoff(输入) 行集偏移。对于查询语句,该参数将被忽略;对于非查询语句,该参数表明向服务器发送多行数据时的起始偏移行,从0开始计算。 snap_in(输入) 保留参数。 snap_out(输入) 保留参数。 mode(输入) 执行的模式,如下所示。 OCI_DEFAULT:缺省模式。
OCI_COMMIT_ON_SUCCESS:自动提交模式。当SQL执行以后,会自动提交执行的SQL。
OCI_DESCRIBE_ONLY:描述模式。通过该模式执行准备好的语句,并不是真正的执行语句,而是返回语句中的结果集描述,应用程序可以通过调用OCIAttrGet 函数来获取这些信息。
OCI_EXACT_FETCH:提取模式。当执行完以后,可以从结果集中提取数据。
-
示例
OCIStmtExecute(svchpp, stmthpp, errhpp, (ub4)0, (ub4)0, NULL, NULL, OCI_DEFAULT);
3.5.3.OCIBindByPos
-
功能
创建程序变量和一个SQL语句中的占位符之间的结合。
-
函数
sword OCIBindByPos(OCIStmt *stmtp, OCIBind **bindp, OCIError *errhp, ub4 position, dvoid *valuep, sb4 value_sz, ub2 dty, dvoid *indp, ub2 *alenp, ub2 *rcodep, ub4 maxarr_len, ub4 *curelep, ub4 mode) -
参数
OCIBindByPos 参数说明
名称 描述 stmtp(输入/输出) 正在处理的SQL语句的句柄。 bindp(输入/输出) 输出的绑定信息句柄。可以通过该句柄调用OCIBindArrayOfStruct函数来设定该参数每行的间隔长度。 errhp(输入/输出) 出现错误时可以传递给OCIErrorGet()诊断信息的错误句柄。 position(输入) 如果OCIBindByPos()被调用,则占位符属性由位置指定。位置是从1开始。 valuep(输入/输出) dty参数中指定类型的数据值或数据值数组的地址。可以指定数据值数组为SQL多行操作提供数据。 value_sz(输入) valuep 的最大可能大小(以字节为单位)。 dty(输入) 被绑定值的数据类型。 indp(输入) 保留参数。 alenp(输入) 保留参数。 rcodep(输入) 保留参数。 maxarr_len(输入) 保留参数。 curelep(输入) 保留参数。 mode(输入) 绑定模式,如下所示。 OCI_DEFAULT:缺省模式。
OCI_DATA_AT_EXEC:数据在执行时获取,此时指定的valuep无效(需要搭配OCIStmtSetPieceInfo或者OCIBindDynamic使用,由其指定动态绑定地址或分片绑定地址,如未指定,OCIStmtExecute调用会返回OCI_NEED_DATA)。
-
示例
OCIBindByPos(stmthp, &bndhp[0], errhp, (ub4) 1, (dvoid *) &in1[0], (sb4) sizeof(in1[0]), SQLT_INT, (dvoid *) 0, (ub2 *)0, (ub2 *)0, (ub4) 0, (ub4 *) 0, (ub4) OCI_DEFAULT);
3.5.4.OCIDefineByPos
-
功能
将选择列表中的项目与类型和输出数据缓冲区相关联。
-
函数
sword OCIDefineByPos(OCIStmt *stmtp, OCIDefine **defnp, OCIError *errhp, ub4 position, dvoid *valuep, sb4 value_sz, ub2 dty, dvoid *indp, ub2 *rlenp, ub2 *rcodep, ub4 mode) -
参数
OCIDefineByPos 参数说明
名称 描述 stmtp(输入) 请求的SQL查询操作的句柄。 defnp(输入/输出) 绑定结构输出指针。 errhp(输入/输出) 出现错误时可以传递给OCIErrorGet()诊断信息的错误句柄。 position(输入) 此值在选择列表中的位置。位置从1开始,从左到右编号。 valuep(输入/输出) 指向dty参数中指定类型的缓冲区或缓冲区数组的指针。 value_sz(输入) 每个valuep缓冲区的大小(以字节为单位)。 dty(输入) 数据类型。 indp(输入) 指示符缓冲区,如果结果集中存在NULL值,那么OCI会回填该缓冲区,把对应的位置置为-1,其他情况下置 0;如果在绑定的时候,未设置该指示符缓冲区,但是获取的结果中又存在 NULL 值,结果集提取时会返回OCI_ERROR的错误 rlenp(输入/输出) 返回值长度指示缓冲区,如果返回值未发生 截断,那么该缓冲区中的值就是实际的返回值长度;如果返回值在获取的时候发生了截断,那么该缓冲区的值就是未截断以前的长度;如果返回值是空值,该缓冲区的值将被置为 0。 rcodep(输入) 保留参数。 mode(输入) 绑定模式,如下所示。 OCI_DEFAULT:缺省模式。
OCI_DYNAMIC_FETCH:动态提取,此时指定的valuep无效(需要搭配OCIStmtGetPieceInfo、OCIStmtSetPieceInfo或者OCIBindDynamic使用,由其指定动态绑定地址或分片绑定地址,如未指定,OCIStmtFetch、OCIStmtFetch2调用会返回OCI_NEED_DATA)。
-
示例
OCIDefineByPos(stmthpp, &bhp2, errhpp, 2, (dvoid *)&val, sizeof(val), SQLT_INT, NULL,&datalen, NULL, OCI_DEFAULT);
3.5.5.OCIStmtFetch
-
功能
获取查询的结果。
-
函数
sword OCIStmtFetch(OCIStmt *stmtp, OCIError *errhp, ub4 nrows, ub2 orientation, ub4 mode) -
参数
OCIStmtFetch 参数说明
名称 描述 stmtp(输入) 请求的SQL查询操作的句柄。 errhp(输入) 出现错误时可以传递给OCIErrorGet()诊断信息的错误句柄。 nrows(输入) 要从当前位置获取的行数。 orientation(输入) 行集提取的方式,可以有以下几种方式。 OCI_FETCH_NEXT:从当前游标位置向下进行提取操作。
OCI_FETCH_FIRST:从结果集的第一行开始向下进行提取操作。
OCI_FETCH_LAST:从结果集的最后一行开始向下提取操作。
OCI_FETCH_PRIOR:从结果集的当前游标位置向上进行提取操作。
mode(输入) 提取模式,取值为OCI_DEFAULT:缺省模式。 -
注意
如果语句句柄设置了预取值属性时,并且预取值小于执行语句结果集条数,那么最多只能取到预取值大小的条数,当获取的条数大于预取值时会返回OCI_NO_DATA。当需要一次获取多行数据值时,取到的实际条数如果小于nrows会返回OCI_NO_DATA。
-
示例
OCIStmtFetch(stmthpp, errhpp, 1, OCI_FETCH_NEXT, OCI_DEFAULT);
3.5.6.OCIStmtFetch2
-
功能
获取SQL语句生成的(可滚动)结果集中的一行。可用该函数替代OCIStmtFetch()函数。
-
函数
sword OCIStmtFetch2(OCIStmt *stmtp, OCIError *errhp, ub4 nrows, ub2 orientation, sb4 fetchOffset, ub4 mode) -
参数
OCIStmtFetch2 参数说明
名称 描述 stmtp(输入) 结果集语句句柄。 errhp(输入) 出现错误时可以传递给OCIErrorGet()诊断信息的错误句柄。 nrows(输入) 要从当前位置获取的行数。 orientation(输入) 行集提取的方式,可以有以下几种方式。 OCI_DEFAULT:与OCI_FETCH_NEXT作用相同。
OCI_FETCH_CURRENT:提取当前行。
OCI_FETCH_NEXT:提取当前游标指针位置后的数据行。默认为该方式(与OCI_DEFAULT相同),用于不可滚动的语句句柄。
OCI_FETCH_FIRST:取结果集的第一行。
OCI_FETCH_LAST:取结果集的最后一行。
OCI_FETCH_PRIOR:提取结果集中当前游标指针位置之前的数据行。
OCI_FETCH_ABSOLUTE:获取结果集中的绝对行号(由fetchOffset参数指定)。
OCI_FETCH_RELATIVE:获取结果集中的相对行号(由fetchOffset参数指定) 。
fetchOffset(输入) 和orientation参数一起来改变当前行的位置。 mode(输入) 提取模式,取值为OCI_DEFAULT:缺省模式。 -
注意
如果语句句柄设置了预取值属性时,并且预取值小于执行语句结果集条数,那么最多只能取到预取值大小的条数,当获取的条数大于预取值时会返回OCI_NO_DATA。当需要一次获取多行数据值时,取到的实际条数如果小于nrows会返回OCI_NO_DATA。
该调用与 OCIStmtFetch()调用类似,只是多了参数fetchOffset。它可以用于所有的语句句柄,不论是否可滚动。对于一个不可滚动的语句句柄,orientation参数只能取 OCI_FETCH_NEXT,忽略偏移量fetchOffset。
orientation 设置为 OCI_FETCH_RELATIVE 时偏移量fetchOffset等效值如下所示。
-
OCI_FETCH_CURRENT:偏移量的值为0。
-
OCI_FETCH_NEXT:偏移量的值为1。
-
OCI_FETCH_PRIOR:偏移量的值为-1。
-
OCI_ATTR_ROW_COUNT的值为获取的最大绝对行号。
所有其他orientation模式,除了OCI_FETCH_ABSOLUTE与OCI_FETCH_RELATIVE之外都忽略fetchOffset值。
该调用也可以通过使用OCI_FETCH_LAST,然后以OCI_ATTR_CURRENT_POSITION方式调用OCIAttrGet()函数来获取结果集中的行数。
该函数返回值与OCIStmtFetch相同。除了返回代码OCI_NO_DATA,每一次对于可滚动语句句柄的提取(或执行)操作完成后,并不是应用程序需要的所有行都被返回,此时会发送错误返回代码。
可滚动的语句句柄需要被显式地撤销(即提取0行)或释放,从而才能释放当前滚动游标所占用的服务器资源。不可滚动的语句句柄在收到错误代码后会自动释放。
使用OCI_ATTR_ROWS_FETCHED可获取最后一次成功提取到用户缓冲区中的行数。
-
-
示例
OCIStmtFetch2(stmthpp, errhpp, 1, OCI_FETCH_NEXT, 1,OCI_DEFAULT);
3.5.7.OCIBindByName
-
功能
创建程序变量和一个SQL语句中的占位符之间的结合。
-
函数
sword OCIBindByName(OCIStmt *stmtp, OCIBind **bindpp, OCIError *errhp, CONST OCIText *placeholder, sb4 placeh_len, dvoid *valuep, sb4 value_sz, ub2 dty, dvoid *indp, ub2 *alenp, ub2 *rcodep, ub4 maxarr_len, ub4 *curelep, ub4 mode) -
参数
OCIBindByName 参数说明
名称 描述 stmtp(输入/输出) 绑定影响的语句句柄。 bindp(输入/输出) 输出的绑定信息句柄。可以通过该句柄调用OCIBindArrayOfStruct函数来设定该参数每行的间隔长度。 errhp(输入/输出) 错误信息句柄,是传给函数OCIErrorGet()处理获取诊断信息的句柄。 placeholder(输入) 绑定的参数名称。 placeh_len(输入) 参数名称的长度。 valuep(输入/输出) 参数值缓冲区指针。 value_sz(输入) 参数类型单个值的大小。 dty(输入) 参数的数据类型。 indp(输入/输出) 指示器变量或数组的指针。 alenp(输入) 保留参数。 rcodep(输入) 保留参数。 maxarr_len(输入) 保留参数。 curelep(输入) 保留参数。 mode(输入) 绑定模式,取值如下所示。 OCI_DEFAULT:缺省模式。
OCI_DATA_AT_EXEC:数据在执行时获取,此时指定的valuep无效(需要搭配OCIStmtSetPieceInfo或者OCIBindDynamic使用,由其指定动态绑定地址或分片绑定地址,如未指定,OCIStmtExecute调用会返回OCI_NEED_DATA)。
-
注意
当不再需要分配的缓冲区时,它们应该由客户端释放。
-
示例
OCIBindByName(ph->phOCIstmt, &bhp[1], ph->phOCIErr, ":Vdata2", strlen(":Vdata2"), raw2, sizeof(raw2), SQLT_BIN, 0,0,0,0,0, OCI_DEFAULT);
3.5.8.OCIBindArrayOfStruct
-
功能
指定参数绑定时,每个参数项中值的间隔大小,以字节计算(以数组方式进行参数绑定)。
-
函数
sword OCIBindArrayOfStruct(OCIBind *bindp, OCIError *errhp, ub4 pvskip, ub4 indskip, ub4 alskip, ub4 rcskip) -
参数
OCIBindArrayOfStruct 参数说明
名称 描述 bindp(输入) 参数绑定结构指针,它来自OCIBindByName或OCIBindByPos的参数绑定函数输出。 errhp(输入) 错误信息句柄,是传给函数OCIErrorGet()处理获取诊断信息的句柄。 pvskip(输入) 参数值下一个值的间隔长度。在多行绑定时,可以通过指定该参数来找到下一行值所在的位置。 indskip(输入) 参数值下一个指示器或结构的间隔长度。 alskip(输入) 参数值下一个实际长度的间隔长度。 rcskip(输入) 参数值下一个列级返回码值的间隔值。 -
示例
OCIBindArrayOfStruct(bndhp[0], errhp, s1, indsk[0], rlsk[0], rcsk[0]);
3.5.9.OCIDefineArrayOfStruct
-
功能
指定行集中每一列中每行值存贮位置间隔的大小,以字节计算(以数组方式进行参数绑定)。
-
函数
sword OCIDescribeAny (OCIDefine* defnp, OCIError* errhp, ub4 pvskip, ub4 indskip, ub4 alskip, ub4 rcskip); -
参数
OCIDefineArrayOfStruct 参数说明
名称 描述 defnp(输入) 参数定义结构指针,它来自OCIDefineByName或OCIDefineByPos的参数绑定函数输出。 errhp(输入) 错误信息句柄,是传给函数OCIErrorGet()处理获取诊断信息的句柄。 pvskip(输入) 参数值下一个值的间隔长度。在多行输出绑定时,可以通过指定该参数来找到下一行值所在的位置。 indskip(输入) 参数值下一个指示器或结构的间隔长度。 alskip(输入) 参数值下一个实际长度的间隔长度。 rcskip(输入) 保留参数。 -
示例
OCIDefineArrayOfStruct(defnp [0], errhp, s1, indsk[0], rlsk[0], rcsk[0]);
3.5.10.OCIStmtSetPieceInfo
-
功能
设置分片信息。
-
函数
sword OCIStmtSetPieceInfo ( dvoid *hndlp, ub4 type, OCIError *errhp, CONST dvoid *bufp, ub4 *alenp, ub1 piece, CONST dvoid *indp, ub2 *rcodep ); -
参数
表 OCIStmtSetPieceInfo 参数说明
名称 描述 hndlpp(输入/输出) 绑定/定义句柄。 type(输入) 句柄的类型。 errhp(输出) 错误句柄,调用失败时,可通过OCIErrorGet()可获取错误诊断信息。 bufp(输入/输出) 当bufp作为输入型绑定变量时,它是指向一个存储包含数值或分段信息的存储空间的指针;作为输出型绑定或定义变量时,它指向一个获取分段信息或数值的存储空间。 alenp(输入/输出) 分段信息或值的字节长度。 piecep(输入) 分段参数,仅用于输入绑定变量,取值如下所示。 OCI_ONE_PIECE
OCI_FIRST_PIECE
OCI_NEXT_PIECE
OCI_LAST_PIECE
indp(输入/输出) 仅做兼容。 rcodep(输入/输出) 仅做兼容。 -
注意
-
仅允许1行数据做分片。
-
如果还有分片数据执行OCISmtExecute、OCIStmtFetch、OCIStmtFetch2会返回OCI_NEED_DATA。
-
-
示例
OCIStmtSetPieceInfo((dvoid *)defnp[1], (ub4)hdltype, error, (dvoid *)bufout, &alenp, piece, (dvoid *)&indptr, &rcode);
3.5.11.OCIStmtGetPieceInfo
-
功能
获取分片信息。
-
函数
sword OCIStmtGetPieceInfo ( CONST OCIStmt *stmtp, OCIError *errhp, dvoid **hndlpp, ub4 *typep, ub1 *in_outp, ub4 *iterp, ub4 *idxp, ub1 *piecep ); -
参数
OCIStmtGetPieceInfo 参数说明
名称 描述 stmthp(输入) 语句句柄。 errhp(输出) 错误句柄,调用失败时,可通过OCIErrorGet()可获取错误诊断信息。 hndlpp(输出) 返回一个指向绑定或定义句柄的指针,该句柄提供或需要当前的运行数据。 typep(输出) 需要分片输出返回OCI_HTYPE_DEFINE。 in_outp(输出) 需要分片输出返回 OCI_PARAM_OUT。 iterp(输出) 仅做兼容。 idxp(输出) 仅做兼容。 piecep(输出) 返回以下值中的一个:OCI_FIRST_PIECE,OCI_NEXT_PIECE。 -
注意
仅允许1行数据做分片。
-
示例
OCIStmtGetPieceInfo(stmt, error, (void **)&defnp[1], &hdltype,&in_out, &iter, &idx, &piece);
3.5.12.OCIBindDynamic
-
功能
通过回调函数动态数据绑定。
-
函数
sword OCIBindDynamic(OCIBind *bindp, OCIError *errhp, dvoid *ictxp, OCICallbackInBind (icbfp)(/*_ dvoid *ictxp, OCIBind *bindp, ub4 iter, ub4 index, dvoid **bufpp, ub4 *alenp, ub1 *piecep, dvoid **indpp */), dvoid *octxp, OCICallbackOutBind(ocbfp)(/*_ dvoid *octxp, OCIBind *bindp, ub4 iter, ub4 index, dvoid **bufpp, ub4 **alenpp, ub1 *piecep, dvoid **indpp, ub2 **rcodepp _*/); -
参数
OCIBindDynamic 参数说明
名称 描述 bindp(IN/OUT) 绑定信息句柄(通过调用OCIBindByName或者OCIBindByPos获得)。 errhp(IN/OUT) 错误句柄。 ictxp(IN/OUT) 绑定输入回调函数所需的上下文指针。 icbfp(IN) 指向IN的回调函数。 ictxp(IN) 此回调函数的上下文指针。 bindp(IN) 传入的绑定句柄。 iter(IN) 仅做兼容。 index(IN) 仅做兼容。 bufpp(OUT) 指向缓冲区指针。 alenp(OUT) 用于读取绑定值后填充大小的指针。 piecep(OUT) 仅做兼容。 indpp(OUT) 绑定列的类型指针。 Octxp(IN) 回调函数的上下文指针。 ocbfp(IN) 绑定输出的回调函数。 octxp(IN/OUT) 绑定输出回调函数所需的上下文指针。 bindp(IN) 绑定句柄标识符。 iter(IN) 仅做兼容。 index(IN) 仅做兼容。 bufpp(OUT) 指向缓冲区指针。 alenpp(IN/OUT) 用于读取绑定值后填充大小的指针。 piecep(IN/OUT) 仅做兼容。 indpp(OUT) 绑定列的类型指针。 rcodepp(OUT) 返回内容的指针。 -
返回值
成功返回OCI_SUCCESS,参数非法返回OCI_INCALID_HANDLE,失败返回OCI_ERROR。
-
示例
OCIBindDynamic(bndhp, error, (dvoid *) &pos[0], cbf_no_data, (dvoid *) &pos[0], cbf_get_data);
3.5.13.OCIDefineDynamic
-
功能
如果在OCIDefineByPos中选择了OCI_DYNAMIC_FETCH模式,则调用此接口设置所需的附加属性。
-
函数
sword OCIDefineDynamic(OCIDefine *defnp, OCIError *errhp,dvoid *octxp, OCICallbackDefine(ocbfp)(/*_ dvoid *octxp, OCIDefine *defnp, ub4 iter, dvoid **bufpp, ub4 **alenpp, ub1 *piecep, dvoid **indpp, ub2 **rcodep _*/)); -
参数
表 OCIDefineDynamic 参数说明
名称 描述 defnp(IN/OUT) 定义信息句柄(通过调用OCIDefineByPos获得)。 errhp(IN/OUT) 错误句柄。 octxp(IN/OUT) 回调函数所需的上下文指针。 ocbfp(IN) 回调函数。 octxp(IN) 此回调函数的上下文指针。 defnp(IN) 定义的句柄。 iter(IN) 仅做兼容。 bufpp(OUT) 指向缓冲区的指针,用来存储列值。 alenpp(IN/OUT) 指向缓冲区指针。 piecep(IN/OUT) 仅做兼容。 indpp(OUT) 指针变量。 rcodep(IN) 仅做兼容。 -
返回值
成功返回OCI_SUCCESS,参数非法返回OCI_INCALID_HANDLE,失败返回OCI_ERROR。
-
示例
OCIDefineDynamic(defnp[1], error, (dvoid *) &res_buf, (OCICallbackDefine) cdf_fetch_buffer);
3.6.事务
3.6.1.OCITransCommit
-
功能
提交与指定的服务上下文联系的事务。
-
函数
sword OCITransCommit(OCISvcCtx *svchp, OCIError *errhp, ub4 flags) -
参数
OCITransCommit 参数说明
名称 描述 svchp(输入) 服务上下文句柄。 errhp(输入) 出现错误时可以传递给OCIErrorGet()诊断信息的错误句柄。 flags(输入) 保留参数,用于全局事务中的单阶段提交优化的标志。 -
示例
OCITransCommit(svchpp, errhpp, 0);
3.6.2.OCITransRollback
-
功能
回滚当前事务。
-
函数
sword OCITransRollback(OCISvcCtx *svchp, OCIError *errhp, ub4 flags) -
参数
OCITransRollback 参数说明
名称 描述 svchp(输入) 服务上下文句柄。 errhp(输入) 出现错误时可以传递给OCIErrorGet()诊断信息的错误句柄。 flags(输入) 保留参数。 -
示例
OCITransRollback(svchpp, errhpp, 0);
3.6.3.OCITransStart
-
功能
设置事务开始。
-
函数
sword OCITransStart(OCISvcCtx *svchp, OCIError *errhp, uword timeout, ub4 flags) -
参数
OCITransStart 参数说明
名称 描述 svchp(输入/输出) 服务上下文句柄。 errhp(输入/输出) 出现错误时可以传递给OCIErrorGet()诊断信息的错误句柄。 timeout(输入) 保留参数。 falgs(输入) 指定或者启动一个新的事务或者恢复一个现存的事务。并指定可串行的或只读的状态。可指定一个以上的值。默认情况是启动一个读/写事务。标记值如下所示。 OCI_TRANS_NEW:启动一个新的事务分支。默认情况是启动一个紧耦合的并且可迁移的分支。
OCI_TRANS_READONLY:启动一个只读的事务。
OCI_TRANS_SERIALIZABLE:启动一个可串行化的事务。
OCI_TRANS_RESUME:唤醒一个事务。
-
注意
此函数设置全局或可序列化事务的开始。如果flags参数指定应启动新事务,则当前与服务上下文句柄关联的事务上下文在调用结束时初始化。
-
示例
OCITransStart(svchpp, errhpp, 60, OCI_TRANS_NEW);
3.6.4.OCITransDetach
-
功能
断开一个事务。
-
函数
sword OCITransDetach (OCISvcCtx *svchp, OCIError *errhp, ub4 flags) -
参数
OCITransDetach 参数说明
名称 描述 svchp(输入/输出) 服务上下文句柄。 errhp(输入/输出) 出现错误时可以传递给OCIErrorGet()诊断信息的错误句柄。 falgs(输入) 默认参数:OCI_DEFAULT。 -
示例
OCITransDetach(NULL, error, OCI_DEFAULT);
3.7.大对象
3.7.1.OCILobRead
-
功能
读取LOB或者BFILE的一部分到缓冲区。
-
函数
sword OCILobRead(OCISvcCtx *svchp, OCIError *errhp, OCILobLocator *locp, ub4 *amtp, ub4 offset, dvoid *bufp, ub4 bufl, dvoid *ctxp, OCICallbackLobRead (cbfp) (dvoid *ctxp, CONST dvoid *bufp, ub4 len, ub1 piece), ub2 csid, ub1 csfrm) -
参数
OCILobRead 参数说明
名称 描述 svchp(输入/输出) 服务上下文句柄。 errhp(输入/输出) 出现错误时可以传递给OCIErrorGet()诊断信息的错误句柄。 locp(输入) 一个LOB句柄唯一引用LOB。此LOB句柄必须是从svchp指定的服务器获取的定位器。 amtp(输入/输出) 保留参数。 offset(输入) 在输入时,这是从LOB值开始的绝对偏移量。第一个位置是1。 buf1(输入) 缓冲区的长度每次最多允许读1G(以八位字节为单位)。 ctxp(输入) 回调函数的上下文指针,可以为NULL。 cbfp(输入) 注册的回调函数,可为每个分片调用。若为空,则对每个分片将返回OCI_NEED_DATA。当需要继续读取LOB数据时,回调函数返回值必须是OCI_CONTINUE。若返回错误,则LOB的读将终止。回调函数具有固定的函数原型,以下为函数参数。 ctxp(输入):回调函数的上下文,可以为空。
bufp(输入/输出):指向LOB分片的数据缓冲区的指针。
len(输入):bufp缓冲区中的当前分片的字节长度。
piece(输入):哪一个分片。
csid(输入) 缓冲区数据的字符集ID。 csfrm(输入) 缓冲区数据的字符集表。这个参数必须要和LOB的类型一致。 bufp(输入/输出) 指向读取片段的缓冲区的指针。假定分配的内存长度为bufl。 LOB数据字符数或者字节数
LOB 输入 输出定宽的客户端字符集 输出变宽的客户端字符集 BLOB 字节 字节 字节 CLOB 字符 字符 字节 输入数量指从服务器端CLOB读入的字符数。输出数量指读进缓冲区bufp的字节数。
-
示例
OCILobRead(svchp, errhp, lobp, &amtp, 1, buf+readsize, lenp+1-readsize , (dvoid *) 0, (sb4 (*) (dvoid *, const dvoid *, ub4, ub1))0, (ub2)0, (ub1)SQLCS_IMPLICIT);
3.7.2.OCILobWrite
-
功能
将缓冲区中的数据写入到LOB中。
-
函数
sword OCILobWrite(OCISvcCtx *svchp, OCIError *errhp, OCILobLocator *locp, ub4 *amtp, ub4 offset, dvoid *bufp, ub4 buflen, ub1 piece, dvoid *ctxp, OCICallbackLobWrite (cbfp) (/*dvoid *ctxp, dvoid *bufp, ub4 *lenp, ub1 *piecep */), ub2 csid, ub1 csfrm) -
参数
OCILobWrite 参数说明
名称 描述 svchp(输入/输出) 服务上下文句柄。 errhp(输入/输出) 出现错误时可以传递给OCIErrorGet()诊断信息的错误句柄。 locp(输入) 一个LOB句柄唯一引用LOB。此LOB句柄必须是从svchp指定的服务器获取的定位器。 amtp(输入/输出) 保留参数。 offset(输入) 在输入时,这是从LOB值开始的绝对偏移量。第一个位置是1。 bufp(输入) 指向读取片段的缓冲区的指针。假定分配的内存长度为buflen。 buflen(输入) 缓冲区的长度每次最多允许读1G(以八位字节为单位)。 piece(输入) 保留参数。 ctxp(输入) 回调函数的上下文。 cbfp(输入) 在分片方式写入操作时对每个分片调用注册 的回调函数。当cbfp为空时,将采用询问(polling)方式写入LOB数据。若需要写继续,则回调函数应该返回OCI_CONTINUE。否则将返回错误码,LOB写入操作将被终止。回调函数具有固定的函数原型,以下参数为 该函数参数。 ctxp(输入):回调函数上下文,可以为空。
bufp(输入/输出):指向LOB分片数据缓冲区的指针。该参数与传递给OCILobWrite()函数的bufp相同。
lenp(输入/输出):bufp缓冲区中LOB数据的字节长度(输入),当前分片在bufp中 的字节长度(输出)。
piecep(输出):当前所写入哪一个数据分片。
csid(输入) 缓冲区数据的字符集ID。 csfrm(输入) 缓冲区数据的字符集格式。csfrm参数必须要和LOB的类型一致。 LOB函数实际写入的LOB数据长度
LOB 输入定宽的客户端字符集 输入变宽的客户端字符集 输出 BLOB 字节 字节 字节 CLOB 字符 字节 字节 输入数量指用户要写进LOB的数据的字节数而不是在bufp中的字节数(由buflen)指定。
-
示例
OCILobWrite(svchp, errhp, lobp, &amtp, 0, (dvoid *)buf, (ub4)1024, 0, (dvoid *)0, 0, (ub2)0, (ub1)SQLCS_IMPLICIT);
3.7.3.OCILobGetLength
-
功能
获取LOB的长度。
-
函数
sword OCILobGetLength(OCISvcCtx *svchp, OCIError *errhp, OCILobLocator *locp, ub4 *lenp) -
参数
OCILobGetLength 参数说明
名称 描述 svchp(输入) 服务上下文句柄。 errhp(输入/输出) 出现错误时可以传递给OCIErrorGet()诊断信息的错误句柄。 locp(输入) 一个LOB句柄唯一引用LOB。此LOB句柄必须是从svchp指定的服务器获取的定位器。 lenp(输出) 在输出时,如果LOB不为NULL,则它是LOB的长度。 -
示例
OCILobGetLength(ph->phOCISvctx, ph->phOCIErr, lobl, &size);
3.7.4.OCILobCreateTemporary
-
功能
创建一个临时LOB对象。
-
函数
sword OCILobCreateTemporary(OCISvcCtx *svchp, OCIError *errhp, OCILobLocator *locp, ub2 csid, ub1 csfrm, ub1 lobtype, boolean cache, OCIDuration duration) -
参数
OCILobCreateTemporary 参数说明
名称 描述 svchp(输入) OCI服务上下文句柄。 errhp(输入/输出) 出现错误时可以传递给OCIErrorGet()诊断信息的错误句柄。 locp(输入/输出) 指向临时大对象的定位器。 csid(输入) 保留参数。 csfrm(输入) 保留参数。 lobtype(输入) 创建的LOB类型,可选值如下所示。 OCI_TEMP_BLOB:临时BLOB。
OCI_TEMP_CLOB:临时CLOB。
cache(输入) 保留参数。 duration(输入) 临时LOB对象的有效期限,可选值如下所示。 OCI_DURATION_SESSION
OCI_DURATION_CALL
-
示例
OCILobCreateTemporary(svchp, errhp, &lob3, 0, 0, OCI_TEMP_BLOB, false, 0);
3.7.5.OCILobAssign
-
功能
赋值一个LOB对象到另一个。
-
函数
sword OCILobAssign(OCIEnv *envhp, OCIError *errhp, const OCILobLocator *src_locp, OCILobLocator **dst_locpp) -
参数
OCILobAssign 参数说明
名称 描述 envhp(输入/输出) 环境句柄。 errhp(输入/输出) 出现错误时可以传递给OCIErrorGet()诊断信息的错误句柄。 src_locp(输入) 被赋值的LOB句柄。 dst_locpp(输入/输出) 需要设置的LOB句柄。 -
示例
OCILobAssign(envhp, errhp, NULL, NULL);
3.7.6.OCILobFreeTemporary
-
功能
释放一个临时LOB。
-
函数
sword OCILobFreeTemporary (OCISvcCtx *svchp, OCIError *errhp, OCILobLocator *locp) -
参数
OCILobFreeTemporary 参数说明
名称 描述 svchp(输入/输出) OCI服务上下文句柄。 errhp(输入/输出) 错误句柄,可以把它传给OCIErrorGet()以获得关于错误的详细信息。 locp(输入/输出) LOB句柄,它唯一的指定了一个需要被释放的LOB。 -
示例
OCILobFreeTemporary (NULL, error, lob);
3.7.7.OCILobIsEqual
-
功能
判断给定的LOB句柄是否相等。
-
函数
sword OCILobIsEqual(OCIEnv *envhp, const OCILobLocator *x, const OCILobLocator *y, boolean *is_equal) -
参数
OCILobIsEqual 参数说明
名称 描述 envhp(输入) OCI环境句柄。 x(输入) LOB句柄。 y(输入) LOB句柄。 is_equal(输出) TRUE表示相等,FALSE表示不等。 -
示例
OCILobIsEqual(envhp, &lob3, &lob4, &isEqual);
3.7.8.OCILobEnableBuffering
-
功能
开启Lob的缓存。
-
函数
sword OCILobEnableBuffering( OCISvcCtx *svchp, OCIError *err, OCILobLocator *locp) -
参数
OCILobEnableBuffering 参数说明
名称 描述 svchp(输入) 服务上下文句柄。 err(输入/输出) 出现错误时可以传递给OCIErrorGet()诊断信息的错误句柄。 locp(输入) 需要开启缓存的LOB句柄。 为LOB定位器启用LOB缓冲,之后通过该LOB读取或写入数据时,将使用LOB缓冲子系统。
-
注意
调用该接口后,该LOB调用这些接口时会返回错误,只有当调用OCILobDisableBuffering结束缓存功能后才能成功调用:OCILobAppend()、OCILobCopy()、OCIlobErase()、OCILobGetLength()、OCILobTrim()。
-
示例
OCILobEnableBuffering(sc, error, clob);
3.7.9.OCILobDisableBuffering
-
功能
关闭Lob的缓存。
-
函数
sword OCILobDisableBuffering( OCISvcCtx *svchp, OCIError *err, OCILobLocator *locp) -
参数
OCILobDisableBuffering 参数说明
名称 描述 svchp(输入) 服务上下文句柄。 err(输入/输出) 出现错误时可以传递给OCIErrorGet()诊断信息的错误句柄。 locp(输入) 需要关闭缓存的LOB句柄。 -
示例
OCILobDisableBuffering(svcctx, error, clob);
3.7.10.OCILobFlushBuffer
-
功能
将此 LOB 的所有缓冲区刷新或写入服务器。
-
函数
sword OCILobFlushBuffer( OCISvcCtx *svchp, OCIError *err, OCILobLocator *locp, ub4 flag) -
参数
OCILobFlushBuffer 参数说明
名称 描述 svchp(输入) 服务上下文句柄。 err(输入/输出) 出现错误时可以传递给OCIErrorGet()诊断信息的错误句柄。 locp(输入) 需要写入的LOB句柄。 flag(输入) 缓冲区释放标识,如下所示。 OCI_LOB_BUFFER_FREE:释放缓冲区。
OCI_LOB_BUFFER_NOFREE:不释放缓冲区,仅重置缓冲区内容。
-
示例
OCILobFlushBuffer(svcctx, error, clob, OCI_LOB_BUFFER_NOFREE);
3.7.11.OCILobAppend
-
功能
在另一个 LOB 的末尾附加一个 LOB 值。
-
函数
sword OCILobAppend ( OCISvcCtx *svchp, OCIError *errhp, OCILobLocator *dst_locp, OCILobLocator *src_locp ); -
参数
OCILobAppend 参数说明
名称 描述 svchp(输入) 服务上下文句柄。 errhp(输入/输出) 错误句柄。 dst_locp(输入/输出) 被附加的LOB句柄。 src_locp(输入) 附加的LOB句柄。 -
示例
OCILobAppend(svcctx, error, lob_dest, lob_src);
3.7.12.OCILobTrim
-
功能
将 LOB 值截断。
-
函数
sword OCILobTrim ( OCISvcCtx *svchp, OCIError *errhp, OCILobLocator *locp, ub4 newlen ); -
参数
OCILobTrim 参数说明
名称 描述 svchp(输入) 服务上下文句柄。 errhp(输入/输出) 错误句柄。 locp(输入/输出) 被截断的LOB句柄。 newlen(输入) 新LOB的长度。 -
示例
OCILobTrim(svcctx, error, lob, newlen);
3.7.13.OCILobErase
-
功能
从指定偏移量开始删除内部 LOB 数据的指定部分。
-
函数
sword OCILobErase ( OCISvcCtx *svchp, OCIError *errhp, OCILobLocator *locp, ub4 *amount, ub4 offset ); -
参数
OCILobErase 参数说明
名称 描述 svchp(输入) 服务上下文句柄。 errhp(输入/输出) 错误句柄。 locp(输入/输出) 指定的LOB句柄。 amount(输入/输出) 需要删除的字节数。IN的时候为需要删除的字节数,OUT的时候为实际删除的字节数。 offset(输入) 绝对偏移量,从1开始。 -
注意
被删除的字节会被填充,并不会真正删除,CLOB类型会被填充为空格,BLOB类型会被填充为\0。
-
示例
OCILobErase(svcctx, error, lob, &amount, offset);
3.7.14.OCILobCopy
-
功能
将一个 LOB 值的全部或部分复制到另一个 LOB 值中。
-
函数
sword OCILobCopy ( OCISvcCtx *svchp, OCIError *errhp, OCILobLocator *dst_locp, OCILobLocator *src_locp, ub4 amount, ub4 dst_offset, ub4 src_offset ); -
参数
OCILobCopy 参数说明
名称 描述 svchp(输入) 服务上下文句柄。 errhp(输入/输出) 错误句柄。 dst_locp(输入/输出) 目的LOB句柄。 src_locp(输入) 源LOB句柄。 amount(输入) 源LOB句柄需要复制的字节数。 dst_offset(输入) 目的LOB句柄复制开始的偏移量。 src_offset(输入) 源LOB句柄复制的偏移量。 -
注意
如果拷贝的长度大于大对象的长度,最多就拷贝大对象的长度。
-
示例
OCILobCopy(svcctx, error, lob_dest, lob_src, amount, dst_offset, src_offset);
3.7.15.OCILobOpen
-
功能
以指定模式打开一个大对象。
-
函数
sword OCILobOpen ( OCISvcCtx *svchp, OCIError *errhp, OCILobLocator *locp, ub1 mode ); -
参数
表 OCILobOpen 参数说明
名称 描述 svchp(输入) 服务上下文句柄。 errhp(输入/输出) 错误句柄。 locp(输入/输出) 要打开的LOB句柄。 mode(输入) 打开模式。 OCI_LOB_READONLY:仅读。
OCI_LOB_WRITEONLY:仅写。
OCI_LOB_APPENDONLY:写且将lob指针移到最后。
OCI_LOB_READWRITE:读写。
-
示例
OCILobOpen(svcctx, error, lob, OCI_LOB_READONLY);
3.7.16.OCILobClose
-
功能
关闭一个大对象。
-
函数
sword OCILobClose ( OCISvcCtx *svchp, OCIError *errhp, OCILobLocator *locp); -
参数
表OCILobClose 参数说明
名称 描述 svchp(输入) 服务上下文句柄。 errhp(输入/输出) 错误句柄。 locp(输入/输出) 需要关闭的LOB句柄。 -
示例
OCILobClose(svcctx, error, lob);
3.7.17.OCILobLocatorIsInit
-
功能
LOB是否被初始化。
-
函数
sword OCILobLocatorIsInit( OCIEnv *envhp, OCIError *errhp, CONST OCILobLocator *locp, Boolean *is_initialized ); -
参数
表 OCILobLocatorIsInit 参数说明
名称 描述 envhp(输入) 环境句柄。 errhp(输入/输出) 错误句柄。 locp(输入) 判断的Lob句柄。 is_initialized(输出) 是否被初始化。 -
示例
OCILobLocatorIsInit(envhp ,errhp ,locp, &is_init);
3.7.18.OCILobLocatorAssign
-
功能
赋值一个LOB至另一个。
-
函数
sword OCILobLocatorAssign ( OCISvcCtx *svchp, OCIError *errhp, const OCILobLocator *src_locp, OCILobLocator **dst_locpp ); -
参数
OCILobLocatorAssign 参数说明
名称 描述 svchp(输入/输出) 语句句柄。 errhp(输入/输出) 错误句柄。 src_locp(输入) 被赋值的LOB句柄。 dst_locp (输入/输出) 需要设置的LOB句柄。必须通过调用OCIDescriptorAlloc()分配空间。 -
示例
OCILobLocatorAssign(svchp,errhp, src_locp,&dst_locp);
3.8.RAW对象
3.8.1.OCIRawPtr
-
功能
获取指向原始数据的指针。
-
函数
sword OCIRawPtr (OCIEnv *envhp, const OCIRaw* raw) -
参数
OCIRawPtr 参数说明
名称 描述 envhp(输入) OCI环境句柄。 raw(输入) Raw对象指针。 -
示例
OCIRawPtr(env, NULL);
3.8.2.OCIRawSize
-
功能
返回raw对象原始数据的大小。
-
函数
sword OCIRawPtr (OCIEnv *envhp, const OCIRaw* raw) -
参数
OCIRawSize 参数说明
名称 描述 envhp(输入) OCI环境句柄。 raw(输入) Raw对象指针。 -
示例
OCIRawSize(NULL, raw);
3.8.3.OCIRawAllocSize
-
功能
获取Raw对象分配的大小。
-
函数
sword OCIRawAllocSize (OCIEnv* envhp, OCIError *errhp, const OCIRaw* raw) ub4* allocsize); -
参数
OCIRawAllocSize 参数说明
名称 描述 envhp(输入) OCI环境句柄。 errhp(输入/输出) 错误句柄,可以把它传给 OCIErrorGet()以获得关于错误的详细信息。 raw(输入) Raw对象指针。 allocsize(输出) 返回raw对象分配的大小。 -
示例
OCIRawAllocSize(env, error, raw, &allocsize);
3.8.4.OCIRawAssignBytes
-
功能
将一段内存复制给一个raw对象。
-
函数
sword OCIRawAssignBytes (OCIEnv* envhp, OCIError *errhp, const ub1* source, ub4 source_len, OCIRaw** target) -
参数
OCIRawAssignBytes 参数说明
名称 描述 envhp(输入) OCI环境句柄。 errhp(输入/输出) 错误句柄,可以把它传给OCIErrorGet()以获得关于错误的详细信息。 source (输入) 需要复制的内存地址。 source_len(输入) 需要复制的内存的长度。 target(输出) 返回的raw对象。 -
示例
OCIRawAssignBytes(env, NULL, data, len, &raw);
3.8.5.OCIRawResize
-
功能
重新分配raw对象的大小。
-
函数
sword OCIRawResize (OCIEnv* envhp, OCIError *errhp, ub2 new_size, OCIRaw** rawp) -
参数
OCIRawResize 参数说明
名称 描述 envhp(输入) OCI环境句柄。 errhp(输入/输出) 错误句柄,可以把它传给OCIErrorGet()以获得关于错误的详细信息。 new_size (输入) 重新分配的大小。 Rawp(输出) 重新分配过大小的Raw对象。 -
示例
OCIRawResize(NULL, error, new_size, &raw);
3.8.6.OCIRawAssignRaw
-
功能
通过一个raw对象复制出另一个raw对象。
-
函数
sword OCIRawAssignRaw (OCIEnv* envhp, OCIError *errhp, const OCIRaw* rhs, OCIRaw** lhs) -
参数
OCIRawAssignRaw 参数说明
名称 描述 svchp(输入) OCI环境句柄。 errhp(输入/输出) 错误句柄,可以把它传给 OCIErrorGet()以获得关于错误的详细信息。 rhs (输入) 需要复制的Raw对象。 lhs(输出) 复制过后生成的Raw对象。 -
示例
OCIRawAssignRaw(env, NULL, raw_rhs, &raw_lhs);
3.9.时间
3.9.1.OCIDateTimeConstruct
-
功能
初始化datetime描述符的信息。
-
函数
sword OCIDateTimeConstruct( void *hndl, OCIError *err, OCIDateTime *datetime, sb2 yr, ub1 mnth, ub1 dy, ub1 hr, ub1 mm, ub1 ss, ub4 fsec, OraText *timezone, size_t timezone_length) -
参数
OCIDateTimeConstruct 参数说明
名称 描述 hndl(输入) OCI环境句柄。 err(输入/输出) 错误句柄。 datetime(输入) OCIDateTime的描述符指针。 yr(输入) 年。 mnth(输入) 月。 dy(输入) 日。 hr(输入) 时。 mm(输入) 分。 ss(输入) 秒。 fsec(输入) 小数秒。 timezone(输入) 时区。 timezone_length(输入) 时区长度。 日期时间参数范围请参见《优炫数据库管理系统SQL语言手册》“数据类型”章节中的“日期/时间类型”小节中的“日期/时间类型”表。
-
注意
datetime参数需要先通过OCIDescriptorAlloc函数分配空间。
-
示例
OCIDescriptorAlloc((dvoid *)env,(void **)&constructdatetime, OCI_DTYPE_DATE, 0, (void **)0);
3.9.2.OCIDateTimeFromText
-
功能
把字符串按照一定格式转换成DateTime类型。
-
函数
sword OCIDateTimeFromText( dvoid *hndl, OCIError *err, const OraText *date_str, size_t dstr_length, const OraText *fmt, ub1 fmt_length, const OraText *lang_name, size_t lang_length, OCIDateTime *datetime) -
参数
OCIDateTimeFromText 参数说明
名称 描述 hndl(输入) OCI环境句柄。 err(输入/输出) 错误句柄。 date_str(输入) 用来转换的日期字符串。 dstr_length(输入) 日期字符串的长度。 fmt(输入) 日期格式串。 fmt_length(输入) 日期格式串长度。 lang_name(输入) 日期中语言的名称。 lang_length(输入) 语言字符串的长度。 datetime(输出) OCIDateTime类型指针。 日期时间参数范围请参见《优炫数据库管理系统函数和操作符手册》中的“数据类型格式化函数”章节中的“用于日期/时间格式化的模板模式”表。
-
注意
datetime参数需要先通过OCIDescriptorAlloc函数分配空间。日期中的语言使用的是默认数据库中的语言,暂时不支持按照输入的语言转换。
-
示例
OCIDateTimeFromText((dvoid *)env, error, column_time, sizeof(column_time), fmt, sizeof(fmt), (OraText *)LANG, sizeof(LANG), datetime);
3.9.3.OCIDateTimeToText
-
功能
根据指定格式把一个日期类型数据转换成字符串。
-
函数
sword OCIDateTimeToText( dvoid *hndl, OCIError *err, OCIDateTime *datetime, const OraText *fmt, ub1 fmt_length, ub1 fsprec, const OraText *lang_name, size_t lang_length, size_t *buf_size, const OraText *buf) -
参数
OCIDateTimeToText 参数说明
名称 描述 hndl(输入) OCI环境句柄。 err(输入/输出) 错误句柄。 datetime(输入) 用来转换的OCIDateTime类型指针。 fmt(输入) 日期格式串。 fmt_length(输入) 日期格式串长度。 fsprec(输入) 指定返回结果字符串中秒的精度。 lang_name(输入) 日期中语言的名称。 lang_length(输入) 语言字符串的长度。 buf_size(输入\输出) 结果字符串的长度。 buf(输出) 缓冲区指针,转换后字符串存入改区域。 日期时间参数范围请参见《优炫数据库管理系统函数和操作符手册》中的“数据类型格式化函数”章节中的“用于日期/时间格式化的模板模式”表。
-
注意
日期中的语言使用的是默认数据库中的语言,暂时不支持按照输入的语言转换。秒的精度暂时不支持按照输入的计算,默认是6位小数。
-
示例
OCIDateTimeToText((dvoid *)env, error, datetime, fmt, strlen((char*)fmt), 2, NULL, 0, &buf_size, timeout);
3.9.4.OCIDateTimeGetDate
-
功能
获取OCIDateTime中的日期信息。
-
函数
sword OCIDateTimeGetDate( dvoid *hndl, OCIError *err, CONST OCIDateTime *datetime, sb2 *yr, ub1 *mnth, ub1 *dy) -
参数
OCIDateTimeGetDate 参数说明
名称 描述 hndl(输入) OCI环境句柄。 err(输入/输出) 错误句柄。 datetime(输入) 要获取的OCIDateTime描述符指针。 yr(输出) 年。 mnth(输出) 月。 dy(输出) 日。 -
注意
如果datetime是OCI_DTYPE_TIME或OCI_DTYPE_TIME_TZ类型,获取日期会返回错误OCI_ERROR。
-
示例
OCIDateTimeGetDate((dvoid *)env, error, datetime, &year, &month, &day);
3.9.5.OCIDateTimeGetTime
-
功能
初始化datetime描述符的信息。
-
函数
sword OCIDateTimeGetTime( void *hndl, OCIError *err, OCIDateTime *datetime, ub1 *hr, ub1 *mm, ub1 *ss, ub4 *fsec) -
参数
OCIDateTimeGetTime 参数说明
名称 描述 hndl(输入) OCI环境句柄。 err(输入/输出) 错误句柄。 datetime(输入) 要获取的OCIDateTime描述符指针。 hr(输出) 时。 mm(输出) 分。 ss(输出) 秒。 fsec(输出) 小数秒。 -
注意
如果datetime是OCI_DTYPE_DATE类型,获取时间会返回错误OCI_ERROR。
-
示例
OCIDateTimeGetTime((dvoid *)env, error, datetime, &hr, &mm, &ss, &fsec);
3.10.时间间隔
时间间隔句柄需要事先调用OCIDesccriptorAlloc申请空间,事后调用OCIDesccriptorFree释放空间。
3.10.1.OCIIntervalSetYearMonth
-
功能
设置时间间隔的年月。
-
函数
sword OCIIntervalSetYearMonth( void *hndl, OCIError *err, sb4 yr, sb4 mnth, OCIInterval *result) -
参数
OCIIntervalSetYearMonth 参数说明
名称 描述 hndl(输入) OCI环境句柄。 err(输入/输出) 错误句柄。 yr(输入) 年。 mnth(输入) 月。 result(输出) 输出的时间间隔。 -
注意
设置成功后天秒部分会被清空。
-
示例
OCIIntervalSetYearMonth(env, error, 1, 2, inter);
3.10.2.OCIIntervalGetYearMonth
-
功能
获取时间间隔的年月。
-
函数
sword OCIIntervalGetYearMonth( void *hndl, OCIError *err, sb4 *yr, sb4 *mnth, const OCIInterval *interval) -
参数
OCIIntervalGetYearMonth 参数说明
名称 描述 hndl(输入) OCI环境句柄。 err(输入/输出) 错误句柄。 yr(输入) 年,范围为-178000000到178000000。 mnth(输入) 月。 interval(输出) 需要获取年月的时间间隔。 -
示例
OCIIntervalGetYearMonth(env, error, &year, &month, inter);
3.10.3.OCIIntervalSetDaySecond
-
功能
设置时间间隔的天秒。
-
函数
sword OCIIntervalSetDaySecond( void *hndl, OCIError *err, sb4 dy, sb4 hr, sb4 mm, sb4 ss, sb4 fsec, OCIInterval *result) -
参数
OCIIntervalSetDaySecond 参数说明
名称 描述 hndl(输入) OCI环境句柄。 err(输入/输出) 错误句柄。 dy(输入) 天。 hr(输入) 小时。 mm(输入) 分钟。 ss(输入) 秒。 fsec(输入) 微秒。 result(输出) 输出的时间间隔。 -
注意
设置成功后年月部分会被清空。
-
示例
OCIIntervalSetDaySecond(NULL, error, 1, 2, 3, 4, 5, inter);
3.10.4.OCIIntervalGetDaySecond
-
功能
获取时间间隔的天秒。
-
函数
sword OCIIntervalGetDaySecond( void *hndl, OCIError *err, sb4 *dy, sb4 *hr, sb4 *mm, sb4 *ss, sb4 *fsec, OCIInterval *interval) -
参数
OCIIntervalGetDaySecond 参数说明
名称 描述 hndl(输入) OCI环境句柄。 err(输入/输出) 错误句柄。 dy(输入) 天。 hr(输入) 小时。 mm(输出) 分钟。 ss(输出) 秒。 fsec(输出) 微秒。 interval(输入) 需要获取时间的时间间隔。 -
示例
OCIIntervalGetDaySecond(env, error, &dd, &hh, &mm, &ss, &us, inter);
3.10.5.OCIIntervalCompare
-
功能
比较两个时间间隔。
-
函数
sword OCIIntervalCompare( void *hndl, OCIError *err, OCIInterval *inter1, OCIInterval *inter2, sword *result) -
参数
OCIIntervalCompare 参数说明
名称 描述 hndl(输入) OCI环境句柄。 err(输入/输出) 错误句柄。 inter1(输入) 时间间隔1。 inter2(输入) 时间间隔2。 result(输出) 比较结果。 如果inter1 > inter2,则result = 1。
如果inter1 = inter2,则result = 0。
如果inter1 < inter2,则result = -1。
-
示例
OCIIntervalCompare(NULL, error, inter1, inter2, &result);
3.10.6.OCIIntervalAdd
-
功能
两个时间间隔相加。
-
函数
sword OCIIntervalAdd ( void *hndl, OCIError *err, OCIInterval *addend1, OCIInterval *addend2, OCIInterval *result) -
参数
OCIIntervalAdd 参数说明
名称 描述 hndl(输入) OCI环境句柄。 err(输入/输出) 错误句柄。 addend1(输入) 时间间隔1。 addend2(输入) 时间间隔2。 result(输出) 相加的结果。 -
示例
OCIIntervalAdd(env, error, inter1, inter2, inter3);
3.10.7.OCIIntervalAssign
-
功能
将一个时间间隔赋值给另一个时间间隔。
-
函数
sword OCIIntervalAssign( void *hndl, OCIError *err, OCIInterval *ininter, OCIInterval *outinter) -
参数
OCIIntervalAssign 参数说明
名称 描述 hndl(输入) OCI环境句柄。 err(输入/输出) 错误句柄。 ininter(输入) 输入的时间间隔。 outinter(输出) 输出的时间间隔。 -
示例
OCIIntervalAssign(env, error, inter1, inter2);
3.10.8.OCIIntervalToText
-
功能
将时间间隔转成字符串。
-
函数
sword OCIIntervalToText( dvoid *hndl, OCIError *err, CONST OCIInterval *interval, ub1 lfprec, ub1 fsprec, OraText *buffer, size_t buflen, size_t *resultlen) -
参数
OCIIntervalToText 参数说明
名称 描述 hndl(输入) OCI环境句柄。 err(输入/输出) 错误句柄。 interval(输入) 时间间隔。 lfprec(输入) 阈值达到的精度(仅做兼容)。 fsprec(输入) 间隔中分秒的精度(仅做兼容)。 buffer(输出) 用于保存结果的缓冲区。 buflen(输入) 缓冲区长度。 resultlen(输出) 存放缓冲区buffer中结果的长度。 -
示例
OCIIntervalToText(env, error, inter, 0, 0, (OraText* )buf, sizeof(buf), &reslen);
3.10.9.OCIIntervalFromText
-
功能
将字符串转成时间间隔。
-
函数
sword OCIIntervalFromText( void *hndl, OCIError *err, const OraText *inpstr, size_t str_len, OCIInterval *result) -
参数
OCIIntervalFromText 参数说明
名称 描述 hndl(输入) OCI环境句柄。 err(输入/输出) 错误句柄。 inpstr(输入) 时间间隔字符串。允许的输入字符串参考请参考《优炫数据库管理系统SQL语言手册》“数据类型”章节中的“日期/时间类型”小节中的“间隔输入”。 str_len(输入) 时间间隔字符串长度。 result(输出) 转换后的时间间隔。 -
示例
OCIIntervalFromText(env, error, (OraText* )"10year 1day 2hour", 17, inter);
3.10.10.OCIIntervalCheck
-
功能
设置时间间隔的年月。
-
函数
sword OCIIntervalCheck( void *hndl, OCIError *err, OCIInterval *interval, ub4 *valid); -
参数
OCIIntervalCheck 参数说明
名称 描述 hndl(输入) OCI环境句柄。 err(输入/输出) 错误句柄。 interval(输入) 要检查的时间间隔。 valid(输入) 检查结果。 -
注意
这个函数仅检查输入的时间间隔句柄是否合法。
-
示例
OCIIntervalCheck(env, error, inter, &valid);
3.10.11.OCIIntervalDivide
-
功能
利用数字划分一个时间间隔来产生一个时间间隔。
-
函数
sword OCIIntervalDivide ( dvoid *hndl, OCIError *err, OCIInterval *dividend, OCINumber *divisor, OCIInterval *result ); -
参数
OCIIntervalDivide 参数说明
名称 描述 hndl(输入) OCI环境句柄。 err(输入/输出) 错误句柄。 dividend(输入) 被划分的间隔。 divisor(输入) 用于划分的数字。 result (输出) 结果间隔(dividend/divisor)。 -
示例
OCIIntervalDivide(env, error, inter1, num, result);
3.10.12.OCIIntervalMultiply
-
功能
利用数字增长间隔以得到一个间隔。
-
函数
sword OCIIntervalMultiply ( dvoid *hndl, OCIError *err, CONST OCIInterval *inter, OCINumber *nfactor, OCIInterval *result); -
参数
OCIIntervalMultiply 参数说明
名称 描述 hndl(输入) OCI环境句柄。 err(输入/输出) 错误句柄。 inter(输入) 要被增长的间隔。 nfactor 用于增长的数字,即增长量倍数。 result 结果间隔(inter * nfactor)。 -
示例
OCIIntervalMultiply(env, error, inter1, num, result);
3.10.13.OCIIntervalSubtract
-
功能
两个间隔相减。
-
函数
sword OCIIntervalSubtract ( dvoid *hndl, OCIError *err, OCIInterval *minuend, OCIInterval *subtrahend, OCIInterval *result ); -
参数
OCIIntervalSubtract 参数说明
名称 描述 hndl(输入) OCI环境句柄。 err(输入/输出) 错误句柄。 minuend(输入) 被减数间隔。 subtrahend(输入) 减数间隔。 result(输出) 结果间隔(minuend-subtrahend)。 -
示例
OCIIntervalSubtract(env, error, inter1, inter2, result);
3.11.数字
3.11.1.OCINumberFromInt
-
功能
从int类型转成OCINumber类型。
-
函数
sword OCINumberFromInt ( OCIError *err, const void *inum, uword inum_length, uword inum_s_flag, OCINumber *number) -
参数
OCINumberFromInt 参数说明
名称 描述 err(输入/输出) 出现错误时可以传递给OCIErrorGet()诊断信息的错误句柄。 inum(输入) 需要转换的整形指针。 inum_length(输入) 整型长度,如下所示。 1:inum类型为sb1或ub1。
2:inum类型为sb2或ub2。
4:inum类型为sb4或ub4。
inum_s_flag(输入) 转换类型,如下所示。 OCI_NUMBER_SIGNED:无符号类型。
OCI_NUMBER_UNSIGNED:有符号类型。
number(输出) 转换后的OCINumber类型,需要提前使用OCIDescriptorAlloc分配空间。 -
示例
OCINumberFromInt(error, inum, sizeof(inum), OCI_NUMBER_UNSIGNED, number_int);
3.11.2.OCINumberToInt
-
功能
从OCINumber类型转化成整型。
-
函数
sword OCINumberToInt ( OCIError *err, const OCINumber *number, uword rsl_length, uword rsl_s_flag, void *rsl) -
参数
OCINumberToInt 参数说明
名称 描述 err(输入/输出) 出现错误时可以传递给OCIErrorGet()诊断信息的错误句柄。 number(输入) 需要转换的OCINumber类型。 rsl_length(输入) 转换结果的长度,如下所示。 1:rsl类型为sb1或ub1。
2:rsl类型为sb2或ub2。
4:rsl类型为sb4或ub4。
rsl_flag(输入) 转换类型,如下所示。 OCI_NUMBER_SIGNED:无符号类型。
OCI_NUMBER_UNSIGNED:有符号类型。
rsl(输出) 转换结果。 -
示例
OCINumberToInt(error, number_int, sizeof(inum), OCI_NUMBER_UNSIGNED, &inum);
3.11.3.OCINumberFromText
-
功能
从字符串转成OCINumber类型。
-
函数
sword OCINumberFromText( OCIError *err, CONST OraText *str, ub4 str_length, CONST OraText *fmt, ub4 fmt_length, CONST OraText *nls_params, ub4 nls_p_length, OCINumber *number ) -
参数
OCINumberFromText 参数说明
名称 描述 err(输入/输出) 出现错误时可以传递给OCIErrorGet()诊断信息的错误句柄。 str(输入) 需要转换的字符串。 str_length(输入) 需要转换的字符串的长度。 fmt(输入) 转换格式,保留参数。 fmt_length(输入) 转换格式的长度,保留参数。 nls_params(输入) 间隔格式,保留参数。 nls_p_length(输入) 间隔格式的长度,保留参数。 number(输出) 转换后的OCINumber类型,需要提前使用OCIDescriptorAlloc分配空间。 -
示例
OCINumberFromText(error, inum, strlen((char*)inum), 0, 0, 0, 0, number_int);
3.11.4.OCINumberToText
-
功能
OCINumber类型转成字符串类型。
-
函数
sword OCINumberToText( OCIError *err, const OCINumber *number, const oratext *fmt, ub4 fmt_length, const oratext *nls_params, ub4 nls_p_length, ub4 *buf_size, oratext *buf) -
参数
OCINumberToText 参数说明
名称 描述 err(输入/输出) 出现错误时可以传递给OCIErrorGet()诊断信息的错误句柄。 number(输入) 需要转换的OCINumber类型。 fmt(输入) 转换格式,保留参数。 fmt_length(输入) 转换格式长度,保留参数。 nls_params(输入) 间隔格式,保留参数。 nls_p_length(输入) 间隔格式的长度,保留参数。 buf_size(输入/输出) 字符串长度。 buf(输出) 字符串。 -
示例
OCINumberToText(error, number_int, NULL, 0, NULL, 0, &length, OraTextout);
3.11.5.OCINumberFromReal
-
功能
从浮点数转换成OCINumber类型。
-
函数
sword OCINumberFromReal( OCIError *err, const void *rnum, uword rnum_length, OCINumber *number) -
参数
OCINumberFromReal 参数说明
名称 描述 err(输入/输出) 出现错误时可以传递给OCIErrorGet()诊断信息的错误句柄。 rnum(输入) 浮点数指针。 rnum_length(输入) 浮点数指针长度,如下所示。 4:rnum类型为float。
8:rnum类型为double。
number(输出) 转换后的OCINumber类型,需要提前使用OCIDescriptorAlloc分配空间。 -
示例
OCINumberFromReal(error, (void *)&dbl, sizeof(dbl), nres);
3.11.6.OCINumberToReal
-
功能
将OCINumber的值转换成浮点型的数值。
-
函数
sword OCINumberToReal( OCIError *err, const OCINumber *number, uword rsl_length, void *rsl) -
参数
OCINumberToReal 参数说明
名称 描述 err(输入/输出) 出现错误时可以传递给OCIErrorGet()诊断信息的错误句柄。 number(输入) OCINumber类型指针。 rsl_length(输入) rsl的长度,如下所示。 4:rnum类型为float。
8:rnum类型为double。
rsl(输出) 浮点型指针。 -
示例
OCINumberToReal(error, nres, sizeof(dbl), (void*)&dbl);
3.11.7.OCINumberAdd
-
功能
两个OCINumber类型相加。
-
函数
sword OCINumberAdd( OCIError *err, const OCINumber *number1, OCINumber *result) -
参数
OCINumberAdd 参数说明
名称 描述 err(输入/输出) 出现错误时可以传递给OCIErrorGet()诊断信息的错误句柄。 number1(输入) 被加数。 number2(输入) 加数。 result(输出) 和,需要提前使用OCIDescriptorAlloc分配空间。 -
示例
OCINumberAdd(error, number_int, number_int2, result);
3.11.8.OCINumberAssign
-
功能
对Number进行赋值。
-
函数
sword OCINumberAssign( OCIError *err, const OCINumber *from, const OCINumber *to) -
参数
OCINumberAssign 参数说明
名称 描述 err(输入/输出) 出现错误时可以传递给OCIErrorGet()诊断信息的错误句柄。 from(输入) 源Number。 to(输出) 目标Number,需要提前使用OCIDescriptorAlloc分配空间。 -
示例
OCINumberAssign(error, number_int, result);
3.11.9.OCINumberDiv
-
功能
计算两个Number的商。
-
函数
sword OCINumberDiv(OCIError *err, const OCINumber *number1, const OCINumber *number2, OCINumber *result) -
参数
OCINumberDiv 参数说明
名称 描述 err(输入/输出) 出现错误时可以传递给OCIErrorGet()诊断信息的错误句柄。 number1(输入) 分子。 number2(输入) 分母。 result(输出) 商,需要提前使用OCIDescriptorAlloc分配空间。 -
示例
OCINumberDiv(error, number_input, number_input2, result);
3.11.10.OCINumberIsInt
-
功能
判断Number类型是不是一个整数。
-
函数
sword OCINumberIsInt( OCIError *err, const OCINumber *number, boolean *result) -
参数
OCINumberIsInt 参数说明
名称 描述 err(输入/输出) 出现错误时可以传递给OCIErrorGet()诊断信息的错误句柄。 number(输入) 待判断数。 result(输出) 判断结果,TRUE是整数,FALSE不是整数。 -
示例
OCINumberIsInt(error, nres, &result);
3.11.11.OCINumberMod
-
功能
计算两个Number类型的余数。
-
函数
sword OCINumberMod( OCIError *err, const OCINumber *number1, const OCINumber *number2, OCINumber *result) -
参数
OCINumberMod 参数说明
名称 描述 err(输入/输出) 出现错误时可以传递给OCIErrorGet()诊断信息的错误句柄。 number1(输入) 分子。 number2(输入) 分母。 result(输出) 结果,需要提前使用OCIDescriptorAlloc分配空间。 -
示例
OCINumberMod(error, number_int, number_int2, result);
3.11.12.OCINumberMul
-
功能
计算两个Number的积。
-
函数
sword OCINumberMul( OCIError *err, const OCINumber *number1, OCINumber *result) -
参数
OCINumberMul 参数说明
名称 描述 err(输入/输出) 出现错误时可以传递给OCIErrorGet()诊断信息的错误句柄。 number1(输入) 被乘数。 number2(输入) 乘数。 result(输出) 积,需要提前使用OCIDescriptorAlloc分配空间。 -
示例
OCINumberMul(error, number_input, number_input2, result);
3.11.13.OCINumbersub
-
功能
两个OCINumber类型相减。
-
函数
sword OCINumberSub( OCIError *err, const OCINumber *number1, const OCINumber *number2, OCINumber *result) -
参数
OCINumbersub 参数说明
名称 描述 err(输入/输出) 出现错误时可以传递给OCIErrorGet()诊断信息的错误句柄。 number1(输入) 减数。 number2(输入) 被减数。 result(输出) 结果。 -
示例
OCINumberMod(error, number_int, number_int2, result);
3.12.直接文件操作
3.12.1.OCIDirPathPrepare
-
功能
准备直接文件操作。
-
函数
sword OCIDirPathPrepare ( OCIDirPathCtx *dpctx, OCISvcCtx *svchp, OCIError *errhp) -
参数
OCIDirPathPrepare 参数说明
名称 描述 dpctx(输入) 直接文件操作句柄。 svchp(输入) 执行所用的上下文句柄。 errhp(输入/输出) 出现错误时可以传递给OCIErrorGet()诊断信息的错误句柄。 在执行文件函数之前,文件操作的信息都要在文件操作环境的上下文件属性中预先设置好。
-
注意
在调用该函数之前,先要在dpctx上下文件中设置好要操作的表信息如OCI_ATTR_SUB_NAME和OCI_ATTR_SCHEMA_NAME、OCI_ATTR_NAME、OCI_ATTR_DATA_TYPE。
-
示例
OCIDirPathPrepare(dpctx, sc, error);
3.12.2.OCIDirPathColArrayEntrySet
-
功能
设置写入文件数据数组上指定位置的数据内容。
-
函数
sword OCIDirPathColArrayEntrySet( OCIDirPathColArray *dpca, OCIError *errhp, ub4 rownum, ub2 colIdx, ub1 *cvalp, ub4 clen, ub1 cflg ) -
参数
OCIDirPathColArrayEntrySet 参数说明
名称 描述 dpca(输入) 直接文件操作句柄。 errhp(输入/输出) 出现错误时可以传递给OCIErrorGet()诊断信息的错误句柄。 rownum(输入) 设置的数据内容在数组中的行号。 colIdx(输入) 设置的数据内容在数组中的列号。 cvalp(输入) 设置的数据内容缓冲区指针。 clen(输入) 数据内容的长度。 cflg(输入) 数据属性标识,如下所示。 OCI_DIRPATH_COL_COMPLETE:在分批设置数据时,使用该标识表示数据已经结束。
OCI_DIRPATH_COL_NULL:表示设置的数据是一个空(NULL)。
OCI_DIRPATH_COL_PARTIAL:分批设置数据,表示当前设置的数据只是一部分。
-
注意
当前行号、列号仅支持按顺序递增,如rownum 0,colIdx 0;rownum 0,colIdx 1;rownum 1,colIdx 0;rownum 1,colIdx 1。暂不支持倒序或其他方式输入。
-
示例
OCIDirPathColArrayEntrySet(dpca, error, rowoff, coloff, (ub1*)number_int, length, OCI_DIRPATH_COL_COMPLETE);
3.12.3.OCIDirPathColArrayToStream
-
功能
把数据数组转换成为数据流。
-
函数
sword OCIDirPathColArrayToStream( OCIDirPathColArray *dpca, OCIDirPathCtx const *dpctx, OCIDirPathStream *dpstr, OCIError *errhp, ub4 rowcnt, ub4 rowoff ) -
参数
OCIDirPathColArrayToStream 参数说明
名称 描述 dpca(输入) 直接路径列数组句柄。 dpctx(输入) 直接文件操作句柄。 dpstr(输入) 数据流描述句柄。 errhp(输入/输出) 出现错误时可以传递给OCIErrorGet()诊断信息的错误句柄。 rowcnt(输入) 要转换的行数,保留参数。 rowoff(输入) 转换时在原数组上的起始偏移行号,保留参数。 -
示例
OCIDirPathColArrayToStream(dpca, dpctx, dpstr, error, 0, 0);
3.12.4.OCIDirPathLoadStream
-
功能
写入转换后的数据流到文件。
-
函数
sword OCIDirPathLoadStream ( OCIDirPathCtx *dpctx, OCIDirPathStream *dpstr, OCIError *errhp ) -
参数
OCIDirPathLoadStream 参数说明
名称 描述 dpctx(输入) 直接文件操作句柄。 dpstr(输入/输出) 数据流描述句柄。 errhp(输入) 出现错误时可以传递给OCIErrorGet()诊断信息的错误句柄。 -
示例
OCIDirPathLoadStream(dpctx, dpstr, error);
3.12.5.OCIDirPathFinish
-
功能
完成直接文件操作,清空相应的环境。
-
函数
sword OCIDirPathFinish ( OCIDirPathCtx *dpctx, OCIError *errhp ) -
参数
OCIDirPathFinish 参数说明
名称 描述 dpctx(输入) 直接文件操作句柄。 errhp(输入/输出) 出现错误时可以传递给OCIErrorGet()诊断信息的错误句柄。 -
示例
OCIDirPathFinish(dpctx, error);
3.13.字符串操作
3.13.1.OCIStringAllocSize
-
功能
获得字符串所占内存空间的大小。
-
函数
sword OCIStringAllocSize( OCIEnv *env, OCIError *err, CONST OCIString *vs, ub4 *allocsize ) -
参数
OCIStringAllocSize 参数说明
名称 描述 env(输入/输出) 已初始化的环境句柄。 err(输入/输出) 错误信息句柄。 vs(输入) 需要获得字节数的字符串,不能为空。 allocsize(输出) 字符串所占内存大小(字节数)。 -
示例
OCIStringAllocSize(env, error, vs, &allocsize);
3.13.2.OCIStringAssign
-
功能
将一个字符串赋值给另一个字符串。
-
函数
sword OCIStringAssign ( OCIEnv *env, OCIError *err, CONST OCIString *rhs, OCIString **lhs ) -
参数
OCIStringAssign 参数说明
名称 描述 env(输入/输出) 已初始化的环境句柄。 err(输入/输出) 错误信息句柄。 rhs(输入) 源字符串。 lhs(输入/输出) 目的字符串。 -
注意
该函数用于赋值字符串 rhs 给 lhs。字符串 lhs 的大小由 rhs 决定,字符串以'\0'为结束符。整个字符串的长度不包括结束符所占的字节数。
-
示例
OCIStringAssign(env, error, rhs, &lhs);
3.13.3.OCIStringAssignText
-
功能
将源文本串赋值给目的字符串。
-
函数
sword OCIStringAssignText ( OCIEnv *env, OCIError *err, CONST OraText *rhs, ub2 rhs_len, OCIString **lhs ) -
参数
OCIStringAssignText 参数说明
名称 描述 env(输入/输出) 已初始化的环境句柄。 err(输入/输出) 错误信息句柄。 rhs(输入) 源字符串。 rhs_len(输入) rhs 字符串的长度。 lhs(输入/输出) 目的字符串。 -
注意
该函数用于赋值rhs给lhs。字符串lhs的大小由rhs决定,如果rhs_len的长度大于rhs的长度,以rhs的长度决定rhs的大小。分配的字符串以'\0'为结束符。整个字符串的长度不包括结束符所占的字节数。
-
示例
OCIStringAssignText(env, error, rhs, rhs_len, &vs);
3.13.4.OCIStringPtr
-
功能
获得指向所给字符串文本的指针。
-
函数
Text* OCIStringPtr ( OCIEnv *env, CONST OCIString *vs ) -
参数
OCIStringPtr 参数说明
名称 描述 env(输入/输出) 已初始化的环境句柄。 vs(输入) 返回指向 OCIString 对象的指针。 -
示例
OCIStringPtr(env, vs);
3.13.5.OCIStringResize
-
功能
为给定的字符串重新指定所占内存的大小。
-
函数
sword OCIStringResize ( OCIEnv *env, OCIError *err, ub4 new_size, OCIString **str ) -
参数
OCIStringResize 参数说明
名称 描述 env(输入/输出) 已初始化的环境句柄。 err(输入/输出) 错误信息句柄。 new_size(输入) 调整后字符串所占内存的字节数。 str(输入/输出) 字符串需要申请的空间,其初始内存将被 OCI 对象缓存释放。 -
注意
该函数用于调整对象缓存中可变长度的字符串的内存大小,字符串的内容不被保存。函数可给字符串分配一个新的内存空间,这时源内存空间将被释放。如果str为空,函数将直接给字符串分配空间。 如果 new_size为0,函数会释放字符串str所占的内存,并返回一个空指针值。
-
示例
OCIStringResize(env, error, new_size, &str);
3.13.6.OCIStringSize
-
功能
获得字符串的长度。
-
函数
sword OCIStringSize ( OCIEnv *env, CONST OCIString *vs ) -
参数
OCIStringSize 参数说明
名称 描述 env(输入/输出) 已初始化的环境句柄。 vs(输出) 需要处理的字符串。 -
注意
返回的字符串长度不包括'\0'结束符所占的字节。
-
示例
OCIStringSize(env, vs);
4.附录
-
由于显式的调用SQL语句并不会被OCI感知到,这可能导致OCI本身对事务的管理和大对象的管理出现错误,请避免显式的调用以下语句。
a. 事务相关操作。
b. 服务端的大对象操作接口。
-
使用大对象接口之前需要创建ux_lob_operate插件。
4.1.编译命令
gcc -o test test.c -DOCI_EXPORT -I/home/uxdb/uxdbinstall/dbsql/include/ -L/home/uxdb/uxdbinstall/dbsql/lib/oci -loci -Wl,-rpath=/home/uxdb/uxdbinstall/dbsql/lib/oci
4.2.创建表
#include <string.h>
#include <oci.h>
int main(int argc, char **argv)
{
int id = 0;
int val = 0;
OCIDefine *bhp1 = NULL;
OCIDefine *bhp2 = NULL;
ub2 datalen = 0;
sb4 rows_fetched = 0;
sb4 cols_fetched = 0;
ub4 sqllen = 0;
char *dbname = "localhost:52025/uxdb";
char *user = "uxdb";
char *password = "1qaz!QAZ";
/* 初始化环境句柄 */
OCIEnv *envhpp = NULL;
/* 初始化服务句柄 */
OCIServer *servhpp = NULL;
/* 初始化捕获错误句柄*/
OCIError *errhpp = NULL;
/* 初始化会话句柄 */
OCISession *usrhpp = NULL;
/* 初始化服务上下文句柄*/
OCISvcCtx *svchpp = NULL;
/* 初始化操作句柄 */
OCIStmt *stmthpp = NULL;
/* 创建OCI环境 */
sword swResult = OCIEnvCreate(&envhpp, OCI_DEFAULT, NULL, NULL, NULL, NULL, 0, NULL);
if(swResult != OCI_SUCCESS && swResult != OCI_SUCCESS_WITH_INFO)
{
printf("OCIEnvCreate Error!\n");
return -1;
}
/* 创建错误句柄 */
OCIHandleAlloc((dvoid *)envhpp, (dvoid **)&errhpp, OCI_HTYPE_ERROR, (size_t)0, (dvoid **)0);
printf("&errhpp = %p\n", errhpp);
/* 创建服务句柄 */
OCIHandleAlloc((dvoid *)envhpp, (dvoid **)&servhpp, OCI_HTYPE_SERVER, (size_t)0, (dvoid **)0);
printf("&servhpp = %p\n", servhpp);
/* 连接服务器 */
if (OCIServerAttach(servhpp, errhpp, (text *)dbname, strlen(dbname), OCI_DEFAULT) != OCI_SUCCESS)
{
printf("OCIServerAttach Error!\n");
return -1;
}
/* 创建服务上下文句柄*/
(void)OCIHandleAlloc((dvoid *)envhpp, (dvoid **)&svchpp, OCI_HTYPE_SVCCTX, (size_t)0, (dvoid **)0);
printf("&svchpp = %p\n", svchpp);
/* 设置属性 */
(void)OCIAttrSet((dvoid *)svchpp, OCI_HTYPE_SVCCTX, (dvoid *)servhpp, (ub4)0, OCI_ATTR_SERVER, (OCIError *)errhpp);
/* 创建用户连接句柄 */
(void)OCIHandleAlloc((dvoid *)envhpp, (dvoid **)&usrhpp, (ub4)OCI_HTYPE_SESSION, (size_t)0, (dvoid **)0);
printf("&usrhpp = %p\n", usrhpp);
/* 设置用户名 */
(void)OCIAttrSet((dvoid *)usrhpp, (ub4)OCI_HTYPE_SESSION, (dvoid *)user, (ub4)strlen(user), (ub4)OCI_ATTR_USERNAME, errhpp);
/* 设置密码 */
(void)OCIAttrSet((dvoid *)usrhpp, (ub4)OCI_HTYPE_SESSION, (dvoid *)password, (ub4)strlen(password), (ub4)OCI_ATTR_PASSWORD, errhpp);
/* 开启连接 */
if(OCISessionBegin(svchpp, errhpp, usrhpp, OCI_CRED_RDBMS, (ub4)OCI_DEFAULT) != OCI_SUCCESS)
{
OCIText errbuf[1024] = {0};
sb4 errcode = 0;
OCIText sqlstate[1024];
OCIErrorGet((dvoid *)errhpp, (ub4)1, sqlstate, &errcode, (OCIText *)errbuf, (ub4)sizeof(errbuf), OCI_HTYPE_ERROR);
printf("Error:%s\n", errbuf);
return -1;
}
/* 创建操作语句句柄 */
OCIHandleAlloc((dvoid *)envhpp, (dvoid **)&stmthpp, OCI_HTYPE_STMT, (size_t)0, (dvoid **)0);
printf("&stmthpp = %p\n", stmthpp);
/* 定义sql语句 */
OCIText sql1[255] = "create table tb1(id int, val int, val2 int);";
OCIText sql2[255] = "insert into tb1 values(1,10,33);";
OCIText sql3[255] = "insert into tb1 values(11,100,333);";
OCIText sql4[255] = "insert into tb1 values(111,1000,3333);";
OCIText sql5[255] = "insert into tb1 values(1111,10000,33333);";
OCIText sql6[255] = "select id,val from tb1 where id < 222;";
sb4 ret = 0;
OCIText err[128] = {'\0'};
if (OCIStmtPrepare(stmthpp, errhpp, (text *)sql1, strlen(sql1), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT) != OCI_SUCCESS)
{
printf("[ERROR] OCIStmtPrepare1\n");
return -1;
}
ret = OCIStmtExecute(svchpp, stmthpp, errhpp, (ub4)0, (ub4)0, NULL, NULL, OCI_DEFAULT); if(OCI_SUCCESS != ret)
{
OCIErrorGet(envhpp, 0, (OCIText *)0, (sb4)0, (OCIText *)err, sizeof(err),
OCI_HTYPE_ERROR);
printf("%s\n", err);
return -1;
}
if (OCIStmtPrepare(stmthpp, errhpp, (text *)sql2, strlen(sql2), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT) != OCI_SUCCESS)
{
printf("[ERROR] OCIStmtPrepare2\n");
return -1;
}
ret = OCIStmtExecute(svchpp, stmthpp, errhpp, (ub4)0, (ub4)0, NULL, NULL, OCI_DEFAULT);
if(OCI_SUCCESS != ret)
{
OCIErrorGet(envhpp, 0, (OCIText *)0, (sb4)0, (OCIText *)err, sizeof(err),
OCI_HTYPE_ERROR);
printf("%s\n", err);
return -1;
}
if (OCIStmtPrepare(stmthpp, errhpp, (text *)sql3, strlen(sql3), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT) != OCI_SUCCESS)
{
printf("[ERROR] OCIStmtPrepare3\n");
return -1;
}
ret = OCIStmtExecute(svchpp, stmthpp, errhpp, (ub4)0, (ub4)0, NULL, NULL, OCI_DEFAULT); if(OCI_SUCCESS != ret)
{
OCIErrorGet(envhpp, 0, (OCIText *)0, (sb4)0, (OCIText *)err, sizeof(err),
OCI_HTYPE_ERROR);
printf("%s\n", err);
return -1;
}
if (OCIStmtPrepare(stmthpp, errhpp, (text *)sql4, strlen(sql4), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT) != OCI_SUCCESS)
{
printf("[ERROR] OCIStmtPrepare4\n");
return -1;
}
ret = OCIStmtExecute(svchpp, stmthpp, errhpp, (ub4)0, (ub4)0, NULL, NULL, OCI_DEFAULT); if(OCI_SUCCESS != ret)
{
OCIErrorGet(envhpp, 0, (OCIText *)0, (sb4)0, (OCIText *)err, sizeof(err),
OCI_HTYPE_ERROR);
printf("%s\n", err);
return -1;
}
if (OCIStmtPrepare(stmthpp, errhpp, (text *)sql5, strlen(sql5), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT) != OCI_SUCCESS)
{
printf("[ERROR] OCIStmtPrepare4\n");
return -1;
}
ret = OCIStmtExecute(svchpp, stmthpp, errhpp, (ub4)0, (ub4)0, NULL, NULL, OCI_DEFAULT); if(OCI_SUCCESS != ret)
{
OCIErrorGet(envhpp, 0, (OCIText *)0, (sb4)0, (OCIText *)err, sizeof(err),
OCI_HTYPE_ERROR);
printf("%s\n", err);
}
/* 准备sql语句 */
//sqllen = OCIStringSize(envhpp, sql6);
sqllen = strlen(sql6);
if (OCIStmtPrepare(stmthpp, errhpp, (text *)sql6, sqllen, (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT) != OCI_SUCCESS)
{
printf("[ERROR] OCIStmtPrepare6\n");
return -1;
}
OCIDefineByPos(stmthpp, &bhp1, errhpp, 1, (dvoid *) &id, sizeof(id), SQLT_INT, NULL, &datalen, NULL, OCI_DEFAULT);
OCIDefineByPos(stmthpp, &bhp2, errhpp, 2, (dvoid *) &val, sizeof(val), SQLT_INT, NULL,
&datalen, NULL, OCI_DEFAULT);
/* 执行sql语句 */
OCIStmtExecute(svchpp, stmthpp, errhpp, (ub4)0, (ub4)0, NULL, NULL, OCI_DEFAULT);
do
{
p rintf("id = %d, val = %d\n", id, val);
} while (OCIStmtFetch(stmthpp, errhpp, 1, OCI_FETCH_NEXT, OCI_DEFAULT) != OCI_NO_DATA);
/* 获取执行结果 */
ret = OCIAttrGet((CONST void *)stmthpp, OCI_HTYPE_STMT, (void *) &rows_fetched, (ub4*)sizeof(rows_fetched), OCI_ATTR_ROW_COUNT, errhpp);
printf("rows = %d,ret = %d\n", rows_fetched, ret);
/* 断开服务器连接 */
OCIServerDetach(servhpp, errhpp, OCI_DEFAULT);
/*释放内存资源 */
ret = OCIHandleFree((dvoid *)stmthpp, OCI_HTYPE_STMT);
printf("ret = %d\n", ret);
ret = OCIHandleFree((dvoid *)svchpp, OCI_HTYPE_SVCCTX);
printf("ret = %d\n", ret);
ret = OCIHandleFree((dvoid *)servhpp, OCI_HTYPE_SERVER);
printf("ret = %d\n", ret);
ret = OCIHandleFree((dvoid *)errhpp, OCI_HTYPE_ERROR);
printf("ret = %d\n", ret);
ret = OCIHandleFree((dvoid *)usrhpp, OCI_HTYPE_SESSION);
printf("ret = %d\n", ret);
return 0;
}
4.3.插入数据及事务提交
#include <string.h>
#include <unistd.h>
#include "oci.h"
int main(int argc, char **argv)
{
int id = 0;
int val = 0;
OCIDefine *bhp1 = NULL;
OCIDefine *bhp2 = NULL;
ub2 datalen = 0;
int rows_fetched = 0;
char *dbname = "localhost:5433/uxdb";
char *user = "uxdb";
char *password = "1qaz!QAZ";
sb4 errcode;
OCIText sqlstate[128];
/* 初始化环境句柄 */
OCIEnv *envhpp = NULL;
/* 初始化服务句柄 */
OCIServer *servhpp = NULL;
/* 初始化捕获错误句柄*/
OCIError *errhpp = NULL;
/* 初始化会话句柄 */
OCISession *usrhpp = NULL;
/* 初始化服务上下文句柄*/
OCISvcCtx *svchpp = NULL;
/* 初始化操作句柄 */
OCIStmt *stmthpp = NULL;
/* 创建OCI环境 */
sword swResult = OCIEnvCreate(&envhpp, OCI_DEFAULT, NULL, NULL, NULL, NULL, 0, NULL);
if(swResult != OCI_SUCCESS && swResult != OCI_SUCCESS_WITH_INFO)
{
printf("OCIEnvCreate Error!\n");
return -1;
}
/* 创建错误句柄 */
OCIHandleAlloc((dvoid *)envhpp, (dvoid **)&errhpp, OCI_HTYPE_ERROR, (size_t)0, (dvoid **)0);
/* 创建服务句柄 */
OCIHandleAlloc((dvoid *)envhpp, (dvoid **)&servhpp, OCI_HTYPE_SERVER, (size_t)0, (dvoid **)0);
/* 连接服务器 */
if (OCIServerAttach(servhpp, errhpp, (text *)dbname, strlen(dbname), OCI_DEFAULT) != OCI_SUCCESS)
{
printf("OCIServerAttach Error!\n");
return -1;
}
/* 创建错误句柄 */
(void)OCIHandleAlloc((dvoid *)envhpp, (dvoid **)&errhpp, OCI_HTYPE_ERROR, (size_t)0, (dvoid **)0);
/* 创建服务上下文句柄*/
(void)OCIHandleAlloc((dvoid *)envhpp, (dvoid **)&svchpp, OCI_HTYPE_SVCCTX, (size_t)0, (dvoid **)0);
/* 设置属性 */
(void)OCIAttrSet((dvoid *)svchpp, OCI_HTYPE_SVCCTX, (dvoid *)servhpp, (ub4)0, OCI_ATTR_SERVER,(OCIError *)errhpp);
/* 创建用户连接句柄 */
(void)OCIHandleAlloc((dvoid *)envhpp, (dvoid **)&usrhpp, (ub4)OCI_HTYPE_SESSION, (size_t)0,(dvoid **)0);
/* 设置用户名 */
(void)OCIAttrSet((dvoid *)usrhpp, (ub4)OCI_HTYPE_SESSION, (dvoid *)user, (ub4)strlen(user), (ub4)OCI_ATTR_USERNAME, errhpp);
/* 设置密码 */
(void)OCIAttrSet((dvoid *)usrhpp, (ub4)OCI_HTYPE_SESSION, (dvoid *)password, (ub4)strlen(password),(ub4)OCI_ATTR_PASSWORD, errhpp);
/* 开启连接 */
if(OCISessionBegin(svchpp, errhpp, usrhpp, OCI_CRED_RDBMS, (ub4)OCI_DEFAULT) != OCI_SUCCESS)
{
char errbuf[128] = {'\0'};
OCIErrorGet((dvoid *)errhpp, (ub4)1, (OCIText *)sqlstate, &errcode, (OCIText *)errbuf,(ub4)sizeof(errbuf), OCI_HTYPE_ERROR);
printf("Error:%s\n", errbuf);
return -1;
}
/* 创建操作语句句柄 */
OCIHandleAlloc((dvoid *)envhpp, (dvoid **)&stmthpp, OCI_HTYPE_STMT, (size_t)0, (dvoid **)0);
/* 定义sql语句 */
char sqlcreate[255] = "create table IF NOT EXISTS tb1(id int, val int)";
char sql1[255] = "insert into tb1 values(6, 666);";
char sql2[255] = "insert into tb1 values(66, 6666);";
char sql3[255] = "select id,val from tb1;";
char sql4[255] = "update tb1 set val = 7777 where id = 66";
int ret;
char err[128] = {'\0'};
/*
* case1:正常执行事务提交成功
* 执行一个insert语句,事务正常提交成功 */
OCITransStart(svchpp, errhpp, 60, OCI_TRANS_NEW);
if (OCIStmtPrepare(stmthpp, errhpp, (text *)sqlcreate, strlen(sqlcreate),(ub4)OCI_NTV_SYNTAX,(ub4)OCI_DEFAULT) != OCI_SUCCESS)
{
printf("[ERROR] OCIStmtPrepare1\n");
return -1;
}
ret = OCIStmtExecute(svchpp, stmthpp, errhpp, (ub4)0, (ub4)0, NULL, NULL, OCI_DEFAULT); if(OCI_SUCCESS != ret)
{
OCIErrorGet(envhpp, 0, (OCIText *)sqlstate, &errcode, (OCIText *)err, sizeof(err), OCI_HTYPE_ERROR);
printf("[ERROR] sqlcreate %s\n", err);
return -1;
}
if (OCIStmtPrepare(stmthpp, errhpp, (text *)sql1, strlen(sql1), (ub4)OCI_NTV_SYNTAX,(ub4)OCI_DEFAULT) != OCI_SUCCESS)
{
printf("[ERROR] OCIStmtPrepare1\n");
return -1;
}
ret = OCIStmtExecute(svchpp, stmthpp, errhpp, (ub4)0, (ub4)0, NULL, NULL, OCI_DEFAULT); if(OCI_SUCCESS != ret)
{
OCIErrorGet(envhpp, 0, (OCIText *)sqlstate, &errcode, (OCIText *)err, sizeof(err), OCI_HTYPE_ERROR);
printf("[ERROR] OCIStmtExecute1 %s\n", err);
return -1;
}
if (OCIStmtPrepare(stmthpp, errhpp, (text *)sql2, strlen(sql2), (ub4)OCI_NTV_SYNTAX,(ub4)OCI_DEFAULT) != OCI_SUCCESS)
{
printf("[ERROR] OCIStmtPrepare2\n");
return -1;
}
ret = OCIStmtExecute(svchpp, stmthpp, errhpp, (ub4)0, (ub4)0, NULL, NULL, OCI_DEFAULT); if(OCI_SUCCESS != ret)
{
OCIErrorGet(envhpp, 0, (OCIText *)sqlstate, &errcode, (OCIText *)err, sizeof(err), OCI_HTYPE_ERROR);
printf("[ERROR] OCIStmtExecute2 %s\n", err);
return -1;
}
if (OCIStmtPrepare(stmthpp, errhpp, (text *)sql4, strlen(sql4), (ub4)OCI_NTV_SYNTAX,(ub4)OCI_DEFAULT) != OCI_SUCCESS)
{
printf("[ERROR] OCIStmtPrepare3\n");
return -1;
}
ret = OCIStmtExecute(svchpp, stmthpp, errhpp, (ub4)0, (ub4)0, NULL, NULL, OCI_DEFAULT);
if(OCI_SUCCESS != ret)
{
OCIErrorGet(envhpp, 0, (OCIText *)sqlstate, &errcode, (OCIText *)err, sizeof(err), OCI_HTYPE_ERROR);
printf("[ERROR] OCIStmtExecute3 %s\n", err);
return -1;
}
ret = OCITransCommit(svchpp, errhpp, 0);
if (ret != OCI_SUCCESS)
{
OCIErrorGet(envhpp, 0, (OCIText *)sqlstate, &errcode, (OCIText *)err, sizeof(err), OCI_HTYPE_ERROR);
printf("OCITransCommit: case 1 test error!\n");
printf("result=%d,errmsg=%s\n", ret, err);
}
else
printf("OCITransCommit: case 1 test sucess!\n");
/*
* case2:构造异常情况测试返回值和error信息
* 1)构造服务器连接异常错误
* 2)构造重复提交错误
*/
/*此处停止数据库,则进行异常情况测试,可以打印错误信息 */
/* 不停止数据库,则继续正常处理 */
printf("If stop db to generated an error!\n");
sleep(2);
ret = OCITransCommit(svchpp, errhpp, 0);
if (ret != OCI_SUCCESS)
{
OCIErrorGet(envhpp, 0, (OCIText *)sqlstate, &errcode, (OCIText *)err, sizeof(err), OCI_HTYPE_ERROR);
printf("OCITransCommit: case 2 test error result!\n");
printf("result=%d,errmsg=%s\n", ret, err);
}
else
printf("OCITransCommit: case 2 test sucess result!\n");
ub4 sqllen = strlen(sql3);
if (OCIStmtPrepare(stmthpp, errhpp, (text *)sql3, sqllen, (ub4)OCI_NTV_SYNTAX,(ub4)OCI_DEFAULT) != OCI_SUCCESS)
{
printf("[ERROR] OCIStmtPrepare6\n");
return -1;
}
OCIDefineByPos(stmthpp, &bhp1, errhpp, 1, (dvoid *)&id, sizeof(id), SQLT_INT, NULL, &datalen, NULL, OCI_DEFAULT);
OCIDefineByPos(stmthpp, &bhp2, errhpp, 2, (dvoid *)&val, sizeof(val), SQLT_INT, NULL, &datalen, NULL, OCI_DEFAULT);
/* 执行sql语句 */
OCIStmtExecute(svchpp, stmthpp, errhpp, (ub4)0, (ub4)0, NULL, NULL, OCI_DEFAULT);
while (OCIStmtFetch(stmthpp, errhpp, 1, OCI_FETCH_NEXT, OCI_DEFAULT) != OCI_NO_DATA)
{
printf("id = %d, val = %d\n", id, val);
}
/* 获取执行结果 */
OCIAttrGet((CONST void *)stmthpp, OCI_HTYPE_STMT, (void *)&rows_fetched,(ub4 *)sizeof(rows_fetched), OCI_ATTR_ROW_COUNT, errhpp);
printf("rows:%d\n", rows_fetched);
/* 断开服务器连接 */
OCIServerDetach(servhpp, errhpp, OCI_DEFAULT);
/*释放内存资源 */
OCIHandleFree((dvoid *)stmthpp, OCI_HTYPE_STMT);
OCIHandleFree((dvoid *)svchpp, OCI_HTYPE_SVCCTX);
OCIHandleFree((dvoid *)servhpp, OCI_HTYPE_SERVER);
OCIHandleFree((dvoid *)errhpp, OCI_HTYPE_ERROR);
return 0;
}
4.4.多行绑定
#include <string.h>
#include <oci.h>
#define ARRAYSIZE 10
#define NAME_LEN 20
typedef struct
{
char id[10];
char sname[20];
int age;
char sex[10];
}stuData;
/* 指示器数组 */
typedef struct
{
sb2 sb2_id[ARRAYSIZE];
sb2 sb2_sname[ARRAYSIZE];
sb2 sb2_age[ARRAYSIZE];
sb2 sb2_sex[ARRAYSIZE];
} stdInd_T;
/* 字段长度数组 */
typedef struct
{
ub2 ub2_id[ARRAYSIZE];
ub2 ub2_sname[ARRAYSIZE];
ub2 ub2_age[ARRAYSIZE];
ub2 ub2_sex[ARRAYSIZE];
} stdLen_T;
stuData tstd[ARRAYSIZE]; /* 数组变量,用于批量操作 */
OCIBind *bindp[ARRAYSIZE] = {0};
OCIDefine *defnp[ARRAYSIZE] = {0};
stuData tstd[ARRAYSIZE]; /* 数组变量,用于批量操作 */
stdInd_T tstdInd;
stdLen_T tstdLen;
stdLen_T tstdRet;
stuData results[ARRAYSIZE];
sb2 sb2aIndid[ARRAYSIZE] = {0}; /* 指示器变量,用于取可能存在空值的字 */
ub2 datalen[ARRAYSIZE] = {0}; /* 获取数据长度 */
char id[NAME_LEN] = {0};
char sname[NAME_LEN] = {0};
int age = 0;
char sex[NAME_LEN] = {0};
static void init_bind_parameter()
{
int i = 0;
memset(tstd, 0, ARRAYSIZE * sizeof(stuData));
for (i = 0; i < ARRAYSIZE; i++)
{
snprintf(tstd[i].id,10,"ID%d",i);
snprintf(tstd[i].sname,20,"李%d",i);
tstd[i].age = i + 10;
if(i % 2 == 0)
snprintf(tstd[i].sex,10,"%s","女");
else
snprintf(tstd[i].sex,10,"%s","男");
}
}
CONST OraText dbname[] = "localhost:52025"; /* ip:port/dbname */
OraText usname[100] = "uxdb";
CONST OraText pwd[] = "1qaz!QAZ";
int main(int argc, char **argv)
{
/* 初始化环境句柄 */
OCIEnv *envhpp = NULL;
/* 初始化服务句柄 */
OCIServer *servhpp = NULL;
/* 初始化捕获错误句柄*/
OCIError *errhpp = NULL;
/* 初始化会话句柄 */
OCISession *usrhpp = NULL;
/* 初始化服务上下文句柄*/
OCISvcCtx *svchpp = NULL;
/* 初始化操作句柄 */
OCIStmt *stmthpp = NULL;
OCIEnv *env = NULL;
OCISvcCtx *sc = NULL;
OCIStmt *stmt = NULL;
OCIError *error = NULL;
int i = 0;
int rowoff = 5;
int update_or_delete_rownum = 2;
int rowoff1 = 1;
int new_age[2] = {20,21};
char pid[2][10] ={0};
char sqlselect[] = "select id,sname,age,sex from stu";
char sqldrop[] = "drop table if exists stu;";
char sqlcreate[] = "create table stu(id varchar(100) not null , sname varchar, age int, sex varchar); ";
char sqlbind[] = "insert into stu(id,sname,age,sex) values(:Vhid,:Vhname,:Vhage,:Vhsex)";
int retcode = -1;
retcode = OCIInitialize((ub4)OCI_DEFAULT, (dvoid *)0, (dvoid * (*)(dvoid *, size_t))0, (dvoid * (*)(dvoid *, dvoid *, size_t))0, (void (*)(dvoid *, dvoid *))0);
if (OCI_SUCCESS != retcode)
{
printf("error : OCIInitialize!\n");
return retcode;
}
retcode = OCIEnvInit((dvoid *)&env, (ub4)OCI_DEFAULT, (size_t)0, (dvoid **)0);
if (OCI_SUCCESS != retcode)
{
printf("error : OCIEnvInit!\n");
return retcode;
}
retcode = OCIHandleAlloc(env, (dvoid *)&sc, (ub4)OCI_HTYPE_SVCCTX, (size_t)0,(dvoid **)0);
if (OCI_SUCCESS != retcode)
{
printf("1failed to allocate connection handle!\n");
return retcode;
}
retcode = OCIHandleAlloc(env, (dvoid *)&error, (ub4)OCI_HTYPE_ERROR, (size_t)0,(dvoid **)0);
if (OCI_SUCCESS != retcode)
{
printf("2failed to allocate error handle!\n");
return retcode;
}
retcode = OCILogon(env, error, &sc, usname, strlen((char *)usname), pwd, strlen((char *)pwd), dbname, strlen((char *)dbname));
if (OCI_SUCCESS != retcode)
{
printf("unable to connect to the database!\n");
return retcode;
}
retcode = OCIHandleAlloc(env, (dvoid *)&stmt, (ub4)OCI_HTYPE_STMT, (size_t)0,(dvoid **)0);
if (OCI_SUCCESS != retcode)
{
printf("failed to allocate statement handle!\n");
return retcode;
}
/* 删除表*/
retcode = OCIStmtPrepare(stmt, error, (text *)sqldrop, (ub4)strlen(sqldrop), (ub4)OCI_NTV_SYNTAX,(ub4)OCI_DEFAULT);
if (OCI_SUCCESS != retcode)
{
printf("failed to prepare sql!\n");
return retcode;
}
retcode = OCIStmtExecute(sc, stmt, error, (ub4)1, (ub4)0, (OCISnapshot *)NULL, (OCISnapshot *)NULL, (ub4)OCI_DEFAULT);
if (OCI_SUCCESS != retcode)
{
printf("failed to execute sql!\n");
return retcode;
}
/* 创建表*/
retcode = OCIStmtPrepare(stmt, error, (text *)sqlcreate, (ub4)strlen(sqlcreate), (ub4)OCI_NTV_SYNTAX,(ub4)OCI_DEFAULT);
if (OCI_SUCCESS != retcode)
{
printf("failed to prepare sql!\n");
return retcode;
}
retcode = OCIStmtExecute(sc, stmt, error, (ub4)1, (ub4)0, (OCISnapshot *)NULL, (OCISnapshot *)NULL, (ub4)OCI_DEFAULT);
if (OCI_SUCCESS != retcode)
{
printf("failed to execute sql!\n");
return retcode;
}
/* 初始化变量数组 */
init_bind_parameter();
/*************************************/
/********* 参数绑定 *********/
/*************************************/
retcode = OCIStmtPrepare(stmt, error, (text *)sqlbind, (ub4)strlen(sqlbind), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT);
retcode = OCIBindByPos(stmt, &bindp[0], error, 1, tstd[0].id, sizeof(tstd[0].id), SQLT_STR, &tstdInd.sb2_id[0], 0, 0, 0, 0, OCI_DEFAULT);
retcode = OCIBindByPos(stmt, &bindp[1], error, 2, tstd[0].sname, sizeof(tstd[0].sname), SQLT_STR, &tstdInd.sb2_sname[0], 0, 0, 0, 0, OCI_DEFAULT);
retcode = OCIBindByPos(stmt, &bindp[2], error, 3, (dvoid *)&tstd[0].age, sizeof(tstd[0].age),SQLT_INT, &tstdInd.sb2_age[0], (ub2 *)0, (ub2)0, (ub4)0, (ub4 *)0, OCI_DEFAULT);
retcode = OCIBindByPos(stmt, &bindp[3], error, 4, tstd[0].sex, sizeof(tstd[0].sex), SQLT_STR, &tstdInd.sb2_sex[0], (ub2 *)0, (ub2)0, (ub4)0, (ub4 *)0, OCI_DEFAULT);
/****************************************/
/********* 变量数组绑定 *********/
/****************************************/
retcode = OCIBindArrayOfStruct(bindp[0], error,sizeof(tstd[0]), 0, 0, 0);
retcode = OCIBindArrayOfStruct(bindp[1], error,sizeof(tstd[0]), 0, 0, 0);
retcode = OCIBindArrayOfStruct(bindp[2], error,sizeof(tstd[0]), 0, 0, 0);
retcode = OCIBindArrayOfStruct(bindp[3], error,sizeof(tstd[0]), 0, 0, 0);
/*************************************/
/********* 插入 *********/
/*************************************/
retcode = OCIStmtExecute(sc, stmt, error, (ub4)ARRAYSIZE, (ub4)0, (OCISnapshot *)NULL, (OCISnapshot *)NULL, (ub4)OCI_DEFAULT);
/*************************************/
/********* 查询 *********/
/*************************************/
retcode = OCIStmtPrepare(stmt, error, (text *)sqlselect, (ub4)strlen(sqlselect), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT);
/* 绑定输出参数 */
retcode = OCIDefineByPos(stmt, &defnp[0], error, 1, (dvoid *)id, (ub4)sizeof(id),SQLT_STR, &sb2aIndid[0], (ub2 *)&datalen[0], NULL, OCI_DEFAULT);
retcode = OCIDefineByPos(stmt, &defnp[1], error, 2, (dvoid *)sname, (ub4)sizeof(sname),SQLT_STR, &sb2aIndid[1], (ub2 *)&datalen[1], NULL, OCI_DEFAULT);
retcode = OCIDefineByPos(stmt, &defnp[2], error, 3, (dvoid *)&age, (ub4)sizeof(age),SQLT_INT, &sb2aIndid[2], (ub2 *)&datalen[2], NULL, OCI_DEFAULT);
retcode = OCIDefineByPos(stmt, &defnp[3], error, 4, (dvoid *)sex, (ub4)sizeof(sex),SQLT_STR, &sb2aIndid[3], (ub2 *)&datalen[3], NULL, OCI_DEFAULT);
/* 执行SQL sqlselect */
retcode = OCIStmtExecute(sc, stmt, error, (ub4)0, (ub4)0, (OCISnapshot *)NULL,(OCISnapshot *)NULL, (ub4)OCI_DEFAULT);
/******************************************/
/********* 获取结果集 *********/
/******************************************/
while ((retcode = OCIStmtFetch(stmt, error, 1, OCI_FETCH_NEXT, OCI_DEFAULT)) != OCI_NO_DATA)
{
printf("id = %s, name = %s, age = %d, sex = %s\n", id, sname, age, sex);
}
return 0;
}
4.5.大对象
前提:需要用户找一个图片并命名为cat.gif。
#include<oci.h>
int retcode = 0;
/* 调用函数OCIStmtPrepare准备语句,调用函数OCIStmtExecute执行语句 */
sword oci_stmt_execute(OCISvcCtx *sc, OCIStmt *stmt, OCIError *error, const char *sql)
{
retcode = OCIStmtPrepare(stmt, error, (text *)sql, (ub4)strlen(sql), (ub4)OCI_NTV_SYNTAX,(ub4)OCI_DEFAULT);
if (OCI_SUCCESS != retcode)
{
printf("failed to prepare sql!\n");
return retcode;
}
retcode = OCIStmtExecute(sc, stmt, error, (ub4)1, (ub4)0, (OCISnapshot *)NULL, (OCISnapshot *)NULL, (ub4)OCI_DEFAULT);
if (OCI_SUCCESS != retcode)
{
printf("failed to execute sql!\n");
return retcode;
}
}
/* 调用函数OCILogoff断开数据库连接,并释放环境、连接、语句、错误句柄 */
sword oci_logoff_disconnect(OCIEnv *env, OCISvcCtx *sc, OCIStmt *stmt, OCIError *error)
{
retcode = OCIHandleFree((dvoid *)stmt, (ub4)OCI_HTYPE_STMT);
if (OCI_SUCCESS != retcode)
{
printf("failed to release statement handle!\n");
return retcode;
}
retcode = OCILogoff(sc, error);
if (OCI_SUCCESS != retcode)
{
printf("logout database connection failed!\n");
return retcode;
}
retcode = OCIHandleFree((dvoid *)sc, (ub4)OCI_HTYPE_SVCCTX);
if (OCI_SUCCESS != retcode)
{
printf("failed to release connection handle!\n");
return retcode;
}
retcode = OCIHandleFree((dvoid *)env, (ub4)OCI_HTYPE_ENV);
if (OCI_SUCCESS != retcode)
{
printf("failed to release environment handle!\n");
return retcode;
}
retcode = OCIHandleFree((dvoid *)error, (ub4)OCI_HTYPE_ERROR);
if (OCI_SUCCESS != retcode)
{
printf("failed to release error handle!\n");
return retcode;
}
return retcode;
}
/* 调用函数OCILogon进行连接 */
sword oci_logon_connect(OCIEnv **env, OCISvcCtx **sc, OCIStmt **stmt, OCIError **error, CONST OraText *username,CONST OraText *password, CONST OraText *dbname)
{
retcode = OCIInitialize((ub4)OCI_DEFAULT, (dvoid *)0, (dvoid * (*)(dvoid *, size_t))0, (dvoid * (*)(dvoid *, dvoid *, size_t))0, (void (*)(dvoid *, dvoid *))0);
if (OCI_SUCCESS != retcode)
{
printf("error : OCIInitialize!\n");
return retcode;
}
retcode = OCIEnvInit(env, (ub4)OCI_DEFAULT, (size_t)0, (dvoid **)0);
if (OCI_SUCCESS != retcode)
{
printf("error : OCIEnvInit!\n");
return retcode;
}
retcode = OCIHandleAlloc((dvoid *)*env, (dvoid **)sc, (ub4)OCI_HTYPE_SVCCTX, (size_t)0,(dvoid **)0);
if (OCI_SUCCESS != retcode)
{
printf("failed to allocate connection handle!\n");
return retcode;
}
retcode = OCIHandleAlloc((dvoid *)*env, (dvoid **)error, (ub4)OCI_HTYPE_ERROR, (size_t)0,(dvoid **)0);
if (OCI_SUCCESS != retcode)
{
printf("failed to allocate error handle!\n");
return retcode;
}
retcode = OCILogon(*env, *error, sc, username, strlen((char *)username), password, strlen((char *)password), dbname, strlen((char *)dbname));
if (OCI_SUCCESS != retcode)
{
printf("unable to connect to the database!\n");
return retcode;
}
retcode = OCIHandleAlloc((dvoid *)*env, (dvoid **)stmt, (ub4)OCI_HTYPE_STMT, (size_t)0,(dvoid **)0);
if (OCI_SUCCESS != retcode)
{
printf("failed to allocate statement handle!\n");
return retcode;
}
return retcode;
}
int main(void)
{
OCIEnv *env = NULL;
OCISvcCtx *svcctx = NULL;
OCIStmt *stmt = NULL;
OCIError *error = NULL;
char usname[] = "UXDB";
char pwd[] = "1qaz!QAZ";
char dbname[] = "127.0.0.1:52025/UXDB";
char bufferR[2048] = {0};
char bufgifw[2048] = {0};
const char *bufferW = "abcdefghijklmnopqrstuvwxyz";
char sqldroplob[] = "drop table if exists blo;";
char sqlcreatelob[] = "create table blo(id varchar,text blob, text2 clob);";
char sqlinsertlob[] = "insert into blo(id,text,text2) values(:Vhid,:Vhtext,:Vhtext2)";
char sqlselectlob[] = "select textout(id),text,text2 from blo where id = :id;";
OCILobLocator *lob;
OCILobLocator *lobgif;
FILE *filepw, *filepr;
ub2 indp = 1;
ub4 amtp = strlen(bufferW);
ub4 lob_offset = 0;
ub1 piece = 0;
ub4 size = 0;
/*
* 初始化
*/
oci_logon_connect(&env, &svcctx, &stmt, &error, usname, pwd, dbname);
OCIDescriptorAlloc((dvoid *)env, (dvoid **)&lob, (ub4)OCI_DTYPE_LOB, (size_t)0, (dvoid **)0);
OCILobCreateTemporary(svcctx, error, lob, 0, SQLCS_IMPLICIT, OCI_TEMP_BLOB, OCI_ATTR_NOCACHE, (OCIDuration)0);
OCIDescriptorAlloc((dvoid *)env, (dvoid **)&lobgif, (ub4)OCI_DTYPE_LOB, (size_t)0, (dvoid **)0);
OCILobCreateTemporary(svcctx, error, lobgif, 0, SQLCS_IMPLICIT, OCI_TEMP_BLOB, OCI_ATTR_NOCACHE, (OCIDuration)0);
oci_stmt_execute(svcctx, stmt, error, sqldroplob);
oci_stmt_execute(svcctx, stmt, error, sqlcreatelob);
/*
* 图片写入
*/
lob_offset = 0;
size = 0;
/* 以rb方式打开文件 */
if ((filepr = fopen("./cat.gif", "rb")) == NULL)
{
printf("filepr:文件打开发生错误!\n");
exit(0);
}
fseek(filepr, 0, SEEK_END);
size = ftell(filepr);
fseek(filepr, 0, SEEK_SET);
int pos = 0;
int ret = 0;
while((ret = fread(bufgifw, 1, sizeof(bufgifw), filepr)) == sizeof(bufgifw))
{
OCILobWrite(svcctx, error, lobgif, &amtp, pos, (dvoid *)bufgifw, sizeof(bufgifw), piece,\(dvoid *)0, (sb4(*(*)())(dvoid *, dvoid *, ub4 *, ub1 *))0, (ub2)0, (ub1)SQLCS_IMPLICIT);
pos += sizeof(bufgifw);
memset(bufgifw, 0, sizeof(bufgifw));
}
OCILobWrite(svcctx, error, lobgif, &amtp, pos, (dvoid *)bufgifw, ret, piece,\(dvoid *)0, (sb4(*(*)())(dvoid *, dvoid *, ub4 *, ub1 *))0, (ub2)0, (ub1)SQLCS_IMPLICIT);
fclose(filepr);
/*
* 图片读取
*/
ub4 sizeR = 0;
OCILobGetLength(svcctx, error, lobgif, &sizeR);
/* 以wb+(二进制写入)方式打开文件 */
if ((filepw = fopen("./out.gif", "wb+")) == NULL)
{
printf("filepw:文件打开发生错误!\n");
exit(0);
}
pos = 0;
while(sizeR - pos >= sizeof(bufferR))
{
OCILobRead(svcctx, error, lobgif, &amtp, pos, (void *)bufferR, sizeof(bufferR),\(dvoid *)0, 0, (ub2)0, (ub1)SQLCS_IMPLICIT);
fwrite(bufferR, 1, sizeof(bufferR), filepw);
pos += sizeof(bufferR);
memset(bufferR, 0, sizeof(bufferR));
}
OCILobRead(svcctx, error, lobgif, &amtp, pos, (void *)bufferR, sizeR - pos,\(dvoid *)0, 0, (ub2)0, (ub1)SQLCS_IMPLICIT);
fwrite(bufferR, 1, sizeR - pos, filepw);
fclose(filepw);
/*
* 清理
*/
/* 释放大对象 */
OCILobFreeTemporary(svcctx, error, lob);OCILobFreeTemporary(svcctx, error, lobgif);
/* 释放lob句柄 */
OCIDescriptorFree(lob, OCI_DTYPE_LOB);
OCIDescriptorFree(lobgif, OCI_DTYPE_LOB);
oci_logoff_disconnect(env, svcctx, stmt, error);
}
4.6.多事务
#include <string.h>
#include <oci.h>
CONST OraText dbname[] = "localhost:52025"; /* ip:port/dbname */
OraText usname[100] = "uxdb";
CONST OraText pwd[] = "1qaz!QAZ";
int retcode = 0;
/* 调用函数OCILogon进行连接 */
sword oci_logon_connect(OCIEnv **env, OCISvcCtx **sc, OCIStmt **stmt, OCIError **error, CONST OraText *username,CONST OraText *password, CONST OraText *dbname)
{
retcode = OCIInitialize((ub4)OCI_DEFAULT, (dvoid *)0, (dvoid * (*)(dvoid *, size_t))0, (dvoid * (*)(dvoid *, dvoid *, size_t))0, (void (*)(dvoid *, dvoid *))0);
if (OCI_SUCCESS != retcode)
{
printf("error : OCIInitialize!\n");
return retcode;
}
retcode = OCIEnvInit(env, (ub4)OCI_DEFAULT, (size_t)0, (dvoid **)0);
if (OCI_SUCCESS != retcode)
{
printf("error : OCIEnvInit!\n");
return retcode;
}
retcode = OCIHandleAlloc((dvoid *)*env, (dvoid **)sc, (ub4)OCI_HTYPE_SVCCTX, (size_t)0,(dvoid **)0);
if (OCI_SUCCESS != retcode)
{
printf("failed to allocate connection handle!\n");
return retcode;
}
retcode = OCIHandleAlloc((dvoid *)*env, (dvoid **)error, (ub4)OCI_HTYPE_ERROR, (size_t)0,(dvoid **)0);
if (OCI_SUCCESS != retcode)
{
printf("failed to allocate error handle!\n");
return retcode;
}
retcode = OCILogon(*env, *error, sc, username, strlen((char *)username), password, strlen((char *)password), dbname, strlen((char *)dbname));
if (OCI_SUCCESS != retcode)
{
printf("unable to connect to the database!\n");
return retcode;
}
retcode = OCIHandleAlloc((dvoid *)*env, (dvoid **)stmt, (ub4)OCI_HTYPE_STMT, (size_t)0,(dvoid **)0);
if (OCI_SUCCESS != retcode)
{
printf("failed to allocate statement handle!\n");
return retcode;
}
return retcode;
}
/* 重新连接,并重新分配语句句柄 */
sword oci_reconnect(OCIEnv *env, OCISvcCtx *sc, OCIStmt **stmt, OCIError *error, CONST OraText *username,CONST OraText *password, CONST OraText *dbname)
{
retcode = OCIHandleFree((dvoid *)*stmt, (ub4)OCI_HTYPE_STMT);
if (OCI_SUCCESS != retcode)
{
printf("failed to release statement handle!\n");
return retcode;
}
retcode = OCILogoff(sc, error);
if (OCI_SUCCESS != retcode)
{
printf("logout database connection failed!\n");
return retcode;
}
retcode = OCILogon(env, error, &sc, username, strlen((char *)usname), password, strlen((char *)pwd), dbname, strlen((char *)dbname));
if (OCI_SUCCESS != retcode)
{
printf("unable to connect to the database!\n");
return retcode;
}
retcode = OCIHandleAlloc((dvoid *)env, (dvoid **)stmt, (ub4)OCI_HTYPE_STMT, (size_t)0,(dvoid **)0);
if (OCI_SUCCESS != retcode)
{
printf("failed to allocate statement handle!\n");
return retcode;
}
return retcode;
}
/* 调用函数OCIStmtPrepare准备语句,调用函数OCIStmtExecute执行语句 */
sword oci_stmt_execute(OCISvcCtx *sc, OCIStmt *stmt, OCIError *error, char *sql)
{
retcode = OCIStmtPrepare(stmt, error, (text *)sql, (ub4)strlen(sql), (ub4)OCI_NTV_SYNTAX,(ub4)OCI_DEFAULT);
if (OCI_SUCCESS != retcode)
{
printf("failed to prepare sql!\n");
return retcode;
}
retcode = OCIStmtExecute(sc, stmt, error, (ub4)1, (ub4)0, (OCISnapshot *)NULL, (OCISnapshot *)NULL, (ub4)OCI_DEFAULT);
if (OCI_SUCCESS != retcode)
{
printf("failed to execute sql!\n");
return retcode;
}
}
/* 调用函数OCILogoff断开数据库连接,并释放环境、连接、语句、错误句柄 */
sword oci_logoff_disconnect(OCIEnv *env, OCISvcCtx *sc, OCIStmt *stmt, OCIError *error)
{
retcode = OCIHandleFree((dvoid *)stmt, (ub4)OCI_HTYPE_STMT);
if (OCI_SUCCESS != retcode)
{
printf("failed to release statement handle!\n");
return retcode;
}
retcode = OCILogoff(sc, error);
if (OCI_SUCCESS != retcode)
{
printf("logout database connection failed!\n");
return retcode;
}
retcode = OCIHandleFree((dvoid *)sc, (ub4)OCI_HTYPE_SVCCTX);
if (OCI_SUCCESS != retcode)
{
printf("failed to release connection handle!\n");
return retcode;
}
retcode = OCIHandleFree((dvoid *)env, (ub4)OCI_HTYPE_ENV);
if (OCI_SUCCESS != retcode)
{
printf("failed to release environment handle!\n");
return retcode;
}
retcode = OCIHandleFree((dvoid *)error, (ub4)OCI_HTYPE_ERROR);
if (OCI_SUCCESS != retcode)
{
printf("failed to release error handle!\n");
return retcode;
}
return retcode;
}
int main(int argc, char **argv)
{
OCIEnv *env = NULL;
OCISvcCtx *sc = NULL;
OCIStmt *stmt = NULL;
OCIError *error = NULL;
OCITrans *tran1 = NULL;
OCITrans *tran2 = NULL;
int c1 = 0;
retcode = oci_logon_connect(&env, &sc, &stmt, &error, usname, pwd, dbname);
/* 使用主事务创建表t1 */
retcode = oci_stmt_execute(sc, stmt, error, (char *)"create table t1(c1 int);");
/* 提交主事务 */
retcode = OCITransCommit(sc, error, OCI_DEFAULT);
/* 分配事务句柄1,并附加至连接 */
retcode = OCIHandleAlloc(env, (void **)&tran1, OCI_HTYPE_TRANS, 0, 0);
retcode = OCIAttrSet(sc, OCI_HTYPE_SVCCTX, tran1, 0, OCI_ATTR_TRANS, error);
/* 开启新事务1 */
retcode = OCITransStart(sc, error, 0, OCI_TRANS_NEW);
/* 使用事务1插入数据 */
retcode = oci_stmt_execute(sc, stmt, error, (char *)"insert into t1 values(1);");
/* 分离事务1 */
retcode = OCITransDetach(sc, error, OCI_DEFAULT);
/* 分配事务句柄2,并附加至连接 */
retcode = OCIHandleAlloc(env, (void **)&tran2, OCI_HTYPE_TRANS, 0, 0);
retcode = OCIAttrSet(sc, OCI_HTYPE_SVCCTX, tran2, 0, OCI_ATTR_TRANS, error);
/* 开启新的可串行事务2 */
retcode = OCITransStart(sc, error, 0, OCI_TRANS_NEW | OCI_TRANS_SERIALIZABLE);
/* 使用可串行事务2查询表t1 */
retcode = oci_stmt_execute(sc, stmt, error, (char *)"select * from t1;");
/* 插入未提交查询不到数据 */
retcode = OCIStmtFetch(stmt, error, 1, OCI_FETCH_NEXT, OCI_DEFAULT);
/* 分离事务2 */
retcode = OCITransDetach(sc, error, OCI_DEFAULT);
/* 附加事务1 */
retcode = OCIAttrSet(sc, OCI_HTYPE_SVCCTX, tran1, 0, OCI_ATTR_TRANS, error);
/* 提交事务1 */
retcode = OCITransCommit(sc, error, OCI_DEFAULT);
/* 附加事务2 */
retcode = OCIAttrSet(sc, OCI_HTYPE_SVCCTX, tran2, 0, OCI_ATTR_TRANS, error);
/* 使用可串行事务2查询表t1 */
retcode = oci_stmt_execute(sc, stmt, error, (char *)"select * from t1;");
/* 由于是可串行事务不会发生幻读 */
retcode = OCIStmtFetch(stmt, error, 1, OCI_FETCH_NEXT, OCI_DEFAULT);
/* 清理环境 */
retcode = oci_stmt_execute(sc, stmt, error, (char *)"drop table if exists t1,t2,t3;");
retcode = OCITransCommit(sc, error, OCI_DEFAULT);
retcode = OCIHandleFree(tran1, OCI_HTYPE_TRANS);
retcode = OCIHandleFree(tran2, OCI_HTYPE_TRANS);
retcode = oci_logoff_disconnect(env, sc, stmt, error);
return 0;
}