DPI 编程指南

2.1 基础简介

本章主要介绍DPI的基本概念以及使用方法,以便于用户更好地使用DPI编写应用程序。DPI提供了访问DM数据库的最直接的途径。

DPI的实现参考了Microsoft ODBC 3.0标准,函数功能以及调用过程与ODBC 3.0十分类似,命名统一采用dpi开头的小写英文字母方式,各个单词之间以下划线分割(例:ODBC函数SQLAllocStmt对应的DPI函数就是dpi_alloc_stmt),用户可以参考《Microsoft ODBC 3.0程序员参考手册(第二卷)》之API参考部分的函数说明及调用方法。

句柄

句柄是用于DPI函数申请和使用资源的变量。达梦DPI包含以下句柄:

句柄 说明 宏定义
dhenv 环境句柄 DSQL_HANDLE_ENV
dhcon 连接句柄 DSQL_HANDLE_DBC
dhstmt 语句句柄 DSQL_HANDLE_STMT
dhdesc 描述符句柄 DSQL_HANDLE_DESC
dhloblctr Lob句柄 DSQL_HANDLE_LOB_LOCATOR
dhobj 复合类型句柄 DSQL_HANDLE_OBJECT
dhobjdesc 复合类型描述符句柄 DSQL_HANDLE_OBJDESC
dhbfile BFILE文件句柄 DSQL_HANDLE_BFILE

返回值

DPI的函数执行结果通过返回值来反馈给用户,DPI包含以下返回值:

宏定义 说明
DSQL_SUCCESS 0 执行成功
DSQL_SUCCESS_WITH_INFO 1 执行成功,有警告信息
DSQL_NO_DATA 100 未取得数据
DSQL_ERROR -1 执行失败
DSQL_INVALID_HANDLE -2 非法的句柄
DSQL_NEED_DATA 99 需要数据
DSQL_STILL_EXECUTING 2 语句正在执行
DSQL_PARAM_DATA_AVAILABLE 101 有参数值可以获取

数据类型

数据类型为数据库中字段类型和C语言的数据类型。

DPI中包括以下DSQL类型,对应对象创建时指定的类型:

宏定义 定义类型 说明
DSQL_CHAR char[(n)] 定长字符类型
DSQL_VARCHAR varchar(n) 变长字符类型
DSQL_BIT bit 位类型
DSQL_TINYINT tinyint 有符号小整型(1字节)
DSQL_SMALLINT smallint 有符号短整型(2字节)
DSQL_INT int 有符号整型(4字节)
DSQL_BIGINT bigint 有符号长整型(8字节)
DSQL_DEC dec[(p,s)] numeric[(p,s)] number[(p,s)] 精确数字类型
DSQL_FLOAT real 单精度浮点型
DSQL_DOUBLE float double 双精度浮点型
DSQL_BLOB blob image longvarbinary 二进制大字段
DSQL_DATE date 日期
DSQL_TIME time[(n)] 时间
DSQL_TIMESTAMP timestamp[(n)] 时间戳
DSQL_BINARY binary[(n)] 二进制类型
DSQL_VARBINARY varbinary[(n)] 变长二进制类型
DSQL_CLOB clob text longvarchar 字符大字段
DSQL_TIME_TZ time with time zone 带时区的时间类型
DSQL_TIMESTAMP_TZ timestamp with time zone 带时区的时间戳类型
DSQL_RSET cursor 结果集类型
DSQL_CLASS class class复合类型
DSQL_RECORD record record复合类型
DSQL_ARRAY array 动态array
DSQL_SARRAY array 静态array
DSQL_INTERVAL_YEAR interval year 年时间间隔类型
DSQL_INTERVAL_MONTH interval month 月时间间隔类型
DSQL_INTERVAL_DAY interval day 日时间间隔类型
DSQL_INTERVAL_HOUR interval hour 时时间间隔类型
DSQL_INTERVAL_MINUTE interval minute 分时间间隔类型
DSQL_INTERVAL_SECOND interval second 秒时间间隔类型
DSQL_INTERVAL_YEAR_TO_MONTH interval year to month 年转月 时间间隔类型
DSQL_INTERVAL_DAY_TO_HOUR interval day to hour 日转时 时间间隔类型
DSQL_INTERVAL_DAY_TO_MINUTE interval day to minute 日转分 时间间隔类型
DSQL_INTERVAL_DAY_TO_SECOND interval day to second 日转秒 时间间隔类型
DSQL_INTERVAL_HOUR_TO_MINUTE interval hour to minute 时转分 时间间隔类型
DSQL_INTERVAL_HOUR_TO_SECOND interval hour to second 时转秒 时间间隔类型
DSQL_INTERVAL_MINUTE_TO_SECOND interval minute to second 分转秒 时间间隔类型

DPI中包括以下C类型,对应绑定时使用的数据类型:

宏定义 类型 说明
DSQL_C_NCHAR char 字符类型
DSQL_C_SSHORT signed short 有符号短整型
DSQL_C_USHORT unsigned short 无符号短整型
DSQL_C_SLONG signed int 有符号整型
DSQL_C_ULONG unsigned int 无符号整型
DSQL_C_FLOAT float 单精度浮点型
DSQL_C_DOUBLE double 双精度浮点型
DSQL_C_BIT char 位类型
DSQL_C_STINYINT char 有符号小整型
DSQL_C_UTINYINT unsigned char 无符号小整型
DSQL_C_SBIGINT __int64 有符号长整型,注1:在Windows操作系统下,C中的定义为__int64,在其他操作系统下会有其他的表示方式
DSQL_C_UBIGINT unsigned__int64 无符号长整型
DSQL_C_BINARY unsigned char 二进制类型
DSQL_C_DATE dpi_date_t 日期类型
DSQL_C_TIME dpi_time_t 时间类型
DSQL_C_TIMESTAMP dpi_timestamp_t 日期时间类型
DSQL_C_NUMERIC dpi_numeric_t 数字类型
DSQL_C_INTERVAL_YEAR dpi_interval_t 年时间间隔类型
DSQL_C_INTERVAL_MONTH dpi_interval_t 月时间间隔类型
DSQL_C_INTERVAL_DAY dpi_interval_t 日时间间隔类型
DSQL_C_INTERVAL_HOUR dpi_interval_t 时时间间隔类型
DSQL_C_INTERVAL_MINUTE dpi_interval_t 分时间间隔类型
DSQL_C_INTERVAL_SECOND dpi_interval_t 秒时间间隔类型
DSQL_C_INTERVAL_YEAR_TO_MONTH dpi_interval_t 年转月 时间间隔类型
DSQL_C_INTERVAL_DAY_TO_HOUR dpi_interval_t 日转时 时间间隔类型
DSQL_C_INTERVAL_DAY_TO_MINUTE dpi_interval_t 日转分 时间间隔类型
DSQL_C_INTERVAL_DAY_TO_SECOND dpi_interval_t 日转秒 时间间隔类型
DSQL_C_INTERVAL_HOUR_TO_MINUTE dpi_interval_t 时转分 时间间隔类型
DSQL_C_INTERVAL_HOUR_TO_SECOND dpi_interval_t 时转秒 时间间隔类型
DSQL_C_INTERVAL_MINUTE_TO_SECOND dpi_interval_t 分转秒 时间间隔类型
DSQL_C_DEFAULT 自动映射类型
DSQL_C_LOB_HANDLE dhloblctr 大字段句柄
DSQL_C_RSET dhstmt 结果集类型
DSQL_C_CLASS dhobj 复合对象类型
DSQL_C_RECORD dhobj 复合对象类型
DSQL_C_ARRAY dhobj 复合对象类型
DSQL_C_SARRAY dhobj 复合对象类型
DSQL_C_WCHAR wchar_t 宽字节类型

诊断

函数调用的返回信息放在诊断区域中。每一个环境、连接、及描述符句柄都有一个诊断区域。在诊断区域的头字段返回一般的函数执行信息,它的记录字段记录函数调用的错误信息和警告。用户可以指定获取某一个记录的信息从而更准确地判断函数执行的情况。

2.2 进阶

环境句柄

客户端程序要和数据库服务器进行通信,必须首先进行环境的设置,需要使用到环境句柄。一个环境句柄可以包含多个连接句柄。客户端程序可以通过函数dpi_alloc_env来申请一个环境句柄。环境句柄申请成功后就可以通过函数dpi_alloc_con来申请连接句柄了。环境句柄包含属性如下表所示:

属性 说明 取值
DSQL_ATTR_LOCAL_CODE 本地编码 PG_GBK等
DSQL_ATTR_LANG_ID 错误消息的语言 LANGUAGE_EN或者LANGUAGE_CN

连接句柄

客户端程序要和数据库服务器进行通信,必须和数据库服务器建立连接。所以需要先连接数据库服务器,再使用数据库函数dpi_alloc_con申请连接句柄。要申请连接句柄必须先成功申请环境句柄。一个连接只能属于一个环境句柄。申请连接句柄成功后可以通过函数dpi_login来进行数据的连接登录。

连接句柄包含属性如下表所示:

属性 说明 取值
DSQL_ATTR_ACCESS_MODE 连接的访问模式(可读写) DSQL_MODE_READ_ONLY 或者 DSQL_MODE_READ_WRITE
默认 DSQL_MODE_READ_WRITE
DSQL_ATTR_ASYNC_ENABLE 允许异步执行,未提供 未支持
DSQL_ATTR_AUTO_IPD 自动分配参数描述符(只读)
DSQL_ATTR_AUTOCOMMIT 自动提交(可读写) DSQL_AUTOCOMMIT_ON
或者 DSQL_AUTOCOMMIT_OFF 默认 DSQL_AUTOCOMMIT_ON
DSQL_ATTR_CONNECTION_DEAD 连接存活,未提供
DSQL_ATTR_CONNECTION_TIMEOUT 执行超时时间(可读写) udint4数值
DSQL_ATTR_LOGIN_TIMEOUT 登录超时时间 udint4数值
DSQL_ATTR_PACKET_SIZE 网络包大小,未提供
DSQL_ATTR_TXN_ISOLATION 事务隔离级(可读写) ISO_LEVEL_READ_UNCOMMITTED,ISO_LEVEL_READ_COMMITTED,ISO_LEVEL_SERIALIZABLE
DSQL_ATTR_LOGIN_PORT 登录端口号(可读写) sdint2数值 默认5236
DSQL_ATTR_STR_CASE_SENSITIVE 大小写是否敏感(只读)
DSQL_ATTR_MAX_ROW_SIZE 行最大字节数(只读)
DSQL_ATTR_LOGIN_USER 登陆用户(只读)
DSQL_ATTR_LOGIN_SERVER 登录服务器IP或unixsocket文件路径名。
如果DSQL_ATTR_INET_TYPE是Unix SOCKET,那么DSQL_ATTR_LOGIN_SERVER必须填写unixsocket文件路径名。两者需配套使用。只有Linux环境才支持UNIXSOCKET,Windows不支持(设置了也会被忽略)
DSQL_ATTR_INSTANCE_NAME 实例名称(只读)
DSQL_ATTR_CURRENT_SCHEMA 当前模式(只读)
DSQL_ATTR_SERVER_CODE 服务器的编码(只读)
DSQL_ATTR_LOCAL_CODE 本地编码(可读写) PG_SQL_ASCII,PG_UTF8,PG_GBK,PG_BIG5,PG_ISO_8859_9,PG_EUC_JP,PG_EUC_KR,PG_KOI8R,PG_ISO_8859_1,PG_GB18030,PG_ISO_8859_11,PG_UTF16
DSQL_ATTR_LANG_ID 错误消息的语言(可读写) LANGUAGE_EN或者LANGUAGE_CN
DSQL_ATTR_APP_NAME 应用名称(可读写)
DSQL_ATTR_COMPRESS_MSG 消息压缩(可读写) DSQL_TRUE压缩,DSQL_FALSE不压缩
DSQL_ATTR_RWSEPARATE 读写分离(可读写) DSQL_TRUE开启,DSQL_FALSE关闭
DSQL_ATTR_RWSEPARATE_PERCENT 读写分离比例(可读写) 0-100 默认25
DSQL_ATTR_CURRENT_CATALOG (只读)
DSQL_ATTR_TRX_STATE 事务状态(只读) DSQL_TRX_ACTIVE和DSQL_TRX_COMPLETE
DSQL_ATTR_USE_STMT_POOL 语句句柄缓存池(可读写) DSQL_TRUE 开启,DSQL_FALSE 关闭
DSQL_ATTR_SSL_PATH SSL证书所载的路径路径(可读写) 字符串(最长256)
DSQL_ATTR_SSL_PWD SSL加密密码(可读写) 字符串(最长512)
DSQL_ATTR_MPP_LOGIN mpp登陆方式(可读写) DSQL_MPP_LOGIN_GLOBAL 全局登陆 DSQL_MPP_LOGIN_LOCAL 本地登陆
DSQL_ATTR_UKEY_NAME UKEY登录验证的UKEY名
DSQL_ATTR_UKEY_PIN UKEY登录验证时的UKEY密钥 最长256
DSQL_ATTR_UDP_FLAG UDP通讯的收发模式 1表示单发单收,2表示多发多收,默认为2
DSQL_ATTR_LOGIN_CERTIFICATE 指定登录加密用户名密码公钥所在的路径。该属性和dm_svc.conf中配置项LOGIN_CERTIFICATE功能一样。两者不一致时,DSQL_ATTR_LOGIN_CERTIFICATE设置优先 字符串(最长256)
DSQL_ATTR_INET_TYPE 指定网络连接类型 取值为:DSQL_INET_TCP、DSQL_INET_UDP 、DSQL_INET_IPC 、DSQL_INET_RDMA 、DSQL_INET_UNIXSOCKET。缺省为 DSQL_INET_TCP
DSQL_ATTR_TCNAME_LOWER 是否将通过描述获取的表名和列名转换为小写 DSQL_TRUE
或者
DSQL_FALSE
默认
DSQL_FALSE

语句句柄

DPI用语句句柄来存取名称、参数、错误以及其他关于语句处理流程的信息。在一个连接句柄下可以有多个语句句柄,一个特定的SQL语句总是和一个句柄连接相联系的。在DPI中,通过语句句柄可以了解到语句的状态、当前语句的诊断信息、语句的参数以及结果集绑定的应用程序变量等信息、每一个语句的当前属性值。客户程序调用dpi_alloc_stmt函数申请一个语句句柄,用dpi_free_stmt函数释放一个语句句柄。

语句句柄包含属性如下表所示:

属性 说明 取值
DSQL_ATTR_ROW_BIND_TYPE 行绑定类型(可读写)
DSQL_ATTR_ROW_BIND_OFFSET_PTR 行绑定偏移(可读写)
DSQL_ATTR_ROW_OPERATION_PTR 绑定行数据处理指示(可读写)
DSQL_ATTR_ROW_STATUS_PTR 获取行数据状态指示(可读写)
DSQL_ATTR_ROWS_FETCHED_PTR 已获取行数指示(可读写)
DSQL_ATTR_ROW_ARRAY_SIZE 行集大小(可读写)
DSQL_ATTR_ROWSET_SIZE 行集大小(可读写)
DSQL_ATTR_USE_BOOKMARKS 是否使用书签(可读写)
DSQL_ATTR_FETCH_BOOKMARK_PTR 书签值(可读写)
DSQL_ATTR_PARAM_BIND_OFFSET_PTR 参数绑定值的偏移位置(可读写)
DSQL_ATTR_PARAM_BIND_TYPE 参数绑定类型(可读写)
DSQL_ATTR_PARAM_OPERATION_PTR 参数数据处理指示(可读写)
DSQL_ATTR_PARAM_STATUS_PTR 参数使用状态(可读写)
DSQL_ATTR_PARAMS_PROCESSED_PTR 参数集中参数处理的个数(可读写)
DSQL_ATTR_PARAMSET_SIZE 参数集大小(可读写)
DSQL_ATTR_ROW_NUMBER 当前行位置(只读)
DSQL_ATTR_IMP_ROW_DESC 服务器端的行描述(只读)
DSQL_ATTR_IMP_PARAM_DESC 服务器端参数描述(只读)
DSQL_ATTR_APP_PARAM_DESC 应用程序参数描述(可读写)
DSQL_ATTR_APP_ROW_DESC 应用程序行描述(可读写)
DSQL_ATTR_CURSOR_TYPE 游标类型(可读写) DSQL_CURSOR_FORWARD_ONLY DSQL_CURSOR_STATIC DSQL_CURSOR_KEYSET_DRIVEN DSQL_CURSOR_DYNAMIC
DSQL_ATTR_CONCURRENCY 游标的并发方式(可读写) DSQL_CONCUR_READ_ONLY
DSQL_CONCUR_LOCK DSQL_CONCUR_ROWVER
DSQL_CONCUR_VALUES
DSQL_ATTR_CURSOR_SCROLLABLE 游标是否可滚动(可读写) DSQL_NONSCROLLABLE DSQL_SCROLLABLE
DSQL_ATTR_CURSOR_SENSITIVITY 结果集修改对其他游标是否可见(可读写) DSQL_UNSPECIFIED
DSQL_INSENSITIVE DSQL_SENSITIVE
DSQL_ATTR_MAX_LENGTH 字符类型或者二进制类型列的最大返回长度(可读写)
DSQL_ATTR_MAX_ROWS 结果集返回的最大行数(可读写)
DSQL_ATTR_NOSCAN 是否检查语句中的转义符(可读写),未提供
DSQL_ATTR_QUERY_TIMEOUT 执行超时时间(可读写),未提供
DSQL_ATTR_RETRIEVE_DATA 游标滚动后是否检索数据(可读写),未提供
DSQL_ATTR_ENABLE_AUTO_IPD 自动分配参数描述符(可读写) DSQL_TRUE 或者DSQL_FALSE
DSQL_ATTR_ASYNC_ENABLE 异步执行(可读写),未提供
DSQL_ATTR_KEYSET_SIZE 键集驱动游标结果集中行的大小(可读写),未提供
DSQL_ATTR_SIMULATE_CURSOR 指定游标更新和删除是否只影响单行(可读写),未提供
DSQL_ATTR_METADATA_ID 是否允许模糊查询(可读写) DSQL_TRUE DSQL_FALSE
DSQL_ATTR_SQL_CHARSET 字符集编码(可读写) PG_SQL_ASCII,PG_UTF8,
PG_GBK,PG_BIG5,
PG_ISO_8859_9,PG_EUC_JP,
PG_EUC_KR,PG_KOI8R,
PG_ISO_8859_1,PG_GB18030,
PG_ISO_8859_11,PG_UTF16
DSQL_ATTR_IGN_BP_ERR 批量参数错误数据处理策略(可读写) DSQL_TRUE DSQL_FALSE

描述符句柄

一个描述符句柄是指包含列或者动态参数信息的一个数据结构。对于许多应用程序,直接访问与操作描述符会使得操作更加简单。在DPI中描述符分为以下几种类型:

  1. 应用程序参数描述符(APD):包含被应用程序设置的输入动态参数或者随执行SQL语句中的CALL产生的输出动态参数;
  2. 驱动执行参数描述符(IPD):对于输入参数,在完成应用程序指定的数据转换之后,它包含了与APD相同的参数。对于输出参数,在进行了一些应用程序指定的数据转换之前,它包含了返回的参数;
  3. 驱动执行行描述符(IRD):包含数据库中的一行;
  4. 应用程序行描述符(ARD):包含数据的行。

描述符字段包括头字段与记录域字段,它们全面地描述列与参数。

一个描述符包括了以下的头字段:

属性 说明
DSQL_DESC_ALLOC_TYPE 描述符的分配类型(只读)
DSQL_DESC_ARRAY_SIZE 描述符的记录数组大小(APD,ARD可读写)
DSQL_DESC_ARRAY_STATUS_PTR 数据状态指示(可读写)
DSQL_DESC_BIND_OFFSET_PTR 绑定数据偏移(APD,ARD可读写)
DSQL_DESC_BIND_TYPE 绑定类型(APD,ARD可读写)
DSQL_DESC_COUNT 描述符包含记录个数(APD,ARD,IPD可读写,IRD只读)
DSQL_DESC_ROWS_PROCESSED_PTR 处理数据的个数(IRD,IPD可读写)

一个描述符包括了以下的记录域字段:

属性 说明
DSQL_DESC_AUTO_UNIQUE_VALUE 结果集列是否是自动增长的(IRD只读)
DSQL_DESC_BASE_COLUMN_NAME 结果集列的基列列名(IRD只读)
DSQL_DESC_BASE_TABLE_NAME 结果集列的基表名(IRD只读)
DSQL_DESC_CASE_SENSITIVE 对象是否大小写敏感(IRD,IPD只读)
DSQL_DESC_CATALOG_NAME 列对应的库名(IRD只读)
DSQL_DESC_CONCISE_TYPE 对象对应的精简类型(APD,ARD,IPD可读写,IRD只读)
DSQL_DESC_DATA_PTR 绑定数据的地址(APD,ARD可读写)
DSQL_DESC_DATETIME_INTERVAL_CODE 时间日期类型,时间日期间隔类型的子类型(APD,ARD,IPD可读写,IRD只读)
DSQL_DESC_DATETIME_INTERVAL_PRECISION 时间间隔类型的引导精度(APD,ARD,IPD可读写,IRD只读)
DSQL_DESC_DISPLAY_SIZE 列的显示长度(IRD只读)
DSQL_DESC_FIXED_PREC_SCALE 指示是否是固定精度刻度的数字类型(IPD,IRD只读)
DSQL_DESC_INDICATOR_PTR 指示符地址(APD,ARD可读写)
DSQL_DESC_LABEL 列的标签(IRD只读)
DSQL_DESC_LENGTH 字符类型的最大或实际字符长度或者二进制类型的最大或实际字节长度
(APD,ARD,IPD可读写,IRD只读)
DSQL_DESC_LITERAL_PREFIX 列的前缀字符(IRD只读)
DSQL_DESC_LITERAL_SUFFIX 列的后缀字符(IRD只读)
DSQL_DESC_LOCAL_TYPE_NAME 本地的类型名(IPD,IRD只读)
DSQL_DESC_NAME 列的别名(IPD可读写,IRD只读)
DSQL_DESC_NULLABLE 记录域是否可以为空(IPD,IRD只读)
DSQL_DESC_NUM_PREC_RADIX 记录域数字类型精度的表示基数(APD,ARD,IPD可读写,IRD只读)
DSQL_DESC_OCTET_LENGTH 记录域的最大字节长度(APD,ARD,IPD可读写,IRD只读)
DSQL_DESC_OCTET_LENGTH_PTR 指示绑定字符类型或二进制类型的实际字节长度(APD,ARD可读写)
DSQL_DESC_PARAMETER_TYPE 参数类型(IPD可读写)
DSQL_DESC_PRECISION 精确数字类型的位数或者近似数字类型的尾数尾数,或者时间类型,
时间戳类型,秒间隔类型秒精度(APD,ARD,IPD可读写,IRD只读)
DSQL_DESC_ROWVER 指示列是否记录行的版本信息(IPD,IRD只读)
DSQL_DESC_SCALE DEC或者NUMERIC类型的刻度
DSQL_DESC_SCHEMA_NAME 列所属基表所在的模式名(IRD只读)
DSQL_DESC_SEARCHABLE 列的条件查询方式(IRD只读)
DSQL_DESC_TABLE_NAME 列所在的基表表名(IRD只读)
DSQL_DESC_TYPE C类型或者DSQL类型,时间或者间隔类型则表示的为详细的类型DSQL_DT或DSQL_INTERVAL(APD,ARD,IPD可读写,IRD只读)
DSQL_DESC_TYPE_NAME 数据源的数据类型(IPD,IRD只读)
DSQL_DESC_UNNAMED 记录域是否是命名的(IPD可读写,IRD只读)
DSQL_DESC_UNSIGNED 指示记录域是否为无符号数字类型(IPD,IRD只读)
DSQL_DESC_UPDATABLE 列是否为可更新(IRD只读)
DSQL_DESC_BIND_PARAMETER_TYPE 参数类型(IPD可读写)
DSQL_DESC_DATETIME_FORMAT 时间类型格式(APD, ARD 可读写)
DSQL_DESC_CHARSET 字符集编码(APD, ARD 可读写)

lob句柄

lob句柄为大字段操纵句柄,可以对大字段进行更新和读取处理。通过lob句柄可以获取大字段对象的长度、读取大字段实际数据、更新大字段数据、截取大字段数据。lob句柄从属于某一个语句句柄,可以通过dpi_alloc_handle或者dpi_alloc_lob_locator函数进行分配,再通过绑定到某个大字段对象进行操作。在释放语句句柄时必须先释放语句句柄上所有的lob句柄,否则函数会返回执行失败的错误。

诊断信息

诊断信息反映函数执行情况,某个函数若返回DSQL_SUCCESS_WITH_INFO或者DSQL_ERROR,就能通过调用dpi_get_diag_rec或者dpi_get_diag_field函数获取具体的诊断信息,从而有效的定位错误原因。

诊断信息分为诊断头信息以及诊断域信息。

诊断头信息包含如下字段:

属性 说明
DSQL_DIAG_NUMBER 诊断信息个数
DSQL_DIAG_DYNAMIC_FUNCTION_CODE 语句类型
DSQL_DIAG_ROW_COUNT 语句执行影响的行数
DSQL_DIAG_PRINT_INFO 存储过程或语句块的打印信息
DSQL_DIAG_EXPLAIN explain语句的结果

诊断域信息包含如下字段。

属性 说明
DSQL_DIAG_COLUMN_NUMBER 出错的列号
DSQL_DIAG_ROW_NUMBER 出错的行号
DSQL_DIAG_MESSAGE_TEXT 错误信息
DSQL_DIAG_ERROR_CODE 错误码

2.3 函数原型

1. dpi_alloc_handle

函数

DPIRETURN
dpi_alloc_handle(
		sdint2 		hndl_type,
		dhandle 	hndl_in,
		dhandle 	*hdnl_out
);

功能 用于分配环境、连接、语句、描述符、lob、复合类型对象句柄。

参数

1) hndl_type

输入参数,需要分配句柄的类型,必须为下列值之一:

  • DSQL_HANDLE_ENV
  • DSQL_HANDLE_DBC
  • DSQL_HANDLE_STMT
  • DSQL_HANDLE_DESC
  • DSQL_HANDLE_LOB_LOCATOR
  • DSQL_HANDLE_OBJECT

2) hndl_in

输入参数,通过此句柄分配新的句柄,新句柄运行环境从属此句柄。

如果hndl_type为DSQL_HANDLE_ENV,则这个值为NULL;

如果hndl_type为DSQL_HANDLE_DBC,则这个值必须是一个环境句柄;

如果hndl_type为DSQL_HANDLE_STMT、DSQL_HANDLE_DESC或者DSQL_HANDLE_OBJECT,则这个值必须是一个连接句柄;

如果hndl_type为DSQL_HANDLE_LOB_LOCATOR,则这个值必须是一个语句句柄。

3) hndl_out

输出参数,一个存放新分配句柄数据结构的缓冲区地址。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明

如果函数执行失败,则hndl_out返回NULL。

2. dpi_free_handle

函数

DPIRETURN
dpi_free_handle(
		sdint2 		hndl_type,
		dhandle 	hndl
);

功能

释放资源,用于释放句柄资源。

参数

hdle_type

输入参数,需要被释放句柄的类型。必须为下列值之一:

  • DSQL_HANDLE_ENV
  • DSQL_HANDLE_DBC
  • DSQL_HANDLE_STMT
  • DSQL_HANDLE_DESC
  • DSQL_HANDLE_LOB_LOCATOR
  • DSQL_HANDLE_OBJECT

hndl

输入参数,需要被释放的句柄。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明

若函数执行失败,则需要被释放的句柄依然有效。

3. dpi_alloc_env

函数

DPIRETURN
dpi_alloc_env(
		dhenv  *dpi_henv
);

功能

分配环境句柄。

参数

dpi_henv

输出参数,一个存放新分配环境句柄数据结构的缓冲区地址。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

说明

该函数作用与dpi_alloc_handle指定分配DSQL_HANDLE_ENV一致。

4. dpi_alloc_con

函数

DPIRETURN
dpi_alloc_con(
		dhenv	 dpi_henv,
		dhcon 	 *dpi_hcon
);

功能

分配连接句柄。

参数

  1. dpi_henv

输入参数,通过此环境句柄分配新的连接句柄,新句柄运行环境从属此句柄。

  1. dpi_hcon

输出参数,一个存放新分配连接句柄数据结构的缓冲区地址。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明

该函数作用与dpi_alloc_handle指定分配DSQL_HANDLE_DBC一致。

5. dpi_alloc_stmt

函数

DPIRETURN
dpi_alloc_stmt(
		dhcon 		dpi_hcon,
		dhstmt 		*dpi_hstm
);

功能

分配语句句柄。

参数

  1. dpi_hcon

输入参数,通过此连接句柄分配新的语句句柄,新句柄运行环境从属此句柄。

  1. dpi_hstmt

输出参数,一个存放新分配语句句柄数据结构的缓冲区地址。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明

该函数作用与dpi_alloc_handle指定分配DSQL_HANDLE_STMT一致。

6. dpi_alloc_desc

函数

DPIRETURN
dpi_alloc_desc(
		dhcon 	dpi_hcon,
		dhdesc 	*dpi_hdes
);

功能

分配描述符句柄。

参数

  1. dpi_hcon

输入参数,通过此连接句柄分配新的描述符句柄,新句柄运行环境从属此句柄。

2)dpi_hdesc

输出参数,一个存放新分配描述符句柄数据结构的缓冲区地址。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明

该函数作用与dpi_alloc_handle指定分配DSQL_HANDLE_DESC一致。

7. dpi_alloc_lob_locator

函数

DPIRETURN
dpi_alloc_lob_locator(
		dhstmt 		dpi_hstmt,
		dhloblctr 	*dpi_loblctr
);

功能

分配lob句柄。

参数

  1. dpi_hstmt

输入参数,通过此语句句柄分配新的lob句柄,新句柄运行环境从属此句柄。

  1. dpi_loblctr

输出参数,一个存放新分配lob句柄数据结构的缓冲区地址。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明

该函数作用与dpi_alloc_handle指定分配DSQL_HANDLE_LOB_LOCATOR一致。

8. dpi_free_env

函数

DPIRETURN
dpi_free_env(
		dhenv 		dpi_henv
);

功能

释放环境句柄。

参数

dpi_henv

输入参数,需要被释放的环境句柄。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明

该函数作用与dpi_free_handle指定DSQL_HANDLE_ENV一致。

9. dpi_free_con

函数:

DPIRETURN
dpi_free_con(
		dhcon 	dpi_hcon
);

功能

释放连接句柄。

参数

dpi_hcon

输入参数,需要被释放的连接句柄。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVLAID_HANDLE

说明

该函数作用与dpi_free_handle指定DSQL_HANDLE_DBC一致。在释放连接时必须保证连接已经与服务器断开,否则函数失败。

10. dpi_free_stmt

函数

DPIRETURN
dpi_free_stmt(
		dhstmt 		dpi_hstmt
);

功能

释放语句句柄。

参数

dpi_hstmt

输入参数,需要被释放的语句句柄。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明

该函数作用与dpi_free_handle指定DSQL_HANDLE_STMT一致。在释放语句句柄时必须保证句柄上分配的lob句柄都已经释放,否则函数执行失败。

11. dpi_free_desc

函数

DPIRETURN
dpi_free_desc(
		dhdesc 		dpi_hdesc
);

功能

释放描述符句柄。

参数

dpi_hdesc

输入参数,需要被释放的描述符句柄。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明

该函数作用与dpi_free_handle指定DSQL_HANDLE_DESC一致。所要释放的描述符句柄必须为手动分配的,否则函数执行失败。

12. dpi_free_lob_locator

函数

DPIRETURN
dpi_free_lob_locator(
		dhloblctr 	dpi_loblctr
);

功能

释放lob句柄。

参数

dpi_loblctr

输入参数,需要被释放的lob句柄。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明

该函数作用与dpi_free_handle指定DSQL_HANDLE_LOB_LOCATOR一致。

13. dpi_set_env_attr

函数

DPIRETURN
dpi_set_env_attr(
		dhenv 		dpi_henv,
		sdint4 		attr_id,
		dpointer 	val,
		sdint4 		val_len
);

功能

设置环境句柄的属性。

参数

1) dpi_henv

输入参数,需要被设置属性的环境句柄。

2) attr_id

输入参数,设置的属性,参见说明。

3) val

输入参数,所需设置属性的值。根据属性的不同,值可能为32位的整形数或者以0结尾的字符串。

4) val_len

输入参数,如果设置的val指向字符串或者二进制缓冲区,此参数表示val的字节长度。如果val为整形数,则此参数忽略。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明

属性 字段类型
DSQL_ATTR_LOCAL_CODE sdint4
DSQL_ATTR_LANG_ID sdint4

14. dpi_set_con_attr

函数

DPIRETURN
dpi_set_con_attr(
		dhcon 		dpi_hcon,
		sdint4 		attr_id,
		dpointer 	val,
		sdint4 		val_len
);

功能

设置连接句柄属性。

参数

1) dpi_hcon

输入参数,需要被设置属性的连接句柄。

2) attr_id

输入参数,设置的属性,参见说明。

3) val

输入参数,所需设置属性的值。根据属性的不同,值可能为32位的整形数或者以0结尾的字符串。

4) val_len

输入参数,如果设置的val指向字符串或者二进制缓冲区,此参数表示val的字节长度。如果val为整形数,则此参数忽略。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明

属性 字段类型
DSQL_ATTR_ACCESS_MODE udint4
DSQL_ATTR_ASYNC_ENABLE udint4
DSQL_ATTR_AUTO_IPD udint4
DSQL_ATTR_AUTOCOMMIT udint4
DSQL_ATTR_CONNECTION_DEAD udint4
DSQL_ATTR_CONNECTION_TIMEOUT udint4
DSQL_ATTR_LOGIN_TIMEOUT udint4
DSQL_ATTR_PACKET_SIZE udint4
DSQL_ATTR_TXN_ISOLATION sdint4
DSQL_ATTR_ATTR_ENCRYPT udint4
DSQL_ATTR_LOGIN_PORT sdint2
DSQL_ATTR_STR_CASE_SENSITIVE udint4
DSQL_ATTR_MAX_ROW_SIZE udint4
DSQL_ATTR_LOGIN_USER sdbyte*
DSQL_ATTR_LOGIN_SERVER sdbyte*
DSQL_ATTR_INSTANCE_NAME sdbyte*
DSQL_ATTR_CURRENT_SCHEMA sdbyte*
DSQL_ATTR_SERVER_CODE sdint4
DSQL_ATTR_LOCAL_CODE sdint4
DSQL_ATTR_LANG_ID sdint4
DSQL_ATTR_APP_NAME sdbyte*
DSQL_ATTR_COMPRESS_MSG sdint4
DSQL_ATTR_CURRENT_CATALOG sdbyte*
DSQL_ATTR_TRX_STATE sdint4
DSQL_ATTR_USE_STMT_POOL dint4
DSQL_ATTR_SSL_PATH sdbyte*
DSQL_ATTR_SSL_PWD sdbyte*
DSQL_ATTR_MPP_LOGIN sdint4
DSQL_ATTR_UKEY_NAME sdbyte*
DSQL_ATTR_UKEY_PIN sdbyte*
DSQL_ATTR_UDP_FLAG sdint4
DSQL_ATTR_INET_TYPE sdbyte*

15. dpi_set_stmt_attr

函数

DPIRETURN
dpi_set_stmt_attr(
		dhstmt 			dpi_hstmt,
		sdint4 			attr_id,
		dpointer		 val,
		sdint4 			val_len
);

功能

设置语句句柄属性。

参数

1) dpi_hstmt

输入参数,需要被设置属性的语句句柄。

  1. attr_id

输入参数,设置的属性,参见说明。

  1. val

输入参数,所需设置属性的值。根据属性的不同,值可能为下列之一:

  • 一个描述符句柄

  • 一个udint4类型的值

  • 一个ulength类型的值

  • 一个下列情况之一的指针:

    • 一个以0结尾的字符串
    • 一个二进制缓冲区
    • 一个slength、ulength或者udint2类型的值或者数组
    • 一个驱动定义的值
  1. val_len

输入参数,如果设置的val指向字符串或者二进制缓冲区,此参数表示val的字节长度。如果val为整形数,则此参数忽略。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明

属性 字段 类型 属性 字段类型
DSQL_ATTR_ROW_BIND_TYPE ulength DSQL_ATTR_IMP_ROW_DESC void*
DSQL_ATTR_ROW_BIND_OFFSET_PTR ulength* DSQL_ATTR_IMP_PARAM_DESC void*
DSQL_ATTR_ROW_OPERATION_PTR udint2* DSQL_ATTR_APP_PARAM_DESC void*
DSQL_ATTR_ROW_STATUS_PTR udint2* DSQL_ATTR_APP_ROW_DESC void*
DSQL_ATTR_ROWS_FETCHED_PTR ulength* DSQL_ATTR_CURSOR_TYPE ulength
DSQL_ATTR_ROW_ARRAY_SIZE ulength DSQL_ATTR_CONCURRENCY ulength
DSQL_ATTR_ROWSET_SIZE ulength DSQL_ATTR_CURSOR_SCROLLABLE ulength
DSQL_ATTR_USE_BOOKMARKS ulength DSQL_ATTR_CURSOR_SENSITIVITY ulength
DSQL_ATTR_FETCH_BOOKMARK_PTR slength* DSQL_ATTR_MAX_LENGTH ulength
DSQL_ATTR_PARAM_BIND_OFFSET_PTR ulength* DSQL_ATTR_MAX_ROWS ulength
DSQL_ATTR_PARAM_BIND_TYPE ulength DSQL_ATTR_NOSCAN ulength
DSQL_ATTR_PARAM_OPERATION_PTR udint2* DSQL_ATTR_QUERY_TIMEOUT ulength
DSQL_ATTR_PARAM_STATUS_PTR udint2* DSQL_ATTR_RETRIEVE_DATA ulength
DSQL_ATTR_PARAMS_PROCESSED_PTR ulength* DSQL_ATTR_ENABLE_AUTO_IPD ulength
DSQL_ATTR_PARAMSET_SIZE ulength DSQL_ATTR_ASYNC_ENABLE ulength
DSQL_ATTR_ROW_NUMBER ulength DSQL_ATTR_KEYSET_SIZE ulength

16. dpi_get_env_attr

函数

DPIRETURN
dpi_get_env_attr(
		dhenv 		dpi_henv,
		sdint4 		attr_id,
		dpointer 	val,
		sdint4 		buf_len,
		sdint4 		*val_len
);

功能

获取环境句柄属性。

参数

  1. dpi_henv

输入参数,获取属性的环境句柄。

  1. attr_id

输入参数,需要获取的属性。

  1. val

输出参数,指向返回指定属性当前值的缓冲区的指针。

  1. buf_len

输入参数,如果val返回的是字符串,则此参数为val缓冲区的长度。如果val返回的不是字符串,则此参数忽略。

  1. val_len

输出参数,指向返回val中可提供字符串的总长度的缓冲区的指针。如果val为NULL,则不返回长度,如果属性值为字符串,总长度大于等于buf_len,则val值被截断且以0结尾。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明

属性值参见函数dpi_set_env_attr。

17. dpi_get_con_attr

函数

DPIRETURN
dpi_get_con_attr(
		dhcon 		dpi_hcon,
		sdint4 		attr_id,
		dpointer 	val,
		sdint4 		buf_len,
		sdint4 		*val_len
);

功能

获取连接句柄属性。

参数

1)dpi_hcon

输入参数,获取属性的连接句柄。

  1. attr_id

输入参数,需要获取的属性。

3)val

输出参数,指向返回指定属性当前值的缓冲区的指针。

  1. buf_len

输入参数,如果val返回的是字符串,则此参数为val缓冲区的长度。如果val返回的不是字符串,则此参数忽略。

  1. val_len

输出参数,指向返回val中可提供字符串的总长度的缓冲区的指针。如果val为NULL,则不返回长度,如果属性值为字符串,总长度大于等于buf_len,则val值被截断且以0结尾。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明

属性值参见函数dpi_set_con_attr。

18. dpi_get_stmt_attr

函数

DPIRETURN
dpi_get_stmt_attr(
		dhstmt 		dpi_hstmt,
		sdint4 		attr_id,
		dpointer 	val,
		sdint4 		buf_len,
		sdint4 		*val_len
);

功能

获取语句句柄属性。

参数

  1. dpi_hstmt

输入参数,获取属性的语句句柄。

  1. attr_id

输入参数,需要获取的属性。

  1. val

输出参数,指向返回指定属性当前值的缓冲区的指针。

  1. buf_len

输入参数,如果val返回的是字符串,则此参数为val缓冲区的长度。如果val返回的不是字符串,则此参数忽略。

  1. val_len

输出参数,指向返回val中可提供字符串的总长度的缓冲区的指针。如果val为NULL,则不返回长度,如果属性值为字符串,总长度大于等于buf_len,则val值被截断且以0结尾。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明

属性值参见函数dpi_set_stmt_attr

19. dpi_get_diag_rec

函数

DPIRETURN
dpi_get_diag_rec(
		sdint2 		hndl_type,
		dhandle 		hndl,
		sdint2 		rec_num,
		sdint4 		*err_code,
		sdbyte 		*err_msg,
		sdint2 		buf_sz,
		sdint2 		*msg_len
);

功能

获取复合字段的诊断信息。

参数

  1. hndl_type 输入参数,需要获取诊断信息的句柄类型。必须为下列值之一:
  • DSQL_HANDLE_ENV
  • DSQL_HANDLE_DBC
  • DSQL_HANDLE_STMT
  • DSQL_HANDLE_DESC
  • DSQL_HANDLE_LOB_LOCATOR
  • DSQL_HANDLE_OBJECT
  • DSQL_HANDLE_OBJECTDESC
  1. hndl

输入参数,需要取得诊断信息且由hndl_type所标示的句柄。

  1. rec_num

输入参数,诊断信息的索引号。索引起始为1。

  1. err_code

输出参数,指向用于记录错误码的缓冲区的指针。此信息包含在DSQL_DIAG_ERROR_CODE诊断域中。

  1. err_msg

输出参数,指向用于记录诊断消息缓冲区的指针。此信息包含在DSQL_DIAG_MESSAGE_TEXT诊断域中。

  1. buf_sz

输入参数,err_msg缓冲区的长度。

  1. msg_len

输出参数,指向用于返回诊断消息总长度的缓冲区的指针。如果诊断消息长度大于等于buf_sz,则诊断消息被截断且以0结尾。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

DSQL_NO_DATA_FOUND

说明

函数返回值含义:

  • DSQL_SUCCESS:函数成功返回诊断信息。

  • DSQL_SUCCESS_WITH_INFO:err_msg缓冲区长度不足,诊断信息被截断。

  • DSQL_ERROR:发生了下列情况之一:

    • rec_num小于等于0。
    • buf_sz小于0。
  • DSQL_INVALID_HANDLE:由hndl_type所标示的hndl为一个无效的句柄。

  • DSQL_NO_DATA:rec_num大于句柄所含有的诊断信息总数。

20. dpi_get_diag_field

函数

DPIRETURN
dpi_get_diag_field(
		sdint2		 hndl_type,
		dhandle 	 hndl,
		sdint2 		rec_num,
		sdint2 		diag_id,
		dpointer 	diag_info,
		slength		 buf_len,
		slength 	*info_len
);

功能

获取诊断信息的某个指定域的值。

参数

  1. hndl_type

输入参数,需要获取诊断信息的句柄类型。必须为下列值之一:

  • DSQL_HANDLE_ENV
  • DSQL_HANDLE_DBC
  • DSQL_HANDLE_STMT
  • DSQL_HANDLE_DESC
  • DSQL_HANDLE_LOB_LOCATOR
  • DSQL_HANDLE_OBJECT
  • DSQL_HANDLE_OBJECTDESC
  1. hndl

输入参数,需要取得诊断信息且由hndl_type所标示的句柄。

  1. rec_num

输入参数,诊断信息的索引号。索引起始为1。如果diag_id为诊断头信息,则此参数被忽略。

  1. diag_id

输入参数,指定需要获取值的诊断域。更多信息参见说明。

  1. diag_info

输出参数,指向返回诊断域信息的缓冲区的指针。数据类型依赖于diag_id。

  1. buf_len

输入参数,如果diag_info返回的是字符串,则此参数为diag_info缓冲区的长度。如果diag_info返回的不是字符串,则此参数忽略。

  1. info_len

输出参数,指向返回diag_info中可提供字符串的总长度的缓冲区的指针。如果diag_info为NULL,则不返回长度,如果diag_info值为字符串,总长度大于等于buf_len,则diag_info值被截断且以0结尾。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

DSQL_NO_DATA

说明

函数返回值含义:

  • DSQL_SUCCESS:函数成功返回诊断信息。
  • DSQL_SUCCESS_WITH_INFO:diag_info缓冲区长度不足,诊断信息被截断。
  • DSQL_ERROR:发生了下列情况之一:
  • rec_num小于等于0。对于诊断头,忽略rec_num。
  • 所要求的诊断域的值为字符串,而buf_sz小于0。
  • diag_id不是一个有效的诊断域。
  • diag_id为DSQL_DIAG_ROW_COUNT,DSQL_DIAG_DYNAMIC_FUNCTION_CODE,DSQL_DIAG_PRINT_INFO或者DSQL_DIAG_EXPLAIN,但hndl不是一个语句句柄。
  • DSQL_INVALID_HANDLE:由hndl_type所标示的hndl为一个无效的句柄。
  • DSQL_NO_DATA:rec_num大于句柄所含有的诊断信息总数。

21. dpi_login

函数

DPIRETURN
dpi_login(
		dhcon 		dpi_hcon,
		sdbyte		* svr,
		sdbyte		* user,
		sdbyte		* pwd
);

功能

与指定的数据库服务器建立连接。

参数

  1. dpi_hcon

输入参数,连接句柄。

  1. svr

输入参数,数据库服务器所对应的地址。

  1. user

输入参数,登录数据库服务器的登录名。

  1. pwd

输入参数,登录数据库服务器的口令。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明

若需要登录的服务器的端口不是默认端口,则需要在调用之前设置连接属性DSQL_ATTR_LOGIN_PORT,或者svr设置为ip:port形式,例如:192.168.0.143:5289。登录函数支持以服务名登录,需要配置dm_svc.conf文件。

22. dpi_logout

函数

DPIRETURN
dpi_logout(
		dhcon 	dpi_hcon
);

功能

断开与数据库服务器的连接。

参数

dpi_hcon

输入参数,连接句柄。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明

23. dpi_commit

函数

DPIRETURN
dpi_commit(
	dhcon 		dpi_hcon
);

功能

提交连接上的所有活动事务。

参数:

dpi_hcon

输入参数,连接句柄。

返回值:

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明:

手动提交事务,必须将连接的自动提交属性设置为非自动提交,否则无效果。默认为自动提交。

24. dpi_rollback

函数

DPIRETURN
dpi_rollback(
		dhcon 		dpi_hcon
);

功能

回滚连接上的所有活动事务。

参数:

dpi_hcon

输入参数,连接句柄。

返回值:

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明:

手动回滚事务,必须将连接的自动提交属性设置为非自动提交,否则无效果。默认为自动提交。

25. dpi_copy_desc

函数

DPIRETURN
dpi_copy_desc(
		dhdesc 		src_desc,
		dhdesc 		target_desc
);

功能

复制一个描述符句柄的信息到另外一个描述符句柄上。

参数说明:

1)src_desc

输入参数,源描述符句柄。

2)target_desc

输入参数,目的描述符句柄。目的描述符句柄可以为APD、ARD或者IPD,但不能为IRD。

返回值:

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明:

描述符句柄拷贝。只能拷贝到APD、ARD或者IPD,不能拷贝到IRD。

26. dpi_set_desc_rec

函数

DPIRETURN
dpi_set_desc_rec(
		dhdesc 		dpi_desc,
		sdint2 		rec_num,
		sdint2		 type,
		sdint2 		sub_type,
		slength 	length,
		sdint2 		prec,
		sdint2		 scale,
		dpointer	 data_ptr,
		slength		* str_len,
		slength		* ind_ptr
);

功能

设置复合的描述符域的信息。这些信息可以影响所绑定列或者参数的数据类型和绑定的缓冲区信息。

参数:

1)dpi_desc

输入参数,描述符句柄。不能为IRD句柄。

2)rec_num

输入参数,包含所设置域的描述符记录的索引号。此参数从0起始。当为0时,表示所设置的为书签列。此参数值必须大于等于0。如果此参数的值大于DSQL_DESC_COUNT的值,则DSQL_DESC_COUNT的值改变为rec_num。

3)type

输入参数,设置描述符记录DSQL_DESC_TYPE域的值。

4)sub_type

输入参数,对于类型为DSQL_DT或者DSQL_INTERVAL的记录,此参数值设置DSQL_DESC_DATETIME_INTERVAL_CODE域的值。

5)length

输入参数,此参数值设置描述符记录的DSQL_DESC_OCTET_LENGTH域的值。

6)prec

输入参数,此参数值设置描述符记录的DSQL_DESC_PRECISION域的值。

7) scale

输入参数,此参数值设置描述符记录的DSQL_DESC_SCALE域的值。

8) data_ptr

输入或输出参数,此参数值设置描述符记录的DSQL_DESC_DATA_PTR域的值。data_ptr可以设置为NULL。如果data_ptr设置为NULL,dpi_desc又与ARD关联,则这意味着清空了绑定信息。

9) str_len

输入或输出参数,此参数值设置描述符记录的DSQL_DESC_OCTET_LENGTH_PTR域的值。str_len可以设置为NULL。

10)ind_ptr

输入或输出参数,此参数值设置描述符记录的DSQL_DESC_INDICATOR_PTR域的值。ind_ptr可以设置为NULL。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明:

具体参见dpi_set_desc_field函数说明。

27. dpi_set_desc_field

函数

DPIRETURN
dpi_set_desc_field(
		dhdesc 		dpi_desc,
		sdint2 		rec_num,
		sdint2 		field,
		dpointer 	val,
		sdint4 		val_len
);

功能

设置描述符记录单个域的值。

参数:

  1. dpi_desc

输入参数,描述符句柄。

  1. rec_num

输入参数,包含所设置域的描述符记录的索引号。此参数从0起始。当为0时,表示所设置的为书签列。此参数值必须大于等于0。如果此参数的值大于DSQL_DESC_COUNT的值,则DSQL_DESC_COUNT的值改变为rec_num。

  1. field

输入参数,所要设置的域。详见说明。

  1. val

输入参数,指向包含描述符信息的缓冲区,或者一个4字节的值。数据类型依赖于field的值。如果val为一个4字节的值,则是4字节还是2字节的值依赖于field参数。

  1. val_len

输入参数,如果val指向一个字符串或者二进制缓冲区,则此参数为val的长度。如果val是一个整形数,则此参数被忽略。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明:

属性 字段类型 属性 字段类型
DSQL_DESC_ALLOC_TYPE sdint2 DSQL_DESC_LITERAL_PREFIX sdbyte*
DSQL_DESC_ARRAY_SIZE ulength DSQL_DESC_LITERAL_SUFFIX sdbyte*
DSQL_DESC_ARRAY_STATUS_PTR udint2* DSQL_DESC_LOCAL_TYPE_NAME sdbyte*
DSQL_DESC_BIND_OFFSET_PTR slength* DSQL_DESC_NAME sdbyte*
DSQL_DESC_BIND_TYPE ulength DSQL_DESC_NULLABLE sdint2
DSQL_DESC_COUNT sdint2 DSQL_DESC_NUM_PREC_RADIX sdint4
DSQL_DESC_ROWS_PROCESSED_PTR ulength* DSQL_DESC_OCTET_LENGTH slength
DSQL_DESC_AUTO_UNIQUE_VALUE sdint4 DSQL_DESC_OCTET_LENGTH_PTR slength*
DSQL_DESC_BASE_COLUMN_NAME sdbyte* DSQL_DESC_PARAMETER_TYPE sdint2
DSQL_DESC_BASE_TABLE_NAME sdbyte* DSQL_DESC_PRECISION sdint2
DSQL_DESC_CASE_SENSITIVE sdint4 DSQL_DESC_ROWVER sdint2
DSQL_DESC_CATALOG_NAME sdbyte* DSQL_DESC_SCALE sdint2
DSQL_DESC_CONCISE_TYPE sdint2 DSQL_DESC_SCHEMA_NAME sdbyte*
DSQL_DESC_DATA_PTR void* DSQL_DESC_SEARCHABLE sdint2
DSQL_DESC_DATETIME_INTERVAL_CODE sdint2 DSQL_DESC_TABLE_NAME sdbyte*
DSQL_DESC_DATETIME_INTERVAL_PRECISION sdint4 DSQL_DESC_TYPE sdint2
DSQL_DESC_DISPLAY_SIZE slength DSQL_DESC_TYPE_NAME sdbyte*
DSQL_DESC_FIXED_PREC_SCALE sdint2 DSQL_DESC_UNNAMED sdint2
DSQL_DESC_INDICATOR_PTR slength* DSQL_DESC_UNSIGNED sdint2
DSQL_DESC_LABEL sdbyte* DSQL_DESC_UPDATABLE sdint2
DSQL_DESC_LENGTH ulength

28. dpi_get_desc_rec

函数

DPIRETURN
dpi_get_desc_rec(
    dhdesc      dpi_desc,
    sdint2       rec_num,
    sdbyte      *name_buf,
    sdint2       name_buf_len,
    sdint2       *name_len,
    sdint2       *type,
    sdint2       *sub_type,
    slength      *length,
    sdint2       *prec,
    sdint2       *scale,
    sdint2       *nullable
);

功能

获取复合的描述符记录的域的当前设置或值。

参数:

  1. dpi_desc

输入参数,描述符句柄。

  1. rec_num

输入参数,包含所要获取域的描述符记录的索引号。此参数从0起始。当为0时,表示所设置的为书签列。此参数值必须大于等于0且小于等于DSQL_DESC_COUNT的值。

3)name_buf

输出参数,指向返回DSQL_DESC_NAME域值的缓冲区的指针。

  1. name_buf_len

输入参数,name_buf缓冲区的字节长度。

5)name_len

输出参数,指向返回可填充name_buf的数据的总长度的缓冲区的指针。如果总长度大于或等于name_buf_len,则name_buf中的数据被截断,并以0结尾。

  1. type

输出参数,指向返回DSQL_DESC_TYPE域值的缓冲区的指针。

  1. sub_type

输入参数,对于类型为DSQL_DT或者DSQL_INTERVAL的记录,此参数值设置DSQL_DESC_DATETIME_INTERVAL_CODE域的值。

  1. length

输出参数,指向返回DSQL_DESC_OCTET_LENGTH域值的缓冲区指针。

  1. prec

输出参数,指向返回DSQL_DESC_PRECISION域值的缓冲区指针。

  1. scale

输出参数,指向返回DSQL_DESC_SCALE域值的缓冲区指针。

  1. nullable

输出参数,指向返回DSQL_DESC_NULLABLE域值的缓冲区指针。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

DSQL_NO_DATA

说明:

具体参见dpi_set_desc_field说明。

29. dpi_get_desc_field

函数

DPIRETURN
dpi_get_desc_field(
    dhdesc      dpi_desc,
    sdint2       rec_num,
    sdint2       field,
    dpointer     val,
    sdint4       val_len,
    sdint4       *str_len
);

功能

获取单个描述符记录的域的当前值或设置。

参数:

1) dpi_desc

输入参数,描述符句柄。

2) rec_num

输入参数,包含所要获取域的描述符记录的索引号。此参数从0起始。当为0时,表示所设置的为书签列。此参数值必须大于等于0且小于等于DSQL_DESC_COUNT的值。

  1. field

输入参数,需要获取值的描述符域。详见函数dpi_set_desc_field。

  1. val

输出参数,指向返回描述信息的缓冲区的指针。数据类型依赖于field。

  1. val_len

输入参数,如果val返回的是字符串类型的值,则此参数表示val缓冲区的字节长度。如果val返回的整形数,则此参数被忽略。

  1. str_len

输出参数,指向返回val中可填充的最大字符串的字节长度的缓冲区指针。

返回值

DSQL_SUCCESS

DSQL_SUCCES_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

DSQL_NO_DATA

说明:

具体参见dpi_set_desc_field说明。

30. dpi_bind_param

函数

DPIRETURN
dpi_bind_param(
    dhstmt          dpi_hstmt,
    udint2           iparam,
    sdint2           param_type,
    sdint2           ctype,
    sdint2           dtype,
    ulength          precision,
    sdint2           scale,
    dpointer         buf,
    slength          buf_len,
    slength          *ind_ptr
);

功能

绑定缓冲区到SQL语句中的参数标记。

参数:

  1. dpi**_**hstmt

输入参数,语句句柄。

  1. iparam

输入参数,参数索引号。起始为1。

  1. param_type

输入参数,参数的类型。必须是下列值之一:

● DSQL_PARAM_INPUT 用于绑定非调用存储过程的SQL语句的输入参数

● DSQL_PARAM_OUTPUT 用于绑定过程、函数、语句的输出参数

● DSQL_PARAM_INPUT_OUTPUT 用于绑定调用存储过程的输入和输出参数

● DSQL_PARAM_INPUT_OUTPUT_STREAM 用于绑定输入输出流

● DSQL_PARAM_OUTPUT_STREAM 用于绑定输出流

  1. ctype

输入参数,参数的C数据类型。

  1. dtype

输入参数,参数所对应的数据库的D数据类型

  1. precision

输入参数,列的宽度或者参数相应域的值。

  1. scale

输入参数,列的小数位数或者参数相应域的值。

  1. buf

输入参数,指向存放参数数据的缓冲区的指针。

  1. buf_len

输入参数,buf缓冲的字节长度。

  1. ind_ptr

输入参数,指向存储参数长度的缓冲区的指针。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明:

绑定信息将持续作用直到再次调用dpi_bind_param或者dpi_unbind_params。

31. dpi_desc_param

函数

DPIRETURN
dpi_desc_param(
    dhstmt           dpi_hstmt,
    udint2           iparam,
    sdint2           *sql_type,
    ulength          *prec,
    sdint2           *scale,
    sdint2           *nullable
);

功能

获取准备语句中参数的相关描述信息。

参数:

  1. dpi_hstmt

输入参数,语句句柄。

  1. iparam

输入参数,参数的索引号。起始为1。

  1. sql_type

输出参数,指向返回参数数据库D类型的缓冲区的指针。

  1. prec

输出参数,指向返回参数相应域的值的缓冲区的指针。

  1. scale

输出参数,指向返回参数相应域的值的缓冲区的指针。

  1. nullable

输出参数,指向返回参数是否允许为空的缓冲区的指针。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明:

在绑定信息作用期间返回绑定参数描述信息;无绑定信息时返回服务器描述信息。

32. dpi_exec

函数

DPIRETURN
dpi_exec(
		dhstmt 		dpi_hstmt
);

功能

执行一个已经准备好的语句。如果参数中包含参数,则使用参数的当前设置或值。

参数:

dpi_hstmt

输入参数,语句句柄。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

DSQL_NEED_DATA

说明:

执行一个已准备好的语句,可以多次执行。如果多次执行一个查询语句,需要先调用dpi_close_cursor关闭当前游标,否则会报错。

33. dpi_exec_add_batch

函数

DPIRETURN
dpi_exec_add_batch(
    dhstmt          dpi_hstmt
);

功能

发送一行绑定的数据到dpi做数据转换及存储

参数:

dpi_hstmt

输入参数,语句句柄。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明:

此接口函数提供单行数据绑定插入的缓存,用户绑定参数后,调用此接口进行数据缓存,结合接口dpi_exec_batch可以进行数据插入。接口不支持输出参数,大字段及延迟绑定数据方式。

34. dpi_exec _batch

函数

DPIRETURN
dpi_exec_batch(
    dhstmt          dpi_hstmt
);

功能

发送已经缓存的数据到服务器进行插入操作

参数:

dpi_hstmt

输入参数,语句句柄。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明:

此接口发送dpi_exec_add_batch接口所缓存的数据到服务器进行插入操作。

35. dpi_exec_direct

函数

DPIRETURN
dpi_exec_direct(
    dhstmt          dpi_hstmt,
    sdbyte          *sql_txt
);

功能

直接执行一条语句。如果语句中包含参数,则使用参数的当前设置或值。

参数:

  1. dpi_hstmt

输入参数,语句句柄。

  1. sql_txt

输入参数,要执行的sql语句,以结束符结尾。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

DSQL_NEED_DATA

说明:

单次执行某条语句。

36. dpi_unbind_params

函数

DPIRETURN
dpi_unbind_params(
    dhstmt          dpi_hstmt
);

功能

清空语句句柄上绑定的参数信息。

参数:

dpi_hstmt

输入参数,语句句柄。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明:

37. dpi_unbind_columns

函数

DPIRETURN
dpi_unbind_columns(
    dhstmt          dpi_hstmt
);

功能

清空语句句柄上绑定的列信息。

参数:

dpi_hstmt

输入参数,语句句柄。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明:

38. dpi_param_data

函数

DPIRETURN
dpi_param_data(
    dhstmt          dpi_hstmt,
    dpointer         *val_ptr
);

功能

与dpi_put_data一起使用,用于协助在语句执行时提供参数的数据。

参数:

  1. dpi_hstmt

输入参数,语句句柄。

  1. val_ptr

输出参数,指向用于返回dpi_bind_param绑定的参数地址的缓冲区指针。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

DSQL_NEED_DATA

说明:

当调用dpi_exec或者dpi_exec_direct时,如果返回DSQL_NEED_DATA,则说明需要提供某个参数的数据,此时调用dpi_param_data获取具体参数的信息,并调用dpi_put_data发送相应参数的数据。再次循环上述步骤直至dpi_param_data返回DSQL_SUCCESS或DSQL_SUCCESS_WITH_INFO。

39. dpi_prepare

函数

DPIRETURN
dpi_prepare(
    dhstmt          dpi_hstmt,
    sdbyte          *sql_txt
);

功能

准备一条用于执行的sql语句。

参数:

  1. dpi_hstmt

输入参数,语句句柄。

  1. sql_txt

输入参数,需要准备的sql语句,以结束符结尾。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明:

40. dpi_put_data

函数

DPIRETURN
dpi_put_data(
    dhstmt          dpi_hstmt,
    dpointer         val,
    slength          val_len
);

功能

在语句执行时发送参数数据到驱动。与dpi_param_data配合使用。

参数:

  1. dpi_hstmt

输入参数,语句句柄。

  1. val

输入参数,指向包含实际数据缓冲区的指针。缓冲区数据类型必须与dpi_bind_param时绑定的C类型一致。

  1. val_len

输入参数,val中数据的实际字节长度。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明:

参见dpi_param_data说明。

41. dpi_number_params

函数

DPIRETURN
dpi_number_params(
    dhstmt          dpi_hstmt,
    sdint2          *param_cnt
);

功能

获取sql语句中包含参数的个数。

参数:

  1. dpi_hstmt

输入参数,语句句柄。

  1. param_cnt

输出参数,指向用于存放参数个数的缓冲区的指针。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明:

42. dpi_set_cursor_name

函数

DPIRETURN
dpi_set_cursor_name(
    dhstmt          dpi_hstmt,
    sdbyte          *name,
    sdint2           name_len
);

功能

设置游标的游标名。如果不设置游标名,驱动将创建默认的游标名。

参数:

  1. dpi_hstmt

输入参数,语句句柄。

  1. name

输入参数,指向包含游标名的缓冲区的指针。

  1. name_len

输入参数,name的实际长度。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明:

游标名用于定位更新/删除操作。

43. dpi_get_cursor_name

函数

DPIRETURN
dpi_get_cursor_name(
    dhstmt          dpi_hstmt,
    sdbyte          *name,
    sdint2           buf_len,
    sdint2           *name_len
);

功能

获取指定语句句柄上的游标名。

参数:

  1. dpi_hstmt

输入参数,语句句柄。

  1. name

输出参数,指向返回游标名的缓冲区的指针。

  1. buf_len

输入参数,name缓冲区的字节长度。

  1. name_len

输出参数,执行存放游标名总长度的缓冲区指针。如果游标名长度大于或者等于buf_len,则name中的数据被截断并以0结尾。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明:

  1. dpi_close_cursor

函数

DPIRETURN
dpi_close_cursor(
    dhstmt          dpi_hstmt
);

功能

关闭语句句柄上已经打开的游标,并丢弃所关联的结果集。

参数:

dpi_hstmt

输入参数,语句句柄。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明:

45. dpi_bind_col

函数

DPIRETURN
dpi_bind_col(
    dhstmt          dpi_hstmt,
    udint2           icol,
    sdint2           ctype,
    dpointer         val,
    slength          buf_len,
    slength          *ind
);

功能

绑定数据缓冲区到结果集中的列。

参数:

  1. dpi_hstmt

输入参数,语句句柄。

  1. icol

输入参数,结果集列的索引号。起始为0。如果icol为0,则绑定的为书签列。

  1. ctype

输入参数,数据转换指定的C类型。

  1. val

输出参数,指向存放实际值的缓冲区。

  1. buf_len

输入参数,存放数据缓冲区的长度。

  1. ind

输出参数,指向返回实际数据长度的缓冲区。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明:

绑定列到输出缓冲区用于在调用dpi_fetch或者dpi_fetch_scroll时检索数据。

46. dpi_number_columns

函数

DPIRETURN
dpi_number_columns(
    dhstmt          dpi_hstmt,
    sdint2           *col_cnt
);

功能

获取结果集中列的个数。

参数:

  1. dpi_hstmt

输入参数,语句句柄。

  1. col_cnt

输出参数,指向返回结果集列个数的缓冲区的指针。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明:

47. dpi_desc_column

函数

DPIRETURN
dpi_desc_column(
    dhstmt          dpi_hstmt,
    sdint2           icol,
    sdbyte          *name,
    sdint2           buf_len,
    sdint2           *name_len,
    sdint2           *sqltype,
    ulength          *col_sz,
    sdint2           *dec_digits,
    sdint2           *nullable
);

功能

获取结果集列的描述信息。

参数:

  1. dpi_hstmt

输入参数,语句句柄。

  1. icol

输入参数,结果集列的索引号。起始为0。如果为0,则描述的是书签列信息。

  1. name

输出参数,指向返回列名的缓冲区的指针。

  1. buf_len

输入参数,name缓冲区的字节长度。

  1. name_len

输出参数,指向返回列名总长度的缓冲区的指针。如果列名长度大于或者等于buf_len,则name中数据被截断并以结束符结尾。

  1. sqltype

输出参数,指向返回列的数据库DSQL类型的缓冲区的指针。

  1. col_sz

输出参数,指向返回列的宽度的缓冲区的指针。

  1. dec_digits

输出参数,指向返回列的小数位数的缓冲区的指针。

  1. nullable

输出参数,指向返回列是否允许为空的缓冲区的指针。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明

48. dpi_col_attr

函数

DPIRETURN
dpi_col_attr(
    dhstmt          dpi_hstmt,
    udint2           icol,
    udint2           fld_id,
    dpointer         chr_attr,
    sdint2           buf_len,
    sdint2           *chr_attr_len,
    slength          *num_attr
);

功能

获取结果集中列的描述信息。

参数

  1. dpi_hstmt

输入参数,语句句柄。

  1. icol

输入参数,结果集列的索引号。起始索引为0。当参数被指定为0时,除了DSQL_DESC_TYPE和DSQL_DESC_OCTET_LENGTH外,其他域的值为无效值。

  1. fld_id

输入参数,需要获取值的描述域。

  1. chr_attr

输出参数,指向返回fld_id域的值,此参数仅返回字符串,如果fld_id对应的值不是字符串,则此参数不会被使用。

  1. buf_len

输入参数,chr_attr缓冲区的字节长度。

  1. chr_attr_len

输出参数,指向返回fld_id域可返回字符串的最大长度的缓冲区的指针。如果返回值长度大于或者等于buf_len,则chr_attr中数据被截断并以0结尾。

  1. num_attr

输出参数,指向返回整形数的缓冲区的指针。如果fld_id所返回的值为整形数,则此参数有意义,否则此参数不会被使用。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明

详细参数含义参见2.2.4章节。

49. dpi_bulk_operation

函数

DPIRETURN
dpi_bulk_operation(
    dhstmt          dpi_hstmt,
    udint2           op
);

功能

执行批量插入和批量的书签操作。包括通过书签更新、删除、获取数据。

参数

  1. dpi_hstmt

输入参数,语句句柄。

  1. op

输入参数,操作方式。必须是下列之一:

  • DSQL_ADD
  • DSQL_UPDATE_BY_BOOKMARK
  • DSQL_DELETE_BY_BOOKMARK
  • DSQL_FETCH_BY_BOOKMARK

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

DSQL_NEED_DATA

说明

函数执行后游标位置未知,必须调用dpi_fetch_scroll重新定位游标。

50. dpi_fetch

函数

DPIRETURN
dpi_fetch(
    dhstmt          dpi_hstmt,
    ulength         *row_num
);

功能

获取下一个行集数据和返回所有绑定列的数据。

参数

  1. dpi_hstmt

输入参数,语句句柄。

  1. row_num

输出参数,指向返回取得行数的缓冲区的指针。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

DSQL_NO_DATA

说明

51. dpi_fetch_scroll

函数

DPIRETURN
dpi_fetch_scroll(
    dhstmt          dpi_hstmt,
    sdint2           orient,
    slength          offset,
    ulength         *row_num
);

功能

获取指定行集数据和返回所有绑定列的数据。

参数

  1. dpi_hstmt

输入参数,语句句柄。

  1. orient

输入参数,获取方式。必须是下列之一:

  • DSQL_FETCH_NEXT
  • DSQL_FETCH_PRIOR
  • DSQL_FETCH_FIRST
  • DSQL_FETCH_LAST
  • DSQL_FETCH_ABSOLUTE
  • DSQL_FETCH_RELATIVE
  • DSQL_FETCH_BOOKMARK
  1. offset

输入参数,获取行的偏移。此参数的意义依赖于orient,对于orient为DSQL_FETCH_RELATIVE时有效,意义为相对于当前游标位置的偏移量。

  1. row_num

输出参数,指向返回取得行数的缓冲区的指针。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

DSQL_NO_DATA

说明

52. dpi_get_data

函数

DPIRETURN
dpi_get_data(
    dhstmt          dpi_hstmt,
    udint2           icol,
    sdint2           ctype,
    dpointer         val,
    slength          buf_len,
    slength          *val_len
);

功能

获取结果集中单个列的数据。

参数

1)dpi_hstmt

输入参数,语句句柄。

  1. icol

输入参数,结果集中列的索引号。结果集索引起始为1。如果icol被设置为0,则获取的是书签列的值,且只有当书签选项启用时才有效。

  1. ctype

输入参数,所要获取数据的目标C类型。

  1. val

输出参数,指向存放数据的缓冲区的指针。

  1. buf_len

输入参数,val缓冲区的字节长度。

  1. val_len

输出参数,指向存放数据长度的缓冲区的指针。如果此参数为NULL,则不返回长度,如果数据长度为NULL,则返回错误。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

DSQL_NO_DATA

说明

dpi_get_data可以分批获取字符类型或者二进制类型数据。

53. dpi_more_results

函数

DPIRETURN
dpi_more_results(
    dhstmt          dpi_hstmt
);

功能

确定句柄上是否包含有多个结果集。如果有,则处理这些结果集。

参数:

dpi_hstmt

输入参数,语句句柄。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

DSQL_NO_DATA

说明

54. dpi_set_pos

函数

DPIRETURN
dpi_set_pos(
    dhstmt         dpi_hstmt,
    ulength         row_num,
    udint2          op,
    udint2          lock_type
);

功能

定位,更新结果集的数据。

参数

  1. dpi_hstmt

输入参数,语句句柄。

  1. row_num

输入参数,行集中行的位置。如果row_num为0,则操作作用于行集中的每一行。

  1. op

输入参数,操作方式。必须是下列之一:

  • DSQL_POSITION
  • DSQL_REFRESH
  • DSQL_UPDATE
  • DSQL_DELETE
  • DSQL_ADD
  1. lock_type

输入参数,指定在op操作之后行的封锁方式。必须是下列之一:

  • DSQL_LOCK_NO_CHANGE
  • DSQL_LOCK_EXCLUSIVE
  • DSQL_LOCK_UNLOCK

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

DSQL_NEED_DATA

说明

55. dpi_row_count

函数

DPIRETURN
dpi_row_count(
    dhstmt          dpi_hstmt,
    sdint8           *row_num
);

功能

返回sql语句所影响行的总数。

参数

  1. dpi_hstmt

输入参数,语句句柄。

  1. row_num

输出参数,指向返回影响行数的缓冲区的指针。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明

56. dpi_lob_get_length

函数

DPIRETURN
dpi_lob_get_length(
    dhloblctr        dpi_loblctr,
    slength         *len
);

功能

获取lob句柄对应大对象的实际长度。

参数

  1. dpi_loblctr

输入参数,lob句柄。

  1. len

输出参数,指向返回大字段长度的缓冲区的指针。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明

CLOB为字符长度,BLOB为字节长度。

57. dpi_lob_read

函数

DPIRETURN
dpi_lob_read(
    dhloblctr       dpi_loblctr,
    ulength         start_pos,
    sdint2          ctype,
    slength		data_to_read,
    dpointer        val_buf,
    slength         buf_len,
    slength         *data_get
);

功能

读取lob句柄所对应大字段的实际数据。

参数

  1. dpi_loblctr

输入参数,lob句柄。

  1. start_pos

输入参数,起始的偏移。起始为1。CLOB类型此参数表示字符偏移,BLOB类型此参数表示字节偏移。

  1. ctype

输入参数,所获取数据的目标C类型。

  1. data_to_read

输入参数,CLOB类型表示要读取的字符数,BLOB类型表示要读取的字节数,缺省值为0。

  1. val_buf

输出参数,指向存放获取数据的缓冲区的指针。

  1. buf_len

输入参数,val_buf缓冲区的字节长度。

  1. data_get

输出参数,指向返回已获取数据的实际长度。CLOB类型表示字符长度,BLOB类型表示字节长度。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明

58.dpi_lob_write

函数

DPIRETURN
dpi_lob_write(
    dhloblctr             dpi_loblctr,
    ulength              start_pos,
    sdint2               ctype,
    dpointer             val,
    ulength              bytes_to_write,
    ulength              *data_writed
);

功能

更新lob句柄所对应的大字段的数据。

参数

  1. dpi_loblctr

输入参数,lob句柄。

  1. start_pos

输入参数,起始的偏移。起始为1。CLOB类型此参数表示字符偏移,BLOB类型此参数表示字节偏移。

  1. ctype

输入参数,更新数据的C数据类型。

  1. val

输入参数,指向存放更新数据缓冲区的指针。

  1. bytes_to_write

输入参数,需要更新数据的字节长度。

  1. data_writed

输出参数,指向返回已更新数据的长度。对于CLOB类型此参数表示字符长度,BLOB类型则此参数表示字节长度。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明

59. dpi_lob_truncate

函数

DPIRETURN
dpi_lob_truncate(
    dhloblctr            dpi_loblctr,
    ulength             len,
    ulength             *data_len
);

功能

截断lob句柄所对应的大字段到指定的长度。

参数

  1. dpi_loblctr

输入参数,lob句柄。

  1. len

输入参数,大字段被截断后的长度。对于CLOB类型此参数表示字符长度,BLOB类型则此参数表示字节长度。

  1. data_len

输出参数,大字段被截断后的实际长度。对于CLOB类型此参数表示字符长度,BLOB类型则此参数表示字节长度。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明

60. dpi_alloc_obj

函数

DPIRETURN
dpi_alloc_obj(
    dhcon            dpi_con,
    dhobj*            object
);

功能

分配复合类型句柄。

参数

  1. dpi_con

输入参数,通过此连接句柄分配新的语句句柄,新句柄运行环境从属此句柄。

  1. object

输出参数, 一个存放新分配复合对象句柄数据结构的缓冲区地址。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明

61. dpi_free_obj

函数

DPIRETURN
dpi_free_obj(
		dhobj 	object
);

功能

释放复合对象句柄。

参数

  1. object

输入参数,复合对象句柄。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明

62. dpi_desc_obj

函数

DPIRETURN
dpi_desc_obj(  
dhcon           dpi_con,
sdbyte*         schema,
sdbyte*         compobj_name,
dhobjdesc*      obj_desc
);

功能

获取复合对象的描述信息。

参数

  1. dpi_con

输入参数,连接句柄。

  1. schema

输入参数,复合对象所属模式名。

  1. compobj_name

输入参数,复合对象名。

  1. obj_desc

输出参数,复合对象描述符句柄。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明

63. dpi_desc_obj2

函数

DPIRETURN
dpi_desc_obj(  
dhcon           dpi_con,
sdbyte*         schema,
sdbyte*         pkg_name,
sdbyte*         compobj_name,
dhobjdesc*      obj_desc
);

功能

获取复合对象的描述信息。该函数功能覆盖了dpi_desc_obj()的功能,描述的复合对象包括包内的复合对象和不属于包内的复合对象,若对象不属于包内,则pkg_name参数置为NULL即可。

参数

  1. dpi_con

输入参数,连接句柄。

  1. schema

输入参数,复合对象所属模式名。

  1. pkg_name

输入参数,复合对象所在的包名,可以为NULL。

  1. compobj_name

输入参数,复合对象名。

  1. obj_desc

输出参数,复合对象描述符句柄。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明

64. dpi_free_obj_desc

函数

DPIRETURN
dpi_free_obj_desc(  
dhobjdesc       obj_desc
);

功能

释放复合对象描述符句柄。

参数

  1. obj_desc

输入参数,复合对象描述符句柄。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明

65. dpi_get_obj_attr

函数

DPIRETURN
dpi_get_obj_attr(  
    dhobj           object, 
    udint4          nth,
    udint2          attr_id,
    dpointer        buf,
    udint4          buf_len,
    slength*        len
);

功能

获取复合对象的属性值。

参数

  1. object

输入参数,获取属性的复合对象句柄。

  1. nth

保留输入参数,暂不起作用。

  1. attr_id

输入参数,需要获取的属性。

  1. buf

输出参数,指向返回指定属性当前值的缓冲区的指针。

  1. buf_len

输入参数,如果val返回的是字符串,则此参数为val缓冲区的长度。如果val返回的不是字符串,则此参数忽略。

  1. len

输出参数,指向返回val中可提供字符串的总长度的缓冲区的指针。如果val为NULL,则不返回长度,如果属性值为字符串,总长度大于等于buf_len,则val值被截断且以0结尾。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明

属性 字段类型
DSQL_ATTR_OBJ_VAL_COUNT udint4

66. dpi_get_obj_desc_attr

函数

DPIRETURN
dpi_get_obj_desc_attr(
    dhobjdesc       obj_desc,
    udint4          nth,
    udint2          attr_id,
    dpointer        buf,
    udint4          buf_len,
    slength*        len
);

功能

获取复合对象描述符上的属性值。

参数

1)obj_desc

输入参数,复合对象描述符句柄。

  1. nth

复合对象要获取域下标

  1. attr_id

输入参数,需要获取的属性。

  1. buf

输出参数,指向返回指定属性当前值的缓冲区的指针。

  1. buf_len

输入参数,如果val返回的是字符串,则此参数为val缓冲区的长度。如果val返回
的不是字符串,则此参数忽略。

  1. len

输出参数,指向返回val中可提供字符串的总长度的缓冲区的指针。如果val为NULL,则不返回长度,如果属性值为字符串,总长度大于等于buf_len,则val值被截断且以0结尾。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明

属性 字段类型
DSQL_ATTR_OBJ_TYPE sdint2
DSQL_ATTR_OBJ_PREC sdint2
DSQL_ATTR_OBJ_SCALE sdint2
DSQL_ATTR_OBJ_NAME sdbyte*
DSQL_ATTR_OBJ_DESC dhobjdesc
DSQL_ATTR_OBJ_FIELD_COUNT udint4
DSQL_ATTR_OBJ_SCHAME sdbyte*

67. dpi_bind_obj_desc

函数

DPIRETURN

dpi_bind_obj_desc(

dhobj object,

dhobjdesc desc

);

功能

绑定复合对象描述符句柄。

参数

  1. object

输入参数,复合对象句柄。

  1. desc

输入参数,复合对象描述符句柄。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明

68.dpi_unbind_obj_desc

函数

DPIRETURN
dpi_unbind_obj_desc(
    dhobj           object
);

功能

解除复合对象描述符句柄绑定。

参数

  1. object

输入参数,复合对象句柄。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明

69. dpi_set_obj_val

函数

DPIRETURN
dpi_set_obj_val(
    dhobj           object,
    udint4          nth,
    udint2          ctype,
    dpointer        val,
    slength         val_len
);

功能

复合对象绑定值。

参数

  1. object

输入参数,复合对象句柄。

  1. nth

输入参数,绑定域下标。

  1. ctype

输入参数,绑定的c数据类型。

  1. val

输入参数,指向存放参数数据的缓冲区的指针。

  1. val_len

输入参数,指向存储参数长度的缓冲区的指针。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明

70. dpi_get_obj_val

函数

DPIRETURN
dpi_get_obj_val(
    dhobj           object,
    udint4          nth,
    udint2          ctype,
    dpointer        val,
    udint4          buf_len,
    slength*        val_len
);

功能

获取复合对象各个域的值。

参数

  1. object

输入参数,复合对象句柄。

  1. nth

复合对象域下标。

  1. cytpe

输入参数,数据转换指定的C类型。

  1. val

输出参数,指向存放实际值的缓冲区。

  1. buf_len

输入参数,如果val返回的是字符串,则此参数为val缓冲区的长度。如果val返回的不是字符串,则此参数忽略。

  1. val_len

输出参数,指向返回val中可提供字符串的总长度的缓冲区的指针。如果val为NULL,则不返回长度,如果属性值为字符串,总长度大于等于buf_len,则val值被截断且以0结尾。

返回值

DSQL_SUCCESS

DSQL_SUCCESS_WITH_INFO

DSQL_ERROR

DSQL_INVALID_HANDLE

说明

2.4 编程参考

2.4.1 编程步骤

应用程序使用DPI访问数据库,可以按照以下几个基本步骤进行:

  1. 调用函数dpi_alloc_env申请环境句柄。(通过dpi_set_env_attr和dpi_get_env_attr可以设置和获取环境句柄属性,环境句柄属性参考2.2.1)。
  2. 调用函数dpi_alloc_con申请连接句柄(通过dpi_set_con_attr和dpi_get_con_attr可以设置和获取连接句柄属性,连接句柄属性参考2.2.2)。
  3. 调用函数dpi_login连接数据库服务器。
  4. 调用函数dpi_alloc_stmt申请语句句柄(通过dpi_set_stmt_attr和dpi_get_stmt_attr可以设置和获取语句句柄属性,语句句柄属性参考2.2.3)。
  5. 调用函数dpi_exec_direct直接执行SQL语句(也可以通过dpi_prepare准备语句,然后通过dpi_bind_param绑定参数,再通过dpi_exec来执行带参数的sql语句;还可以通过dpi_fetch或dpi_fetch_scroll来获取查询的结果集数据)。
  6. 调用函数dpi_free_stmt释放申请的语句句柄。
  7. 调用函数dpi_logout断开应用程序与数据源之间的连接。
  8. 调用函数dpi_free_con释放申请的连接句柄。
  9. 调用函数dpi_free_env释放申请的环境句柄。

程序在编译的过程中需要用到DM的头文件DPI.h、DPIext.h、DPItypes.h,在链接阶段需要用到dmdpi.lib这个库文件,在执行阶段需要用到动态库dmdpi.dll以及dmcalc.dll、dmcomm.dll、dmcyt.dll、dmclientlex.dll、dmcvt.dll、dmelog.dll、dmmem.dll、dmmsg.dll、dmos.dll、dmutl.dll。这几个动态库在安装DM时,已经被放到安装目录下。

另外,当使用64位的DPI接口时,需要添加DM64的宏,即Linux平台下编译程序时添加“-DDM64”编译参数,Windows平台下则在相应工程的预处理器定义中添加“DM64”。

2.4.2 普通数据插入与查询方式的操作

下面通过一个简单的Windows环境下的示例来说明DPI普通数据插入与查询。

创建一个表,通过参数绑定以及数组绑定的方式插入数据,通过fetch和fetch scroll获取结果集并显示,以及通过将结果集输出到数组中。

##include "DPI.h"
##include "DPIext.h"
##include "DPItypes.h"
##include "stdio.h"
##include "stdlib.h"
##include "string.h"
/******************************************************
Notes:
定义相应常量
*******************************************************/
##define ROWS	10				//数组绑定一次插入和读取的行数
##define CHARS	80*1024		    //一次读取和写入的字节数800K
##define FLEN	500				//文件名长度(带地址路径)
##define DM_SVR  "LOCALHOST"
##define DM_USER "SYSDBA"
##define DM_PWD  "SYSDBA"
/* 函数检查及错误信息显示 */
##define DPIRETURN_CHECK(rt, hndl_type, hndl) if(!DSQL_SUCCEEDED(rt)){dpi_err_msg_print(hndl_type, hndl);return rt;}
##define FUN_CHECK(rt) if(!DSQL_SUCCEEDED(rt)){goto END;}
/******************************************************
Notes:
定义常用句柄和变量
*******************************************************/
dhenv		henv;		/* 环境句柄 */
dhcon		hcon;		/* 连接句柄 */
dhstmt		hstmt;		/* 语句句柄 */
dhdesc      hdesc;      /* 描述符句柄 */
dhloblctr	hloblctr;	/* lob类型控制句柄 */
DPIRETURN   rt;         /* 函数返回值 */
/******************************************************
Notes:
    错误信息获取打印
Param:
	hndl_type:	句柄类型
	hndl:		句柄
Return:
	无
*******************************************************/
void
dpi_err_msg_print(sdint2 hndl_type, dhandle hndl)
{
	sdint4 err_code;
	sdint2 msg_len;
	sdbyte err_msg[SDBYTE_MAX];
    /* 获取错误信息字段 */
/*	dpi_get_diag_field(hndl_type, hndl, 1, DSQL_DIAG_MESSAGE_TEXT, err_msg, sizeof(err_msg), NULL);
	printf("err_msg = %s\n", err_msg);*/
    /* 获取错误信息集合 */
	dpi_get_diag_rec(hndl_type, hndl, 1, &err_code, err_msg, sizeof(err_msg), &msg_len);
	printf("err_msg = %s, err_code = %d\n", err_msg, err_code);
}
/******************************************************
Notes:
    连接数据库
Param:
    server: 服务器IP
    uid:	数据库登录账号
    pwd:	数据库登录密码
Return:
    DSQL_SUCCESS 执行成功
    DSQL_ERROR   执行失败
*******************************************************/
DPIRETURN 
dm_dpi_connect(sdbyte* server,  sdbyte* uid, sdbyte* pwd)
{
    /* 申请环境句柄 */
    rt = dpi_alloc_env(&henv);
    DPIRETURN_CHECK(rt, DSQL_HANDLE_ENV, henv);  
    /* 申请连接句柄 */
    rt = dpi_alloc_con(henv, &hcon);
    DPIRETURN_CHECK(rt, DSQL_HANDLE_DBC, hcon);  
    /* 连接数据库服务器 */
    rt = dpi_login(hcon, server, uid, pwd);
    DPIRETURN_CHECK(rt, DSQL_HANDLE_DBC, hcon);  
    return DSQL_SUCCESS;
}
/************************************************
    断开数据库连接
************************************************/
DPIRETURN
dm_dpi_disconnect()
{
    /* 断开连接 */
    rt = dpi_logout(hcon);
    DPIRETURN_CHECK(rt, DSQL_HANDLE_DBC, hcon);  
    /* 释放连接句柄和环境句柄 */
    rt = dpi_free_con(hcon);
    DPIRETURN_CHECK(rt, DSQL_HANDLE_DBC, hcon);
    rt = dpi_free_env(henv);
    DPIRETURN_CHECK(rt, DSQL_HANDLE_ENV, henv);  
    return DSQL_SUCCESS;
}
/************************************************
    初始化表
************************************************/
DPIRETURN 
dm_init_table()
{
    /* 申请语句句柄 */
    rt = dpi_alloc_stmt(hcon, &hstmt);
    DPIRETURN_CHECK(rt, DSQL_HANDLE_DBC, hcon);
	/* 执行sql */
	dpi_exec_direct(hstmt, "drop table dpi_demo");
    rt = dpi_exec_direct(hstmt, "create table dpi_demo(c1 int, c2 char(20), c3 varchar(50), c4 numeric(7,3), c5 timestamp(5), c6 clob, c7 blob)");
    DPIRETURN_CHECK(rt, DSQL_HANDLE_STMT, hstmt);
    /* 释放语句句柄 */
    rt = dpi_free_stmt(hstmt);
    DPIRETURN_CHECK(rt, DSQL_HANDLE_STMT, hstmt);
  
    printf("dm init table success\n");
    return DSQL_SUCCESS;
}
/************************************************
    通过参数绑定的方式执行sql语句
************************************************/
DPIRETURN
dm_insert_with_bind_param()
{
       sdint4          c1 = 0;         /*  与字段匹配的变量  */ 
     sdbyte           c2[10]; 
     sdbyte           c3[10]; 
     ddouble           c4; 
     dpi_timestamp_t     c5; 
     sdbyte           c6[18]; 
     sdbyte           c7[18];
     slength      c1_ind_ptr;
     slength      c2_ind_ptr;       /* 缓冲区长度  */ 
     slength      c3_ind_ptr; 
	slength      c4_ind_ptr=0;
	slength      c5_ind_ptr=0;
     slength      c6_ind_ptr; 
     slength      c7_ind_ptr;  
     /* 分配语句句柄 */ 
     rt = dpi_alloc_stmt(hcon, &hstmt); 
     DPIRETURN_CHECK(rt, DSQL_HANDLE_DBC, hcon);
     /* 准备sql */ 
  rt = dpi_prepare(hstmt, "insert into dpi_demo(c1,c2,c3,c4,c5,c6,c7) values(?,?,?,?,?,?,?)"); 
     DPIRETURN_CHECK(rt, DSQL_HANDLE_STMT, hstmt);  
     /* 字段变量赋值  */ 
	c1 = 201410;
     memcpy(c2, "abcde", 5); 
     memcpy(c3, "abcdefghi", 9); 
     c4      = 0.009; 
     c5.year    = 2011; 
     c5.month  = 3; 
     c5.day    = 1; 
     c5.hour    = 11; 
     c5.minute  = 45; 
     c5.second  = 50; 
     c5.fraction  = 900000000; 
     memcpy(c6, "adfadsfetre2345ert", 18); 
     memcpy(c7, "1234567890abcdef12", 18);  
     c1_ind_ptr =sizeof(c1);
     c2_ind_ptr = 5;       /* 获取缓冲区长度  */ 
     c3_ind_ptr = 9; 
     c4_ind_ptr =sizeof(c4);
     c5_ind_ptr =sizeof(c5);
     c6_ind_ptr = 18; 
     c7_ind_ptr = 18;  
      /* 绑定参数  */ 
	 rt = dpi_bind_param(hstmt, 1, DSQL_PARAM_INPUT, DSQL_C_SLONG, DSQL_INT, sizeof(c1), 0, &c1, sizeof(c1), &c1_ind_ptr);
     DPIRETURN_CHECK(rt, DSQL_HANDLE_STMT, hstmt); 
     rt = dpi_bind_param(hstmt, 2, DSQL_PARAM_INPUT, DSQL_C_NCHAR, DSQL_CHAR, sizeof(c2), 0, c2, sizeof(c2), &c2_ind_ptr); 
     DPIRETURN_CHECK(rt, DSQL_HANDLE_STMT, hstmt); 
     rt = dpi_bind_param(hstmt, 3, DSQL_PARAM_INPUT, DSQL_C_NCHAR, DSQL_VARCHAR, sizeof(c3), 0, c3, sizeof(c3), &c3_ind_ptr); 
     DPIRETURN_CHECK(rt, DSQL_HANDLE_STMT, hstmt); 
     rt = dpi_bind_param(hstmt, 4, DSQL_PARAM_INPUT, DSQL_C_DOUBLE, DSQL_DOUBLE, sizeof(c4), 0, &c4, sizeof(c4), &c4_ind_ptr); 
     DPIRETURN_CHECK(rt, DSQL_HANDLE_STMT, hstmt); 
     rt = dpi_bind_param(hstmt, 5, DSQL_PARAM_INPUT, DSQL_C_TIMESTAMP, DSQL_TIMESTAMP, sizeof(c5), 0, &c5, sizeof(c5), &c5_ind_ptr); 
     DPIRETURN_CHECK(rt, DSQL_HANDLE_STMT, hstmt); 
     rt = dpi_bind_param(hstmt, 6, DSQL_PARAM_INPUT, DSQL_C_NCHAR, DSQL_CLOB, sizeof(c6), 0, c6, sizeof(c6), &c6_ind_ptr); 
     DPIRETURN_CHECK(rt, DSQL_HANDLE_STMT, hstmt); 
     rt = dpi_bind_param(hstmt, 7, DSQL_PARAM_INPUT, DSQL_C_NCHAR, DSQL_BLOB, sizeof(c7), 0, c7, sizeof(c7), &c7_ind_ptr); 
     DPIRETURN_CHECK(rt, DSQL_HANDLE_STMT, hstmt);  
     /* 执行Dsql */ 
     rt = dpi_exec(hstmt); 
     DPIRETURN_CHECK(rt, DSQL_HANDLE_STMT, hstmt);  
     /* 释放语句句柄  */ 
     rt = dpi_free_stmt(hstmt); 
     DPIRETURN_CHECK(rt, DSQL_HANDLE_STMT, hstmt);  
     printf("dm insert with bind param success\n"); 
     return DSQL_SUCCESS; 
}
/************************************************
    通过参数绑定数组的方式执行sql语句
************************************************/
DPIRETURN
dm_insert_with_bind_array()
{
     sdint4          c1[ROWS];           /*  定义字段相应的变量  */ 
     sdbyte           c2[ROWS][10];   
     sdbyte           c3[ROWS][10];   
     ddouble           c4[ROWS]; 
     dpi_timestamp_t     c5[ROWS]; 
     sdbyte           c6[ROWS][18]; 
     sdbyte           c7[ROWS][18]; 
	slength      c1_ind_ptr[ROWS];       /* 缓冲区长度  */
     slength      c2_ind_ptr[ROWS];       /* 缓冲区长度  */ 
	slength      c3_ind_ptr[ROWS];       /* 缓冲区长度  */
	slength      c4_ind_ptr[ROWS];       /* 缓冲区长度  */
	slength      c5_ind_ptr[ROWS];       /* 缓冲区长度  */
     slength      c6_ind_ptr[ROWS]; 
     slength      c7_ind_ptr[ROWS];  
     int        i; 
     int        i_array_rows = ROWS;  
     /* 分配语句句柄  */ 
     rt = dpi_alloc_stmt(hcon, &hstmt); 
     DPIRETURN_CHECK(rt, DSQL_HANDLE_DBC, hcon);
     /* 设置语句句柄属性  */ 
     rt = dpi_set_stmt_attr(hstmt, DSQL_ATTR_PARAMSET_SIZE, (dpointer)i_array_rows, 
sizeof(i_array_rows)); 
     DPIRETURN_CHECK(rt, DSQL_HANDLE_STMT, hstmt); 
     /* 准备sql */ 
     rt = dpi_prepare(hstmt, "insert into dpi_demo(c1,c2,c3,c4,c5,c6,c7) values(?,?,?,?,?,?,?)"); 
     DPIRETURN_CHECK(rt, DSQL_HANDLE_STMT, hstmt); 
     /* 赋值  */ 
     for (i=0; i<i_array_rows; i++)  
     { 
         c1[i]      = i+10; 
         memcpy(c2[i], "abcde", 5); 
         memcpy(c3[i], "abcdefghi", 9); 
         c4[i]      = 0.00901; 
	    c5[i].year    = 2011; 
         c5[i].month  = 3; 
         c5[i].day    = 1; 
         c5[i].hour    = 11; 
         c5[i].minute  = 45; 
         c5[i].second  = 50; 
         c5[i].fraction  = 900; 
         memcpy(c6[i], "adfadsfetre2345ert", 18); 
         memcpy(c7[i], "1234567890abcdef12", 18);
	    c1_ind_ptr[i] = sizeof(c1[i]);
         c2_ind_ptr[i] = 5;  /* 获取缓冲区长度 */ 
         c3_ind_ptr[i] = 9; 
	    c4_ind_ptr[i] = sizeof(c4[i]);
	    c5_ind_ptr[i] = sizeof(c5[i]);
         c6_ind_ptr[i] = 18; 
         c7_ind_ptr[i] = 18; 
     }  
     /* 绑定参数  */ 
     rt = dpi_bind_param(hstmt, 1, DSQL_PARAM_INPUT, DSQL_C_SLONG, DSQL_INT, sizeof(c1[0]), 0, &c1[0], sizeof(c1[0]), &c1_ind_ptr[0]); 
     DPIRETURN_CHECK(rt, DSQL_HANDLE_STMT, hstmt); 
     rt = dpi_bind_param(hstmt, 2, DSQL_PARAM_INPUT, DSQL_C_NCHAR, DSQL_CHAR, 
sizeof(c2[0]), 0, c2[0], sizeof(c2[0]), &c2_ind_ptr[0]); 
     DPIRETURN_CHECK(rt, DSQL_HANDLE_STMT, hstmt); 
     rt = dpi_bind_param(hstmt, 3, DSQL_PARAM_INPUT, DSQL_C_NCHAR, DSQL_VARCHAR, 
	 sizeof(c3[0]), 0, c3[0], sizeof(c3[0]), &c3_ind_ptr[0]); 
     DPIRETURN_CHECK(rt, DSQL_HANDLE_STMT, hstmt); 
     rt = dpi_bind_param(hstmt, 4, DSQL_PARAM_INPUT, DSQL_C_DOUBLE, DSQL_DOUBLE, 
sizeof(c4[0]), 0, &c4[0], sizeof(c4[0]), (slength*)&c4_ind_ptr[0]); 
     DPIRETURN_CHECK(rt, DSQL_HANDLE_STMT, hstmt); 
     rt = dpi_bind_param(hstmt, 5, DSQL_PARAM_INPUT, DSQL_C_TIMESTAMP, 
DSQL_TIMESTAMP, sizeof(c5[0]), 0, &c5[0], sizeof(c5[0]), (slength*)&c5_ind_ptr[0]); 
     DPIRETURN_CHECK(rt, DSQL_HANDLE_STMT, hstmt); 
     rt = dpi_bind_param(hstmt, 6, DSQL_PARAM_INPUT, DSQL_C_NCHAR, DSQL_CLOB, 
sizeof(c6[0]), 0, c6[0], sizeof(c6[0]), &c6_ind_ptr[0]); 
     DPIRETURN_CHECK(rt, DSQL_HANDLE_STMT, hstmt); 
     rt = dpi_bind_param(hstmt, 7, DSQL_PARAM_INPUT, DSQL_C_NCHAR, DSQL_BLOB, 
sizeof(c7[0]), 0, c7[0], sizeof(c7[0]), &c7_ind_ptr[0]); 
     DPIRETURN_CHECK(rt, DSQL_HANDLE_STMT, hstmt); 
     /* 执行Dsql */ 
     rt = dpi_exec(hstmt); 
     DPIRETURN_CHECK(rt, DSQL_HANDLE_STMT, hstmt);  
     /* 释放语句句柄  */ 
     rt = dpi_free_stmt(hstmt); 
     DPIRETURN_CHECK(rt, DSQL_HANDLE_STMT, hstmt);  
     printf("dm insert with bind array success\n"); 
     return DSQL_SUCCESS; 
}
/************************************************
    fetch获取结果集
************************************************/
DPIRETURN
dm_select_with_fetch()
{
    sdint4		        c1 = 0;             /* 与字段匹配的变量,用于获取字段值 */
    sdbyte		        c2[20];
    sdbyte		        c3[50];
    ddouble		   c4;
    dpi_timestamp_t		c5;
    sdbyte		        c6[50];
    sdbyte		        c7[FLEN];  
    slength		        c1_ind = 0;     /* 缓冲区 */
    slength		        c2_ind = 0;
    slength		        c3_ind = 0;
    slength		        c4_ind = 0;
    slength		        c5_ind = 0;
    slength		        c6_ind = 0;
    slength		        c7_ind = 0;  
    ulength		        row_num;        /* 行数 */
    sdint4                 dataflag = 0;  
    /* 分配语句句柄 */
    DPIRETURN_CHECK(dpi_alloc_stmt(hcon, &hstmt), DSQL_HANDLE_STMT, hstmt);  
    /* 执行sql语句 */
    DPIRETURN_CHECK(dpi_exec_direct(hstmt, "select c1,c2,c3,c4,c5,c6,c7 from dpi_demo"), DSQL_HANDLE_STMT, hstmt);  
    /* 绑定输出列 */
    DPIRETURN_CHECK(dpi_bind_col(hstmt, 1, DSQL_C_SLONG, &c1, sizeof(c1), &c1_ind), DSQL_HANDLE_STMT, hstmt);
    DPIRETURN_CHECK(dpi_bind_col(hstmt, 2, DSQL_C_NCHAR, &c2, sizeof(c2), &c2_ind), DSQL_HANDLE_STMT, hstmt);
    DPIRETURN_CHECK(dpi_bind_col(hstmt, 3, DSQL_C_NCHAR, &c3, sizeof(c3), &c3_ind), DSQL_HANDLE_STMT, hstmt);
    DPIRETURN_CHECK(dpi_bind_col(hstmt, 4, DSQL_C_DOUBLE, &c4, sizeof(c4), &c4_ind), DSQL_HANDLE_STMT, hstmt);
    DPIRETURN_CHECK(dpi_bind_col(hstmt, 5, DSQL_C_TIMESTAMP, &c5, sizeof(c5), &c5_ind), DSQL_HANDLE_STMT, hstmt);
    DPIRETURN_CHECK(dpi_bind_col(hstmt, 6, DSQL_C_NCHAR, &c6, sizeof(c6), &c6_ind), DSQL_HANDLE_STMT, hstmt);
    DPIRETURN_CHECK(dpi_bind_col(hstmt, 7, DSQL_C_NCHAR, &c7, sizeof(c7), &c7_ind), DSQL_HANDLE_STMT, hstmt);  
    printf("dm_select_with_fetch......\n");
    printf("----------------------------------------------------------------------\n");
    while(dpi_fetch(hstmt, &row_num) != DSQL_NO_DATA)
    {
        printf("c1 = %d, c2 = %s, c3 = %s, c4 = %f, ", c1, c2, c3, c4);
        printf("c5 = %d-%d-%d %d:%d:%d.%d\n",c5.year,c5.month,c5.day,c5.hour,c5.minute,c5.second,c5.fraction);
        printf("c6 = %s, c7 = %s\n",c6, c7);
        dataflag = 1;
    }
    printf("----------------------------------------------------------------------\n");
    if (!dataflag)
    {
        printf("dm no data\n");
    }  
    /* 释放语句句柄 */
    DPIRETURN_CHECK(dpi_free_stmt(hstmt), DSQL_HANDLE_STMT, hstmt);
    return DSQL_SUCCESS;
}
/************************************************
    使用参数绑定后再fetch获取结果集
************************************************/
DPIRETURN
dm_select_with_fetch_with_param()
{
    sdint4		        c1 = 0;             /* 与字段匹配的变量,用于获取字段值 */
    slength             c1_param_ind = 0;
    sdbyte		        c2[20];
    sdbyte		        c3[50];
    ddouble		        c4;
    dpi_timestamp_t		c5;
    sdbyte		        c6[50];
    sdbyte		        c7[FLEN];  
    slength		        c1_ind = 0;     /* 缓冲区 */
    slength		        c2_ind = 0;
    slength		        c3_ind = 0;
    slength		        c4_ind = 0;
    slength		        c5_ind = 0;
    slength		        c6_ind = 0;
    slength		        c7_ind = 0;  
    ulength		        row_num;        /* 行数 */  
    sdint4              dataflag = 0;  
    c1 = 10;    //读取c1=10的数据  
    /* 分配语句句柄 */
    DPIRETURN_CHECK(dpi_alloc_stmt(hcon, &hstmt), DSQL_HANDLE_STMT, hstmt);
    /* 准备sql */
    DPIRETURN_CHECK(dpi_prepare(hstmt, "select c1,c2,c3,c4,c5,c6,c7 from dpi_demo where c1 = ?"), DSQL_HANDLE_STMT, hstmt);
    /* 绑定参数 */
    DPIRETURN_CHECK(dpi_bind_param(hstmt, 1, DSQL_PARAM_INPUT, DSQL_C_STINYINT, DSQL_INT, sizeof(c1), 0, &c1, sizeof(c1), &c1_param_ind), DSQL_HANDLE_STMT, hstmt);
    /* 执行sql */
    DPIRETURN_CHECK(dpi_exec(hstmt), DSQL_HANDLE_STMT, hstmt);  
    /* 绑定输出列 */
    DPIRETURN_CHECK(dpi_bind_col(hstmt, 1, DSQL_C_SLONG, &c1, sizeof(c1), &c1_ind), DSQL_HANDLE_STMT, hstmt);
    DPIRETURN_CHECK(dpi_bind_col(hstmt, 2, DSQL_C_NCHAR, &c2, sizeof(c2), &c2_ind), DSQL_HANDLE_STMT, hstmt);
    DPIRETURN_CHECK(dpi_bind_col(hstmt, 3, DSQL_C_NCHAR, &c3, sizeof(c3), &c3_ind), DSQL_HANDLE_STMT, hstmt);
    DPIRETURN_CHECK(dpi_bind_col(hstmt, 4, DSQL_C_DOUBLE, &c4, sizeof(c4), &c4_ind), DSQL_HANDLE_STMT, hstmt);
    DPIRETURN_CHECK(dpi_bind_col(hstmt, 5, DSQL_C_TIMESTAMP, &c5, sizeof(c5), &c5_ind), DSQL_HANDLE_STMT, hstmt);
    DPIRETURN_CHECK(dpi_bind_col(hstmt, 6, DSQL_C_NCHAR, &c6, sizeof(c6), &c6_ind), DSQL_HANDLE_STMT, hstmt);
    DPIRETURN_CHECK(dpi_bind_col(hstmt, 7, DSQL_C_NCHAR, &c7, sizeof(c7), &c7_ind), DSQL_HANDLE_STMT, hstmt);  
    /* 打印输出信息 */
    printf("dm_select_with_fetch_with_param......\n");
    printf("----------------------------------------------------------------------\n");
    while(dpi_fetch(hstmt, &row_num) != DSQL_NO_DATA)
    {
        printf("c1 = %d, c2 = %s, c3 = %s, c4 = %f, ", c1, c2, c3, c4);
        printf("c5 = %d-%d-%d %d:%d:%d.%d\n",c5.year,c5.month,c5.day,c5.hour,c5.minute,c5.second,c5.fraction);
        printf("c6 = %s, c7 = %s\n",c6, c7);
        dataflag = 1;
    }
    printf("----------------------------------------------------------------------\n");
    if (!dataflag)
    {
        printf("dm no data\n");
    }  
    /* 释放语句句柄 */
    DPIRETURN_CHECK(dpi_free_stmt(hstmt), DSQL_HANDLE_STMT, hstmt);
    return DSQL_SUCCESS;
}
/************************************************
    fetch获取结果集,scroll结果集
************************************************/
DPIRETURN
dm_select_with_fetch_scroll()
{
    sdint4		        c1 = 0;             /* 与字段匹配的变量,用于获取字段值 */
    sdbyte		        c2[20];
    sdbyte		        c3[50];
    ddouble		        c4;
    dpi_timestamp_t		c5;
    sdbyte		        c6[50];
    sdbyte		        c7[FLEN];
    slength		        c1_ind = 0;     /* 缓冲区 */
    slength		        c2_ind = 0;
    slength		        c3_ind = 0;
    slength		        c4_ind = 0;
    slength		        c5_ind = 0;
    slength		        c6_ind = 0;
    slength		        c7_ind = 0;
    ulength		        row_num;        /* 行数 */
    ulength				val = DSQL_CURSOR_DYNAMIC;
    sdint4              dataflag = 0;
    /* 分配语句句柄 */
    DPIRETURN_CHECK(dpi_alloc_stmt(hcon, &hstmt), DSQL_HANDLE_STMT, hstmt);
    /* 设置语句句柄属性 */
    DPIRETURN_CHECK(dpi_set_stmt_attr(hstmt, DSQL_ATTR_CURSOR_TYPE, (dpointer)val, 0), DSQL_HANDLE_STMT, hstmt);
    /* 执行sql */
    DPIRETURN_CHECK(dpi_exec_direct(hstmt, "select c1,c2,c3,c4,c5,c6,c7 from dpi_demo"), DSQL_HANDLE_STMT, hstmt);
    /* 绑定输出列 */
    DPIRETURN_CHECK(dpi_bind_col(hstmt, 1, DSQL_C_SLONG, &c1, sizeof(c1), &c1_ind), DSQL_HANDLE_STMT, hstmt);
    DPIRETURN_CHECK(dpi_bind_col(hstmt, 2, DSQL_C_NCHAR, &c2, sizeof(c2), &c2_ind), DSQL_HANDLE_STMT, hstmt);
    DPIRETURN_CHECK(dpi_bind_col(hstmt, 3, DSQL_C_NCHAR, &c3, sizeof(c3), &c3_ind), DSQL_HANDLE_STMT, hstmt);
    DPIRETURN_CHECK(dpi_bind_col(hstmt, 4, DSQL_C_DOUBLE, &c4, sizeof(c4), &c4_ind), DSQL_HANDLE_STMT, hstmt);
    DPIRETURN_CHECK(dpi_bind_col(hstmt, 5, DSQL_C_TIMESTAMP, &c5, sizeof(c5), &c5_ind), DSQL_HANDLE_STMT, hstmt);
    DPIRETURN_CHECK(dpi_bind_col(hstmt, 6, DSQL_C_NCHAR, &c6, sizeof(c6), &c6_ind), DSQL_HANDLE_STMT, hstmt);
    DPIRETURN_CHECK(dpi_bind_col(hstmt, 7, DSQL_C_NCHAR, &c7, sizeof(c7), &c7_ind), DSQL_HANDLE_STMT, hstmt);
    /* 显示输出信息 */
    printf("dm_select_with_fetch_scroll......\n");
    printf("----------------------------------------------------------------------\n");
    while(dpi_fetch_scroll(hstmt, DSQL_FETCH_NEXT, 0, &row_num) != DSQL_NO_DATA)
    {
        printf("c1 = %d, c2 = %s, c3 = %s, c4 = %f, ", c1, c2, c3, c4);
        printf("c5 = %d-%d-%d %d:%d:%d.%d\n",c5.year,c5.month,c5.day,c5.hour,c5.minute,c5.second,c5.fraction);
        printf("c6 = %s, c7 = %s\n",c6, c7);
        dataflag = 1;
    }
    if (!dataflag)
    {
        printf("dm no data\n");
        return DSQL_SUCCESS;
    }
    DPIRETURN_CHECK(dpi_fetch_scroll(hstmt, DSQL_FETCH_FIRST, 0, &row_num), DSQL_HANDLE_STMT, hstmt);
    printf("move first : 1\n");
    printf("c1 = %d, c2 = %s, c3 = %s, c4 = %f, ", c1, c2, c3, c4);
    printf("c5 = %d-%d-%d %d:%d:%d.%d\n",c5.year,c5.month,c5.day,c5.hour,c5.minute,c5.second,c5.fraction);
    printf("c6 = %s, c7 = %s\n",c6, c7);
    DPIRETURN_CHECK(dpi_fetch_scroll(hstmt, DSQL_FETCH_LAST, 0, &row_num), DSQL_HANDLE_STMT, hstmt);
    printf("move last : 19\n");
    printf("c1 = %d, c2 = %s, c3 = %s, c4 = %f, ", c1, c2, c3, c4);
    printf("c5 = %d-%d-%d %d:%d:%d.%d\n",c5.year,c5.month,c5.day,c5.hour,c5.minute,c5.second,c5.fraction);
    printf("c6 = %s, c7 = %s\n",c6, c7);
    DPIRETURN_CHECK(dpi_fetch_scroll(hstmt, DSQL_FETCH_ABSOLUTE, 6, &row_num), DSQL_HANDLE_STMT, hstmt);
    printf("move absolute 6: 14\n");
    printf("c1 = %d, c2 = %s, c3 = %s, c4 = %f, ", c1, c2, c3, c4);
    printf("c5 = %d-%d-%d %d:%d:%d.%d\n",c5.year,c5.month,c5.day,c5.hour,c5.minute,c5.second,c5.fraction);
    printf("c6 = %s, c7 = %s\n",c6, c7);
    DPIRETURN_CHECK(dpi_fetch_scroll(hstmt, DSQL_FETCH_PRIOR, 0, &row_num), DSQL_HANDLE_STMT, hstmt);
    printf("move prior : 13\n");
    printf("c1 = %d, c2 = %s, c3 = %s, c4 = %f, ", c1, c2, c3, c4);
    printf("c5 = %d-%d-%d %d:%d:%d.%d\n",c5.year,c5.month,c5.day,c5.hour,c5.minute,c5.second,c5.fraction);
    printf("c6 = %s, c7 = %s\n",c6, c7);
    DPIRETURN_CHECK(dpi_fetch_scroll(hstmt, DSQL_FETCH_RELATIVE, 3, &row_num), DSQL_HANDLE_STMT, hstmt);
    printf("move relative 3: 16\n");
    printf("c1 = %d, c2 = %s, c3 = %s, c4 = %f, ", c1, c2, c3, c4);
    printf("c5 = %d-%d-%d %d:%d:%d.%d\n",c5.year,c5.month,c5.day,c5.hour,c5.minute,c5.second,c5.fraction);
    printf("c6 = %s, c7 = %s\n",c6, c7);
    printf("----------------------------------------------------------------------\n");
    /* 释放语句句柄 */
    DPIRETURN_CHECK(dpi_free_stmt(hstmt), DSQL_HANDLE_STMT, hstmt);
    return DSQL_SUCCESS;
}
/************************************************
    fetch获取结果集输出到数组
************************************************/
DPIRETURN
dm_select_with_fetch_array()
{
    sdint4		        c1[ROWS];             /* 与字段匹配的变量,用于获取字段值 */
    sdbyte		        c2[ROWS][20];
    sdbyte		        c3[ROWS][50];
    ddouble		        c4[ROWS];
    dpi_timestamp_t		c5[ROWS];
    sdbyte		        c6[ROWS][50];
    sdbyte		        c7[ROWS][FLEN];
    slength		        c1_ind[ROWS];     /* 缓冲区 */
    slength		        c2_ind[ROWS];
    slength		        c3_ind[ROWS];
    slength		        c4_ind[ROWS];
    slength		        c5_ind[ROWS];
    slength		        c6_ind[ROWS];
    slength		        c7_ind[ROWS];
    ulength		        row_num;        /* 行数 */
    ulength				i;
    ulength				i_array_rows = ROWS;
    /* 分配语句句柄 */
    DPIRETURN_CHECK(dpi_alloc_stmt(hcon, &hstmt), DSQL_HANDLE_STMT, hstmt);
    /* 设置语句句柄属性 */
    DPIRETURN_CHECK(dpi_set_stmt_attr(hstmt, DSQL_ATTR_ROWSET_SIZE, (dpointer)i_array_rows, sizeof(i_array_rows)), DSQL_HANDLE_STMT, hstmt);
    /* 执行sql */
    DPIRETURN_CHECK(dpi_exec_direct(hstmt, "select c1,c2,c3,c4,c5,c6,c7 from dpi_demo"), DSQL_HANDLE_STMT, hstmt);
    /* 绑定输出列 */
    DPIRETURN_CHECK(dpi_bind_col(hstmt, 1, DSQL_C_SLONG, &c1[0], sizeof(c1[0]), &c1_ind[0]), DSQL_HANDLE_STMT, hstmt);
    DPIRETURN_CHECK(dpi_bind_col(hstmt, 2, DSQL_C_NCHAR, &c2[0], sizeof(c2[0]), &c2_ind[0]), DSQL_HANDLE_STMT, hstmt);
    DPIRETURN_CHECK(dpi_bind_col(hstmt, 3, DSQL_C_NCHAR, &c3[0], sizeof(c3[0]), &c3_ind[0]), DSQL_HANDLE_STMT, hstmt);
    DPIRETURN_CHECK(dpi_bind_col(hstmt, 4, DSQL_C_DOUBLE, &c4[0], sizeof(c4[0]), &c4_ind[0]), DSQL_HANDLE_STMT, hstmt);
    DPIRETURN_CHECK(dpi_bind_col(hstmt, 5, DSQL_C_TIMESTAMP, &c5[0], sizeof(c5[0]), &c5_ind[0]), DSQL_HANDLE_STMT, hstmt);
    DPIRETURN_CHECK(dpi_bind_col(hstmt, 6, DSQL_C_NCHAR, &c6[0], sizeof(c6[0]), &c6_ind[0]), DSQL_HANDLE_STMT, hstmt);
    DPIRETURN_CHECK(dpi_bind_col(hstmt, 7, DSQL_C_NCHAR, &c7[0], sizeof(c7[0]), &c7_ind[0]), DSQL_HANDLE_STMT, hstmt);
    /* 打印输出信息 */
    printf("dm_select_with_fetch_array......\n");
    printf("----------------------------------------------------------------------\n");
    if (dpi_fetch(hstmt, &row_num) != DSQL_NO_DATA)
    {
        row_num = row_num > ROWS ? ROWS : row_num;
        for (i=0; i<row_num; i++)
        {
            printf("c1 = %d, c2 = %s, c3 = %s, c4 = %f, ", c1[i], c2[i], c3[i], c4[i]);
            printf("c5 = %d-%d-%d %d:%d:%d.%d\n",c5[i].year,c5[i].month,c5[i].day,c5[i].hour,c5[i].minute,c5[i].second,c5[i].fraction);
            printf("c6 = %s, c7 = %s\n",c6[i], c7[i]);
        }
    }
    else
    {
        printf("dm no data\n");
    }
    printf("----------------------------------------------------------------------\n");
    /* 释放语句句柄 */
    DPIRETURN_CHECK(dpi_free_stmt(hstmt), DSQL_HANDLE_STMT, hstmt);
    return DSQL_SUCCESS;
}

DPIRETURN
	dm_insert_select_complex_type_value()
	{
		dhobj           obj;          //复合对象句柄
		dhobjdesc       obj_desc;     //复合对象描述句柄
		udint4          cnt, cnt1;
		slength         len;
		sdint2          type, type1, type2;
		sdint2          prec, prec1, prec2;
		sdint2          scale, scale1, scale2;
		int             c1_data,c1_val;
		char            c2_data[21],c2_val[21];
		slength         val_len[2],data_len[2];
		/* 分配语句句柄 */
		DPIRETURN_CHECK(dpi_alloc_stmt(hcon, &hstmt), DSQL_HANDLE_STMT, hstmt);
		dpi_exec_direct(hstmt, "drop table t");
		dpi_exec_direct(hstmt, "drop class cls1");
		DPIRETURN_CHECK(dpi_exec_direct(hstmt, "create class cls1 as c1 int; c2 varchar(20); end;"),DSQL_HANDLE_STMT, hstmt);
		DPIRETURN_CHECK(dpi_exec_direct(hstmt, "create table t(c1 cls1)"),DSQL_HANDLE_STMT,hstmt);
		DPIRETURN_CHECK(dpi_desc_obj(hcon, "SYSDBA", "CLS1", &obj_desc),DSQL_HANDLE_DBC,hcon);
		DPIRETURN_CHECK(dpi_alloc_obj(hcon, &obj),DSQL_HANDLE_DBC,hcon);
		DPIRETURN_CHECK(dpi_bind_obj_desc(obj,obj_desc),DSQL_HANDLE_OBJECT,obj);
		//复合类型获取描述信息
		DPIRETURN_CHECK(dpi_get_obj_desc_attr(obj_desc, 0, DSQL_ATTR_OBJ_FIELD_COUNT, &cnt1, sizeof(cnt1), NULL),DSQL_HANDLE_OBJDESC,obj_desc);
		printf("cnt is : %d\n",cnt1);
		DPIRETURN_CHECK(dpi_get_obj_desc_attr(obj_desc, 1, DSQL_ATTR_OBJ_TYPE, &type1, sizeof(type1), NULL),DSQL_HANDLE_OBJDESC,obj_desc);
		printf("type1 is : %d\n",type1);
		if (type1!=DSQL_INT)
		{
			printf("type error");
		}
		DPIRETURN_CHECK(dpi_get_obj_desc_attr(obj_desc, 2, DSQL_ATTR_OBJ_TYPE, &type2, sizeof(type2), NULL),DSQL_HANDLE_OBJDESC,obj_desc);
		printf("type2 is : %d\n",type2);
		if (type1!=DSQL_VARCHAR)
		{
			printf("type error");
		}
		DPIRETURN_CHECK(dpi_get_obj_desc_attr(obj_desc, 1, DSQL_ATTR_OBJ_PREC, &prec1, sizeof(prec1), NULL),DSQL_HANDLE_OBJDESC,obj_desc);
		printf("prec1 is : %d\n",prec1);
		DPIRETURN_CHECK(dpi_get_obj_desc_attr(obj_desc, 2, DSQL_ATTR_OBJ_PREC, &prec2, sizeof(prec2), NULL),DSQL_HANDLE_OBJDESC,obj_desc);
		printf("prec1 is : %d\n",prec2);
		DPIRETURN_CHECK(dpi_get_obj_desc_attr(obj_desc, 1, DSQL_ATTR_OBJ_SCALE, &scale1, sizeof(scale1), NULL),DSQL_HANDLE_OBJDESC,obj_desc);
		printf("scale1 is : %d\n",scale1);
		DPIRETURN_CHECK(dpi_get_obj_desc_attr(obj_desc, 2, DSQL_ATTR_OBJ_SCALE, &scale2, sizeof(scale2), NULL),DSQL_HANDLE_OBJDESC,obj_desc);
		printf("scale2 is : %d\n",scale2);

		//复合类型插入
		c1_data=1;
		strcpy(c2_data,"aaa");
		data_len[0]=sizeof(c1_data);
		data_len[1]=strlen(c2_data);
		DPIRETURN_CHECK(dpi_set_obj_val(obj, 1, DSQL_C_SLONG, &c1_data, data_len[0]),DSQL_HANDLE_STMT,hstmt);
		DPIRETURN_CHECK(dpi_set_obj_val(obj, 2, DSQL_C_NCHAR, &c2_data, data_len[1]),DSQL_HANDLE_STMT,hstmt);
		/* 执行sql */
		DPIRETURN_CHECK(dpi_prepare(hstmt,"insert into t(c1) values(?)"), DSQL_HANDLE_STMT, hstmt);
		/* 绑定输出列 */
		len = sizeof(obj);
		DPIRETURN_CHECK(dpi_bind_param(hstmt, 1, DSQL_PARAM_INPUT, DSQL_C_CLASS, DSQL_CLASS, 0, 0, &obj, sizeof(obj), &len), DSQL_HANDLE_STMT, hstmt);
		DPIRETURN_CHECK(dpi_exec(hstmt),DSQL_HANDLE_STMT, hstmt);
		DPIRETURN_CHECK(dpi_commit(hcon),DSQL_HANDLE_DBC,hcon);
		//复合类型查询
		DPIRETURN_CHECK(dpi_exec_direct(hstmt, "select c1 from t"),DSQL_HANDLE_STMT,hstmt);
		DPIRETURN_CHECK(dpi_bind_col(hstmt, 1, DSQL_C_CLASS, &obj, sizeof(obj), &len),DSQL_HANDLE_STMT,hstmt);
		DPIRETURN_CHECK(dpi_fetch(hstmt, NULL),DSQL_HANDLE_STMT,hstmt);
		DPIRETURN_CHECK(dpi_get_obj_val(obj, 1, DSQL_C_SLONG, &c1_val, sizeof(c1_val), &val_len[0]),DSQL_HANDLE_STMT,hstmt);
		DPIRETURN_CHECK(dpi_get_obj_val(obj, 2, DSQL_C_NCHAR, c2_val, sizeof(c2_val), &val_len[1]),DSQL_HANDLE_STMT,hstmt);
		printf("c1_val=%d,c2_val=%s\n",c1_val,c2_val);
		if (c1_val!=c1_data||strcmp(c2_val,c2_data)!=0)
		{
			printf("dpi_get_obj_val获取结果 error");
		}
		printf("----------------------------------------------------------------------\n");
		/* 释放语句句柄 */
		DPIRETURN_CHECK(dpi_free_stmt(hstmt), DSQL_HANDLE_STMT, hstmt);
		return DSQL_SUCCESS;
	}
/**
 ** 入口函数
 */
DPIRETURN
main()
{
    //连接数据库
    rt = dm_dpi_connect(DM_SVR, DM_USER, DM_PWD);
    FUN_CHECK(rt);
    //初始化表
    rt = dm_init_table();
    FUN_CHECK(rt);
    //通过参数绑定的方式插入数据
    rt = dm_insert_with_bind_param();
    FUN_CHECK(rt);
    //通过数组绑定的方式插入数据
    rt = dm_insert_with_bind_array();
    FUN_CHECK(rt);
    //通过fetch查询得到结果集
    rt = dm_select_with_fetch();
    FUN_CHECK(rt);
    //通过参数绑定查询得到结果集
    rt = dm_select_with_fetch_with_param();
    FUN_CHECK(rt);
    //通过fetch scroll获取结果集
    rt = dm_select_with_fetch_scroll();
    FUN_CHECK(rt);
    //查询列绑定数组输出
    rt = dm_select_with_fetch_array();
    FUN_CHECK(rt);
   //复合类型插入查询描述信息获取示例
rt = dm_insert_select_complex_type_value();
FUN_CHECK(rt);
 //断开连接
    rt = dm_dpi_disconnect();
    FUN_CHECK(rt);
END:
    return DSQL_SUCCESS;
}

2.4.3 大字段操作

下面通过一个简单的Windows环境下的示例来说明DPI大字段操作。

创建一个表,读取文件插入到lob字段,从lob字段读取数据写入到文件,更新lob字段值,通过专用函数dpi_lob_read读取大字段数据,通过dpi_lob_truncate截取大字段。

##include "DPI.h"
##include "DPIext.h"
##include "DPItypes.h"
##include "stdio.h"
##include "stdlib.h"
##include "string.h"
/******************************************************
Notes:
定义相应常量
*******************************************************/
##define ROWS	10				//数组绑定一次插入和读取的行数
##define CHARS	80*1024		    //一次读取和写入的字节数800K
##define FLEN	500				//文件名长度(带地址路径)
##define DM_SVR  "192.168.0.120:5336"
##define DM_USER "SYSDBA"
##define DM_PWD  "SYSDBA"
##define IN_FILE     "d:\\drivers_win64+win32.zip"
##define UP_FILE     "d:\\drivers_rh6_64+rh6_32.zip"
/* 函数检查及错误信息显示 */
##define DPIRETURN_CHECK(rt, hndl_type, hndl) if(!DSQL_SUCCEEDED(rt)){dpi_err_msg_print(hndl_type, hndl);return rt;}
##define FUN_CHECK(rt) if(!DSQL_SUCCEEDED(rt)){goto END;}
/******************************************************
Notes:
定义常用句柄和变量
*******************************************************/
dhenv		henv;		/* 环境句柄 */
dhcon		hcon;		/* 连接句柄 */
dhstmt		hstmt;		/* 语句句柄 */
dhdesc      hdesc;      /* 描述符句柄 */
dhloblctr	hloblctr;	/* lob类型控制句柄 */
DPIRETURN   rt;         /* 函数返回值 */
/******************************************************
Notes:
    错误信息获取打印
Param:
	hndl_type:	句柄类型
	hndl:		句柄
Return:
	无
*******************************************************/
void
dpi_err_msg_print(sdint2 hndl_type, dhandle hndl)
{
	sdint4 err_code;
	sdint2 msg_len;
	sdbyte err_msg[SDBYTE_MAX];
    /* 获取错误信息字段 */
/*	dpi_get_diag_field(hndl_type, hndl, 1, DSQL_DIAG_MESSAGE_TEXT, err_msg, sizeof(err_msg), NULL);
	printf("err_msg = %s\n", err_msg);*/
    /* 获取错误信息集合 */
	dpi_get_diag_rec(hndl_type, hndl, 1, &err_code, err_msg, sizeof(err_msg), &msg_len);
	printf("err_msg = %s, err_code = %d\n", err_msg, err_code);
}
/******************************************************
Notes:
    连接数据库
Param:
    server:	服务器IP
    uid:	数据库登录账号
    pwd:	数据库登录密码
Return:
    DSQL_SUCCESS 执行成功
    DSQL_ERROR   执行失败
*******************************************************/
DPIRETURN 
dm_dpi_connect(sdbyte* server,  sdbyte* uid, sdbyte* pwd)
{
    /* 申请环境句柄 */
    rt = dpi_alloc_env(&henv);
    DPIRETURN_CHECK(rt, DSQL_HANDLE_ENV, henv);
    /* 申请连接句柄 */
    rt = dpi_alloc_con(henv, &hcon);
    DPIRETURN_CHECK(rt, DSQL_HANDLE_DBC, hcon);
    /* 连接数据库服务器 */
    rt = dpi_login(hcon, server, uid, pwd);
    DPIRETURN_CHECK(rt, DSQL_HANDLE_DBC, hcon);
    return DSQL_SUCCESS;
}
/************************************************
    断开数据库连接
************************************************/
DPIRETURN
dm_dpi_disconnect()
{
    /* 断开连接 */
    rt = dpi_logout(hcon);
    DPIRETURN_CHECK(rt, DSQL_HANDLE_DBC, hcon);
    /* 释放连接句柄和环境句柄 */
    rt = dpi_free_con(hcon);
    DPIRETURN_CHECK(rt, DSQL_HANDLE_DBC, hcon);
    rt = dpi_free_env(henv);
    DPIRETURN_CHECK(rt, DSQL_HANDLE_ENV, henv);
  
    return DSQL_SUCCESS;
}
/************************************************
    初始化表
************************************************/
DPIRETURN 
dm_init_table()
{
    /* 申请语句句柄 */
    rt = dpi_alloc_stmt(hcon, &hstmt);
    DPIRETURN_CHECK(rt, DSQL_HANDLE_DBC, hcon);
	/* 执行sql */
	dpi_exec_direct(hstmt, "drop table dpi_demo");
    rt = dpi_exec_direct(hstmt, "create table dpi_demo(c1 int, c2 char(20), c3 varchar(50), c4 numeric(7,3), c5 timestamp(5), c6 clob, c7 blob)");
    DPIRETURN_CHECK(rt, DSQL_HANDLE_STMT, hstmt);
    /* 释放语句句柄 */
    rt = dpi_free_stmt(hstmt);
    DPIRETURN_CHECK(rt, DSQL_HANDLE_STMT, hstmt);
    printf("dm init table success\n");
    return DSQL_SUCCESS;
}
/************************************************
    从带地址路径的文件名中获取不带路径的文件名
************************************************/
sdbyte*
dm_get_file_name(char* fdirname)
{
	char* fname;
    fname = (char*)malloc(FLEN);
	while(1)
	{
		fdirname = strchr(fdirname+1,'\\');
		if (fdirname == NULL)
		{
            break;
		}
		memcpy(fname, fdirname + 1, FLEN);
    }
    return fname;
}
/************************************************
    读取文件数据写入到lob字段
************************************************/
DPIRETURN
dm_read_file_to_put_data(char* fname)
{
    FILE*	    pfile = NULL;
    sdbyte	    tmpbuf[CHARS];
    slength	    rlen = 0;
    slength	    len	 = 0;
    /* 打开文件 */
    pfile = fopen(fname, "rb");
    if (pfile == NULL)
    {
        printf("open %s fail\n", fname);
        return DSQL_ERROR;
    }
    /* 读取文件数据写入到缓冲区 */
    printf("==========Begin write==========\n");
    while (!feof(pfile))
    {
        len = fread(tmpbuf, sizeof(char), CHARS, pfile);
        if (len <= 0)
        {
            return DSQL_ERROR;
        }
        DPIRETURN_CHECK(dpi_put_data(hstmt, tmpbuf, len), DSQL_HANDLE_STMT, hstmt);
        rlen += len;
        printf("write %u bytes\n", rlen);
    }
    printf("==========End   write==========\n");
    fclose(pfile);
    return DSQL_SUCCESS;
}
/************************************************
    读取数据写入到文件
************************************************/
DPIRETURN
dm_write_file_from_get_data(char* fname)
{
    FILE*		pfile = NULL;
    sdbyte		tmpbuf[CHARS];
    slength		val_len;
    slength		wlen = 0;
    slength		len	 = 0;
    /* 打开文件 */
    pfile = fopen(fname, "wb");
    if (pfile == NULL)
    {
        printf("open %s fail\n", fname);
        return DSQL_ERROR;
    }
    /* 读取数据写入到文件 */
    printf("==========Begin read==========\n");
    while(DSQL_SUCCEEDED(dpi_get_data(hstmt, 7, DSQL_C_BINARY, tmpbuf, CHARS, &val_len)))
    {
        len = val_len > CHARS ? CHARS : val_len;
        fwrite(tmpbuf, sizeof(char), len, pfile);
        wlen += len;
        printf("read %u bytes\n", wlen);
    }
    printf("==========End   read==========\n");
    fclose(pfile);
    return DSQL_SUCCESS;
}
/************************************************
    读取文件插入到blob字段
************************************************/
DPIRETURN
dm_insert_with_file()
{
	sdint4			c1;             /* 定义字段相应的变量 */
	sdbyte			c2[10];
	sdbyte			c3[10];
	ddouble			c4;
	dpi_timestamp_t c5;
	sdbyte			c6[FLEN];
	sdint4			c7;
    slength			c2_ind_ptr;	    /* 缓冲区长度 */
    slength			c3_ind_ptr;
    slength			c6_ind_ptr;
	slength			c7_ind_ptr = DSQL_DATA_AT_EXEC;
	dpointer		c7_val_ptr;

	/* 分配语句句柄 */
	DPIRETURN_CHECK(dpi_alloc_stmt(hcon, &hstmt), DSQL_HANDLE_STMT, hstmt);
	/* 准备sql */
	DPIRETURN_CHECK(dpi_prepare(hstmt, "insert into dpi_demo(c1,c2,c3,c4,c5,c6,c7) values(?,?,?,?,?,?,?)"), DSQL_HANDLE_STMT, hstmt);
	/* 赋值 */
	c1			= 1;
	memcpy(c2, "abcde", 10);
	memcpy(c3, "abcdefghi", 10);
	c4			= 1000.001;
	c5.year		= 2011;
	c5.month	= 3;
	c5.day		= 1;
	c5.hour		= 11;
	c5.minute	= 45;
	c5.second	= 50;
	c5.fraction	= 900000000;
	memcpy(c6, dm_get_file_name(IN_FILE), FLEN);
	c7			= DSQL_DATA_AT_EXEC;
	c2_ind_ptr = sizeof(c2);	/* 获取缓冲区长度 */
	c3_ind_ptr = sizeof(c3);
	c6_ind_ptr = sizeof(c6);
	/* 绑定参数 */
	DPIRETURN_CHECK(dpi_bind_param(hstmt, 1, DSQL_PARAM_INPUT, DSQL_C_SLONG, DSQL_INT, sizeof(c1), 0, &c1, sizeof(c1), NULL), DSQL_HANDLE_STMT, hstmt);
	DPIRETURN_CHECK(dpi_bind_param(hstmt, 2, DSQL_PARAM_INPUT, DSQL_C_NCHAR, DSQL_CHAR, sizeof(c2), 0, &c2, sizeof(c2), &c2_ind_ptr), DSQL_HANDLE_STMT, hstmt);
	DPIRETURN_CHECK(dpi_bind_param(hstmt, 3, DSQL_PARAM_INPUT, DSQL_C_NCHAR, DSQL_VARCHAR, sizeof(c3), 0, &c3, sizeof(c3), &c3_ind_ptr), DSQL_HANDLE_STMT, hstmt);
	DPIRETURN_CHECK(dpi_bind_param(hstmt, 4, DSQL_PARAM_INPUT, DSQL_C_DOUBLE, DSQL_DOUBLE, sizeof(c4), 0, &c4, sizeof(c4), NULL), DSQL_HANDLE_STMT, hstmt);
	DPIRETURN_CHECK(dpi_bind_param(hstmt, 5, DSQL_PARAM_INPUT, DSQL_C_TIMESTAMP, DSQL_TIMESTAMP, sizeof(c5), 0, &c5, sizeof(c5), NULL), DSQL_HANDLE_STMT, hstmt);
	DPIRETURN_CHECK(dpi_bind_param(hstmt, 6, DSQL_PARAM_INPUT, DSQL_C_NCHAR, DSQL_CLOB, sizeof(c6), 0, &c6, sizeof(c6), &c6_ind_ptr), DSQL_HANDLE_STMT, hstmt);
	DPIRETURN_CHECK(dpi_bind_param(hstmt, 7, DSQL_PARAM_INPUT, DSQL_C_BINARY, DSQL_BLOB, sizeof(c7), 0, &c7, sizeof(c7), &c7_ind_ptr), DSQL_HANDLE_STMT, hstmt);
	/* 执行sql */
	if (dpi_exec(hstmt) == DSQL_NEED_DATA)
	{
		if (dpi_param_data(hstmt, &c7_val_ptr) == DSQL_NEED_DATA)   /* 绑定数据 */
		{
			if (!DSQL_SUCCEEDED(dm_read_file_to_put_data(IN_FILE))) return DSQL_ERROR;  /* 读取文件数据存入到字段 */
		}
		DPIRETURN_CHECK(dpi_param_data(hstmt, &c7_val_ptr), DSQL_HANDLE_STMT, hstmt); /* 绑定数据 */
	}
	/* 释放语句句柄 */
	DPIRETURN_CHECK(dpi_free_stmt(hstmt), DSQL_HANDLE_STMT, hstmt);
    printf("dm insert with file success\n");
	return DSQL_SUCCESS;
}
/************************************************
    查询,并将blob字段中插入的文件写入到新的文件中
************************************************/
DPIRETURN
dm_select_with_file()
{
    sdint4		        c1 = 0;             /* 与字段匹配的变量,用于获取字段值 */
    sdbyte		        c2[20];
    sdbyte		        c3[50];
    ddouble		        c4;
    dpi_timestamp_t		c5;
    sdbyte		        c6[50];
    sdbyte		        c7[FLEN];
    slength		        c1_ind = 0;     /* 缓冲区 */
    slength		        c2_ind = 0;
    slength		        c3_ind = 0;
    slength		        c4_ind = 0;
    slength		        c5_ind = 0;
    slength		        c6_ind = 0;
    slength		        c7_ind = 0;
    ulength		        row_num;        /* 行数 */
    ulength				rows = 1;
    sdint4              dataflag = 0;
    /* 分配语句句柄 */
    DPIRETURN_CHECK(dpi_alloc_stmt(hcon, &hstmt), DSQL_HANDLE_STMT, hstmt);
    DPIRETURN_CHECK(dpi_exec_direct(hstmt, "select c1,c2,c3,c4,c5,c6,c7 from dpi_demo"), DSQL_HANDLE_STMT, hstmt);
    DPIRETURN_CHECK(dpi_bind_col(hstmt, 1, DSQL_C_SLONG, &c1, sizeof(c1), &c1_ind), DSQL_HANDLE_STMT, hstmt);
    DPIRETURN_CHECK(dpi_bind_col(hstmt, 2, DSQL_C_NCHAR, &c2, sizeof(c2), &c2_ind), DSQL_HANDLE_STMT, hstmt);
    DPIRETURN_CHECK(dpi_bind_col(hstmt, 3, DSQL_C_NCHAR, &c3, sizeof(c3), &c3_ind), DSQL_HANDLE_STMT, hstmt);
    DPIRETURN_CHECK(dpi_bind_col(hstmt, 4, DSQL_C_DOUBLE, &c4, sizeof(c4), &c4_ind), DSQL_HANDLE_STMT, hstmt);
    DPIRETURN_CHECK(dpi_bind_col(hstmt, 5, DSQL_C_TIMESTAMP, &c5, sizeof(c5), &c5_ind), DSQL_HANDLE_STMT, hstmt);
    DPIRETURN_CHECK(dpi_bind_col(hstmt, 6, DSQL_C_NCHAR, &c6, sizeof(c6), &c6_ind), DSQL_HANDLE_STMT, hstmt);
    while(dpi_fetch(hstmt, &row_num) != DSQL_NO_DATA)
    {
        printf("c1 = %d, c2 = %s, c3 = %s, c4 = %f, ", c1, c2, c3, c4);
        printf("c5 = %d-%d-%d %d:%d:%d.%d\n",c5.year,c5.month,c5.day,c5.hour,c5.minute,c5.second,c5.fraction);
        printf("c6 = %s\n",c6);
        sprintf(c7, "F:\\%d_%s", rows, c6);
        printf("c7 write to %s\n",c7);
        if (!DSQL_SUCCEEDED(dm_write_file_from_get_data(c7))) return DSQL_ERROR;    /* 获取数据写入到文件 */
        rows++;
        dataflag = 1;
    }
    if (!dataflag)
    {
        printf("dm no data\n");
    }
    /* 释放语句句柄 */
    DPIRETURN_CHECK(dpi_free_stmt(hstmt), DSQL_HANDLE_STMT, hstmt);
    return DSQL_SUCCESS;
}
/************************************************
    截断lob句柄所对应的大字段到指定的长度
************************************************/
DPIRETURN
dm_blob_truncate_data(
                   )
{
    slength		    c1_ind = 0;
    slength         trun_len;
    ulength         row_num;        /* 行数 */
    rt = dpi_alloc_stmt(hcon, &hstmt);
    DPIRETURN_CHECK(rt, DSQL_HANDLE_DBC, hcon);
    rt = dpi_alloc_lob_locator(hstmt, &hloblctr);
    DPIRETURN_CHECK(rt, DSQL_HANDLE_LOB_LOCATOR, hloblctr);
    rt = dpi_exec_direct(hstmt, "select c7 from dpi_demo");
    DPIRETURN_CHECK(rt, DSQL_HANDLE_STMT, hstmt);
    rt = dpi_bind_col(hstmt, 1, DSQL_C_LOB_HANDLE, &hloblctr, sizeof(hloblctr), &c1_ind);
    DPIRETURN_CHECK(rt, DSQL_HANDLE_STMT, hstmt);
    while(dpi_fetch(hstmt, &row_num) != DSQL_NO_DATA)
    {
        printf("%d\n", CHARS);
        rt = dpi_lob_truncate(hloblctr, CHARS, &trun_len);
        printf("%d\n", trun_len);
        FUN_CHECK(rt);
    }
END:  
    rt = dpi_free_lob_locator(hloblctr);
    DPIRETURN_CHECK(rt, DSQL_HANDLE_LOB_LOCATOR, hloblctr);
  
    /* 释放语句句柄 */
    rt = dpi_free_stmt(hstmt);
    DPIRETURN_CHECK(rt, DSQL_HANDLE_STMT, hstmt);
    printf("dm_blob_truncate_data success\n");
    return DSQL_SUCCESS;
}
/************************************************
    lob_read
************************************************/
DPIRETURN
dm_lob_read(char* fname)
{
    FILE*		pfile = NULL;
    sdbyte		tmpbuf[CHARS];
    slength		val_len;
    slength		wlen = 0;
    slength     len, rlen;
    ulength     pos;
    /* 打开文件 */
    pfile = fopen(fname, "wb");
    if (pfile == NULL)
    {
        printf("open %s fail\n", fname);
        return DSQL_ERROR;
    }
    //获取大字段长度
    rt = dpi_lob_get_length(hloblctr, &len);
    DPIRETURN_CHECK(rt, DSQL_HANDLE_LOB_LOCATOR, hloblctr);
    /* 读取数据写入到文件 */
    printf("==========Begin read==========\n");
    while(len > 0)
    {
        pos = wlen+1;
        rlen = (len > CHARS) ? CHARS : len;
        rt = dpi_lob_read(hloblctr, pos, DSQL_C_BINARY, rlen, tmpbuf, sizeof(tmpbuf), &val_len);
        fwrite(tmpbuf, sizeof(char), val_len, pfile);
        wlen += val_len;
        printf("read %u bytes\n", wlen);
        len = len - CHARS;
    }
    printf("==========End   read==========\n");
    fclose(pfile);
    return DSQL_SUCCESS;
}
/************************************************
    读取lob句柄所对应大字段的实际数据
************************************************/
DPIRETURN
dm_lob_read_to_file()
{
    sdint4		        c1 = 0;             /* 与字段匹配的变量,用于获取字段值 */
    sdbyte		        c2[20];
    sdbyte		        c3[50];
    ddouble		        c4;
    dpi_timestamp_t		c5;
    sdbyte		        c6[50];
    sdbyte		        c7[FLEN];
    slength		        c1_ind = 0;     /* 缓冲区 */
    slength		        c2_ind = 0;
    slength		        c3_ind = 0;
    slength		        c4_ind = 0;
    slength		        c5_ind = 0;
    slength		        c6_ind = 0;
    slength		        c7_ind = 0;
    ulength		        row_num;        /* 行数 */
    ulength				rows = 1;
    sdint4              dataflag = 0;
    /* 分配语句句柄 */
    DPIRETURN_CHECK(dpi_alloc_stmt(hcon, &hstmt), DSQL_HANDLE_STMT, hstmt);
    DPIRETURN_CHECK(dpi_alloc_lob_locator(hstmt, &hloblctr), DSQL_HANDLE_LOB_LOCATOR, hloblctr);
    DPIRETURN_CHECK(dpi_exec_direct(hstmt, "select c1,c2,c3,c4,c5,c6,c7 from dpi_demo"), DSQL_HANDLE_STMT, hstmt);
    DPIRETURN_CHECK(dpi_bind_col(hstmt, 1, DSQL_C_SLONG, &c1, sizeof(c1), &c1_ind), DSQL_HANDLE_STMT, hstmt);
    DPIRETURN_CHECK(dpi_bind_col(hstmt, 2, DSQL_C_NCHAR, &c2, sizeof(c2), &c2_ind), DSQL_HANDLE_STMT, hstmt);
    DPIRETURN_CHECK(dpi_bind_col(hstmt, 3, DSQL_C_NCHAR, &c3, sizeof(c3), &c3_ind), DSQL_HANDLE_STMT, hstmt);
    DPIRETURN_CHECK(dpi_bind_col(hstmt, 4, DSQL_C_DOUBLE, &c4, sizeof(c4), &c4_ind), DSQL_HANDLE_STMT, hstmt);
    DPIRETURN_CHECK(dpi_bind_col(hstmt, 5, DSQL_C_TIMESTAMP, &c5, sizeof(c5), &c5_ind), DSQL_HANDLE_STMT, hstmt);
    DPIRETURN_CHECK(dpi_bind_col(hstmt, 6, DSQL_C_NCHAR, &c6, sizeof(c6), &c6_ind), DSQL_HANDLE_STMT, hstmt);
    DPIRETURN_CHECK(dpi_bind_col(hstmt, 7, DSQL_C_LOB_HANDLE, &hloblctr, sizeof(hloblctr), &c7_ind), DSQL_HANDLE_STMT, hstmt);
    while(dpi_fetch(hstmt, &row_num) != DSQL_NO_DATA)
    {
        printf("c1 = %d, c2 = %s, c3 = %s, c4 = %f, ", c1, c2, c3, c4);
        printf("c5 = %d-%d-%d %d:%d:%d.%d\n",c5.year,c5.month,c5.day,c5.hour,c5.minute,c5.second,c5.fraction);
        printf("c6 = %s\n",c6);
        sprintf(c7, "F:\\%d_%s", rows, c6);
        printf("c7 write to %s\n",c7);
        if (!DSQL_SUCCEEDED(dm_lob_read(c7))) return DSQL_ERROR;    /* 获取数据写入到文件 */
        rows++;
        dataflag = 1;
    }
    if (!dataflag)
    {
        printf("dm no data\n");
    }
    /* 释放语句句柄 */
    DPIRETURN_CHECK(dpi_free_lob_locator(hloblctr), DSQL_HANDLE_LOB_LOCATOR, hloblctr);
    DPIRETURN_CHECK(dpi_free_stmt(hstmt), DSQL_HANDLE_STMT, hstmt);
    return DSQL_SUCCESS;
}
/************************************************
    lob_read
************************************************/
DPIRETURN
dm_lob_write(char* fname)
{
    FILE*	    pfile = NULL;
    sdbyte	    tmpbuf[CHARS];
    slength	    rlen = 0;
    slength	    len	 = 0;
    slength	    wlen;
    ulength     pos;
    /* 打开文件 */
    pfile = fopen(fname, "rb");
    if (pfile == NULL)
    {
        printf("open %s fail\n", fname);
        return DSQL_ERROR;
    }
    /* 读取文件数据写入到缓冲区 */
    printf("==========Begin write==========\n");
    while (!feof(pfile))
    {
        len = fread(tmpbuf, sizeof(char), CHARS, pfile);
        if (len <= 0)
        {
            return DSQL_ERROR;
        }
        pos = rlen+1;
        //DPIRETURN_CHECK(dpi_lob_write(hloblctr, pos, DSQL_C_BINARY, tmpbuf, len, &wlen), DSQL_HANDLE_LOB_LOCATOR, hloblctr);
		rt = dpi_lob_write(hloblctr, pos, DSQL_C_BINARY, tmpbuf, len, &wlen);
		if(!DSQL_SUCCEEDED(rt))
		{
			dpi_err_msg_print(DSQL_HANDLE_LOB_LOCATOR, hloblctr);
			return rt;
		}

        rlen += len;
        printf("write %u bytes\n", rlen);
    }
    printf("==========End   write==========\n");
    fclose(pfile);
    return DSQL_SUCCESS;
}
/************************************************
    读取文件更新到lob字段
************************************************/
DPIRETURN
dm_lob_write_to_update()
{  
    slength		        c1_ind = 0;     /* 缓冲区 */
    ulength		        row_num;        /* 行数 */
    ulength				rows = 1;
    sdint4              dataflag = 0;
    /* 分配语句句柄 */
    DPIRETURN_CHECK(dpi_alloc_stmt(hcon, &hstmt), DSQL_HANDLE_STMT, hstmt);
    DPIRETURN_CHECK(dpi_alloc_lob_locator(hstmt, &hloblctr), DSQL_HANDLE_LOB_LOCATOR, hloblctr);
    DPIRETURN_CHECK(dpi_exec_direct(hstmt, "select c7 from dpi_demo"), DSQL_HANDLE_STMT, hstmt);
    DPIRETURN_CHECK(dpi_bind_col(hstmt, 1, DSQL_C_LOB_HANDLE, &hloblctr, sizeof(hloblctr), &c1_ind), DSQL_HANDLE_STMT, hstmt);
    while(dpi_fetch(hstmt, &row_num) != DSQL_NO_DATA)
    {
     printf("%s update to c7\n",UP_FILE);
     if (!DSQL_SUCCEEDED(dm_lob_write(UP_FILE))) return DSQL_ERROR;    /* 获取数据写入到文件 */
     rows++;
     dataflag = 1;
    }
    if (!dataflag)
    {
        printf("dm no data\n");
    }
    /* 释放语句句柄 */
    DPIRETURN_CHECK(dpi_free_lob_locator(hloblctr), DSQL_HANDLE_LOB_LOCATOR, hloblctr);
    DPIRETURN_CHECK(dpi_free_stmt(hstmt), DSQL_HANDLE_STMT, hstmt);
    return DSQL_SUCCESS;
}
/**
 ** 入口函数
 */
DPIRETURN
main()
{
    //连接数据
    rt = dm_dpi_connect(DM_SVR, DM_USER, DM_PWD);
    FUN_CHECK(rt);
    //初始化表
    rt = dm_init_table();
    FUN_CHECK(rt);
    //读取文件插入到lob字段(通过dpi_put_data函数写数据)
    rt = dm_insert_with_file();
    FUN_CHECK(rt);
    //从lob字段读取数据写入文件(通过dpi_get_data获取数据)
    rt = dm_select_with_file();
    FUN_CHECK(rt);

	//更新大字段(通过dpi_lob_write更新大字段数据)
    rt = dm_lob_write_to_update();
    FUN_CHECK(rt);
	//获取大字段值(通过dpi_lob_read读取大字段数据)
    rt = dm_lob_read_to_file();
    FUN_CHECK(rt);
	//截取大字段数据
    rt = dm_blob_truncate_data();
    FUN_CHECK(rt);
    //断开连接
    rt = dm_dpi_disconnect();
    FUN_CHECK(rt);
END:
    return  rt;
}

2.5 数据捕获

数据捕获,用于捕获数据库中的表和视图的数据变化。用户根据应用的要求可以定制,用户可以监控表或视图的全部列,也可以监控表或视图的部分列,亦可以监控符合特定条件的列。另外,增强其可读性,在存储捕获的列的信息的时候,可以对这些列执行表达式操作,如把binary存储成字符串。

主要功能介绍如下:

  1. 支持对表的数据捕获
  • 支持对DM所有数据类型的捕获;
  • 能够捕获指定的表的数据变化;
  • 能够指定只捕获表中某些字段的数据变化;
  • 能够捕获符合一定WHERE条件的数据变化(包括原来不符合条件,经修改后变成符合条件的记录;原来符合条件,经修改后变成不符合条件的记录);
  • 能够对捕获的字段进行计算或者函数转换,最终提供的是计算或转换后的值(视图不支持);
  • 能够给出变化数据记录的主键值(有主键时)或ROWID值;
  1. 支持对视图的数据捕获
  • 能够捕获指定的视图的数据变化;
  • 视图的来源能够支持同一用户下多表联合,不同用户下多表联合;
  • 支持除了大字段以外的,所有DM数据类型的捕获;

2.5.1 数据类型

  1. cpt_col_def_struct

定义:

STRUCT cpt_col_def_struct
{
SDBYTE name[129];
SDBYTE col_define[129];
SDBYTE expr[1024];
};
typedef struct cpt_col_def_struct cpt_col_def_t;

功能说明:

指定捕获的字段转成其他的类型进行存储,计算expr的值,并存储成col_define的类型。

参数说明:

name:字段名称,必须与捕获对象字段一致。

col_define:字段类型,该类型只有在表达式不为空时指定才有效,在指定col_define时,要指定完整的定义,如int,varchar(200),numeric(10,2)。视图指定计算表达式时,该参数无效。

expr:字段表达式,如果为空串,则不做计算。视图指定表达时,允许用户指定各种表达式,如C1+1,或者 cast计算函数等。

  1. cpt_error_info_struct

定义:

struct cpt_error_info_struct

{

sdint4 error_no;

sdbyte error_info[DM_MAX_CPT_ERROR_INFO_LEN];

};

typedef struct cpt_error_info_struct cpt_error_info_t;

功能说明:

指定错误码。

参数说明:

error_no:发生错误返回的code码。

error_info:发生错误返回的信息。

2.5.2 相关方法

  1. dm_create_change_data_capture

定义:

DMBOOL  DM_CREATE_CHANGE_DATA_CAPTURE(
##IF CPT_WITH_API
DHCON		CON_HDBC,
##ELSE
VOID *PIDAO_CONNECTION,   
##ENDIF   
SDBYTE*		SCHNAME,
SDBYTE*		TVNAME,
SDBYTE*		WHERES,
CPT_COL_DEF_T*	COL_DEFS,	   
UDINT2		N_COLS,
SDBYTE*		CDC_ID,
UDINT4		CDC_ID_LEN,
SDBYTE*		CDC_BLOB_ID,
UDINT4		CDC_BLOB_ID_LEN,
CPT_ERROR_INFO_T* ERROR_INFO
);

功能说明:

打开数据捕获的DPI接口。

参数说明:

con_hdbc:输入参数,数据库连接句柄。

pidao_connection:输入参数,IDAO_Connection接口指针。

schname:输入参数,捕获对象所属模式,不允许使用带有下划线的模式名,否则会出现错误。

tvname:输入参数,捕获表/视图名。

wheres:输入参数,捕获条件,条件中需明确指定新值或旧值作为条件,若没有条件,则设为空串” ”。如何使用where条件?视图捕获,允许指定where条件,但是不允许指定新值旧值的指定,视图中没有没有这些概念。举例如下:

例1:监控C1列中,为20的数据变化(新值或者旧值为20);
where 为:’C1 = 20’;
例2:监控C2列中,大于20同时小于60的值(新值旧值在区间(20,60));
where 为:’C2 > 20 and C2 < 60’ ;
例3:监控C1列中,旧值\>100的数据变化并且C2 为零的数据变化;
where 为:’OLD.C1 > 100 and C2 = 0’;

col_defs:输入参数,字段描述。

n_cols:输入参数,捕获字段数。n_cols和col_defs必须一致,否则可能发生不可预知的错误

cdc_id:输出参数,捕获请求标识,对应变化表名。

cdc_id_len:输入参数,标识缓冲区长度,建议需大于等于129。

cdc_blob_id:输出参数,捕获请求标识,对应变化大字段表表名。

cdc_blob_id_len:输入参数,大字段标识缓冲区长度,建议需大于等于129。

error_info:输出参数,操作产生错误的原因。

  1. dm_drop_change_data_capture

定义:

DMBOOL  DM_DROP_CHANGE_DATA_CAPTURE(
##IF CPT_WITH_API
DHCON		CON_HDBC,
##ELSE
VOID *  PIDAO_CONNECTION,
##ENDIF
SDBYTE*		CDC_ID,
CPT_ERROR_INFO_T*  ERROR_INFO
);

功能说明:

关闭数据捕获的DPI接口。

参数说明:

con_hdbc:输入参数,数据库连接句柄;

pidao_connection:输入参数,IDAO_Connection接口指针;

cdc_id: 输入参数,捕获表的名字,该表用于记录捕获的数据;

error_info:输出参数,发生错误返回的错误信息。

  1. DM_CPT_SET_LOCAL_CODE

定义:

VOID DM_CPT_SET_LOCAL_CODE(
		sdint4		 code_id,
		sdint4 		 lang_id
);

功能说明:

修改数据捕获的语言信息。

参数说明:

CODE_ID:输入参数,编码类型,暂时无效;

LANG_ID:输入参数,语言类型,0表示中文,1表示英文。

2.5.3 数据信息搜集表

针对每个请求对象T(表或者视图),创建一个对应的数据捕获表CDC_T_ID,如果T的捕获字段包含大字段,还需要建立捕获从表CDC_BLOB_T_ID。

(1) CDC_T_ID

定义:

CREATE TABLE CDC_T_ID (
	OP_SEQ	 		BIGINT,
	OP_ROWID 		BINARY(8),
	OPTYPE 			CHAR(1),
	HAS_BLOB 		CHAR(1),
	OP_time		 	TIMESTAMP,
	T表的主键值或ROW_ID BINARY(8),
	…
	OP_ERROR 		VARchar(250)
);

参数说明:

OP_SEQ:操作顺序;

OP_ROWID:不管有没有主键值,都把rowid添加上;

OP_TYPE:操作类型:'I'/'D'/'U'/'T'/'F'/'D'/'A',分别表示:

I: 插入一条符合条件的记录;

U: 更新一条符合条件的记录为符合条件的记录;

T: 更新一条不符合条件的记录为符合条件的记录;

F: 更新一条符合条件的记录为不符合条件的记录;

D: 删除一条符合条件的记录;

A: 数据采集表被修改

HAS_BLOB:是否有大字段:'Y'/'N'。

OP_TIME:修改的时间;

T表的主键值或ROW_ID:显示表的主键值,如果没有主键则显示ROW_ID。

OP_ERROR:错误码

…:表示监控的字段;比如监控C1,C2。则为C1,C2的定义,如:

C1 INT,
C2 VARCHAR(20);

(2) CDC_ BLOB_T_ID

定义:

CREATE TABLE CDC_T_BLOB_ID(
	OP_ROWID		BINARY(8),
	COL_NAME		VARCHAR(128),
	OP_TIME			TIMESTAMP,
	T表的主键值或ROWID$		BIGINT
);

参数说明:

OP_SEQ :操作顺序;

OP_ROWID:不管有没有主键值,都把rowid添加上;

COL_NAME:大字段名;

OP_TIME:修改的时间;

T表的主键值或ROWID$:显示表的主键值,如果没有主键则显示rowid。

2.5.4 举例说明

第一步,初始化数据捕获环境。

SP_INIT_CPT_SYS(1) ;

第二步,创建要监控的表对象T1。

create table t1(c1 int,c2 blob, c3 CHAR(10),c4 SMALLINT,primary key(c1));
insert into t1 values(1, 'a' , 'aB', 11);
commit;

第三步,在具体代码中调用DPI接口。通过调用数据捕获DPI接口,指定对具体对象、具体列的监控。

下面编写一段代码,通过调用数据捕获DPI接口,来实现对表T1中,所有列的监控。

##include "DPIext.h"
##include "DPI.h"
##include "DPItypes.h"
##include "dmcpt_dll.h"

dhenv	henv;		/*环境句柄*/
dhcon	hdbc;		/*连接句柄*/

dhcon get_hdbc(dhcon hdbc,dhenv	henv)
{
	/*创建DPI运行环境*/
	//dpi_init();
	/*申请一个环境句柄*/
	dpi_alloc_env(&henv);
	/*申请一个连接句柄*/
	dpi_alloc_con(henv,&hdbc);
	/*设置连接端口*/
	dpi_set_con_attr(hdbc, DSQL_ATTR_LOGIN_PORT, 5236, 0);
	/*连接到本地服务器*/
	if (!DSQL_SUCCEEDED(dpi_login(hdbc,"192.168.0.38","SYSDBA","SYSDBA")))
	{
		printf("connect failed!\n");
        		/*释放连接句柄*/
        dpi_free_con(hdbc);
        /*释放环境句柄*/
        dpi_free_env(henv);
		exit(-1);
	}
	return hdbc;
}
void free_hdbc(dhcon hdbc,dhenv	henv)
{
	/*断开与数据源之间的连接*/
	dpi_logout(hdbc);
	/*释放连接句柄*/
	dpi_free_con(hdbc);
	/*释放环境句柄*/
	dpi_free_env(henv);
	}

void test_cptview_case1()
{
	cpt_col_def_t* col_def;
	cpt_col_def_t* temp;
	char cdc_id[130] = "NULL";
	char cdc_blob_id[130]="NULL";
	cpt_error_info_t    ei;
	col_def=(cpt_col_def_t*)malloc(sizeof(cpt_col_def_t)*4);
	strcpy(col_def->name,"c1");
	strcpy(col_def->col_define,"");
	strcpy(col_def->expr,"");

	temp = col_def + 1;
	strcpy(temp->name,"c2");
	strcpy(temp->col_define,"");
	strcpy(temp->expr,"");

	temp = temp + 1;
	strcpy(temp->name,"c3");
	strcpy(temp->col_define,"");
	strcpy(temp->expr,"");

	temp =  temp + 1;
	strcpy(temp->name,"c4");
	strcpy(temp->col_define,"");
	strcpy(temp->expr,"");

	hdbc=get_hdbc(hdbc, henv);  
	dm_create_change_data_capture(hdbc,"SYSDBA","T1","",col_def,4,cdc_id,130,cdc_blob_id,130, &ei);
	printf("cdc_id:%s\n",cdc_id);
	printf("cdc_blob_id:%s\n",cdc_blob_id);
	printf("%s\n",ei.error_info);
	//可以在此改变表中的数据,
	//手动在客户端查询打印出的cdc_id和cdc_blob_id表名,监控开启捕获后,T1表中数据的变化。
	//dm_drop_change_data_capture(hdbc,cdc_id, &ei);可以在此处关闭DPI接口。因为本例需要后面查看查看捕获表,所以不关闭。
	free_hdbc(hdbc, henv);
}
void main()
{
	test_cptview_case1();
	system("pause");
}

第四步,在数据捕获的窗口中,查看打印出的cdc_id和cdc_blob_id。

cdc_id:CPT_SYSDBA_T1_82118833738749
cdc_blob_id:CPT_SYSDBA_T1_82118833738749_BLOB

第五步,对具体对象进行操作。通过disql等客户端来改变表中的数据。

insert into t1 values(2, 'B', 'BC', 22);
insert into t1 values(3, 'C', 'CD', 33);
insert into t1 values(4, 'D', 'DE', 44);

第六步,查看数据捕获表。通过disql等客户端来查看cdc_id和cdc_blob_id表中的数据。

cdc_id表:

select * from CPT_SYSDBA_T1_82118833738749;
--查询结果如下:
行号       OP_SEQ   OPTYPE HAS_BLOB  C1     C3   C4          OP_ERROR
---------- --------  ----------- --------  ----------- --------  ----------- --------  ----------- --------
1          2            I         Y       2      BC   22          NULL
2          3            I         Y       3      CD   33          NULL
3          4            I         Y       4      DE   44          NULL

cdc_blob_id表:

select * from CPT_SYSDBA_T1_82118833738749_BLOB; 
--查询结果如下:
行号       OP_SEQ             COL_NAME C1
---------- -------------------- -------- ----------- ----------- --------
1           2                   C2       2
2           3                   C2       3
3           4                   C2       4

第七步,结束的时候,关闭数据捕获的环境。

SP_INIT_CPT_SYS(0);
微信扫码
分享文档
扫一扫
联系客服