PDF文库 - 千万精品文档,你想要的都能搜到,下载即用。

KingbaseES客户端编程接口指南-ODBC.pdf

Queen°(女王)66 页 695.228 KB下载文档
KingbaseES客户端编程接口指南-ODBC.pdfKingbaseES客户端编程接口指南-ODBC.pdfKingbaseES客户端编程接口指南-ODBC.pdfKingbaseES客户端编程接口指南-ODBC.pdfKingbaseES客户端编程接口指南-ODBC.pdfKingbaseES客户端编程接口指南-ODBC.pdf
当前文档共66页 2.88
下载后继续阅读

KingbaseES客户端编程接口指南-ODBC.pdf

KingbaseES 客户端编程接口指南-ODBC 金仓数据库管理系统 KingbaseES 文档版本:V9(V009R001C001B0024) 发布日期:2023 年 10 月 12 日 北京人大金仓信息技术股份有限公司 目 目 录 录 第 1 章 前言 1 1.1 适用读者 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1.2 相关文档 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1.3 术语 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1.4 手册约定 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 第 2 章 概述 3 2.1 ODBC 简述 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 2.2 KingbaseES ODBC 驱动包 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 第 3 章 ODBC 特性支持约束 6 3.1 系统边界值 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 3.2 特殊数据说明 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 3.3 其它约束 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 3.3.1 表中的列类型到 C 数据类型的转换 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 3.3.2 C 数据类型到 SQL 数据类型的转换 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 3.3.3 表中的列类型到 SQL 数据类型的映射 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 第 4 章 创建数据源 13 4.1 在 Windows 中创建 KingbaseES ODBC 数据源 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 4.2 在 Linux 中创建 KingbaseES ODBC 数据源 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 第 5 章 开发过程 19 第 6 章 KingbaseES ODBC 的扩展属性 21 6.1 KingbaseES ODBC 数据源的高级选项 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 6.2 Linux 环境下 SQLDriverConnect() 连接串中 KingbaseES ODBC 的扩展连接属性 . . . . . . . . . . . . 27 6.3 KingbaseES ODBC 的扩展连接属性和语句属性 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 第 7 章 KingabseES ODBC 驱动使用 37 7.1 Windows 中 ODBC 驱动使用步骤(VS2013) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 7.2 Linux 下调用 ODBC 驱动步骤 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 I 目 第 8 章 示例说明 录 41 8.1 常用的 ODBC 连接串 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 8.2 连接样例 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 8.3 字典函数的应用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 8.4 绑定参数为 BLOB 值 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 8.5 获取 BLOB 列的值 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 8.6 批量 DML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 第 9 章 疑难解答 58 版权声明 61 服务周期承诺 62 II 第 1 章 前言 1 第 章 前言 在本文档中详细说明了 KingbaseES ODBC 驱动的使用方法,以及使用时应该注意的问题。 前言部分包含以下主题: • 适用读者 • 相关文档 • 术语 • 手册约定 1.1 适用读者 《KingbaseES ODBC 指南》面向所有使用 KingbaseES 数据库的用户,主要是使用 ODBC 的应用程序开发人 员。 1.2 相关文档 有关 ODBC 的更多信息,请参阅以下资源: Microsoft ODBC Driver for SQL Server 或者 Using the Oracle ODBC Driver 1.3 术语 无。 1 第 1 章 前言 1.4 手册约定 本文档中可能出现“注意、提示、警告、另请参阅”等标志,它们所代表的含义如下: 注意: 用于突出重要/关键信息、最佳实践等。 提示: 用于突出小窍门、捷径等。 警告: 用于传递设备或环境安全警示信息,若不避免,可能会导致设备损坏、数据丢失、设备性能降低或其 它不可预知的结果。 另请参阅: 用于突出参考、参阅等。 以下程序代码书写约定适用于本文档: 符号 说明 [] 表示包含一个或多个可选项。不需要输入中括号本身。 {} 表示包含两个以上(含两个)的候选,必须在其中选取一个。不需要输入花括号本身。 | 分割中括号或者花括号中的两个或两个以上选项。不需要输入“|”本身。 ... 表示其之前的元素可以被重复。 斜体 表示占位符或者需要提供特定值的变量。 大写 表示系统提供的元素,以便与用户定义的元素相互区分。除出现在方括号中的元素外,应当按 照顺序逐字输入。当然,部分元素在系统中是大小写不敏感的,因此用户可以根据系统说明以 小写形式输入。 小写 表示由用户提供的元素。 2 第 2 章 概述 2 第 章 概述 本章节简单介绍了 ODBC 的背景和 KingbaseES 对其兼容情况。 本章节包含以下内容: • ODBC 简述 • KingbaseES ODBC 驱动包 2.1 ODBC 简述 ODBC 是 Microsoft 提供的、以 C 和 C++ 语言面向 SQL Server 编写的应用程序的主要原生数据访问 API。 开放数据库连接 (ODBC) 提供了一个标准接口,允许一个应用程序访问许多不同的数据源。应用程序的源代码 不需要为每个数据源重新编译。数据库驱动程序将应用程序链接到特定数据源。数据库驱动程序是一个动态链接库, 应用程序可以根据需要调用该库来访问特定数据源。因此,应用程序可以访问数据库驱动程序存在的任何数据源。 ODBC 接口定义如下: • 一个 ODBC 函数调用库,允许应用程序连接到数据源,执行结构化查询语言 (SQL) 语句,并检索结果。 • 基于 SQL-99 规范的 SQL 语法。 • 一套标准的错误代码。 • 连接和登录数据源的标准方法。 • 数据类型的标准表示。 下图展示了 ODBC 模型的组成部分。该模型从 ODBC 应用程序开始,通过 ODBC 应用程序接口 (API) 调用驱 动程序管理器。驱动程序管理器可以是 Microsoft 驱动程序管理器,也可以是 UnixODBC 驱动程序管理器。驱动程 序管理器仍然使用 ODBCAPI 对 ODBC 驱动程序进行调用。ODBC 驱动程序使用数据库 API 通过网络通信链路访 问数据库,该图展示了一个访问三个独立数据库的 ODBC 应用程序。 3 第 2 章 概述 图 2.1.1: ODBC 模型组成部分 2.2 KingbaseES ODBC 驱动包 KingbaseES ODBC 是标准 C 的 ODBC 驱动程序,它支持 Microsoft ODBC 3.0 标准。通过 KingbaseES ODBC Driver,应用程序可以完成与数据库的连接、执行 SQL 语句、从数据库中获取结果、获取状态及错误信息、终止事 务和连接等操作。 4 第 2 章 概述 图 2.2.1: KingbaseES ODBC 驱动结构 5 第 3 章 ODBC 特性支持约束 3 第 章 ODBC 特性支持约束 KingbaseES 对 ODBC 3.0 的支持是有约束的,本节将从系统边界值等方面描述这些约束。 • 系统边界值 • 特殊数据说明 • 其它约束 3.1 系统边界值 表 3.1.1: 系统边界值 3.2 系统特性 最小值 最大值 ODBC 每个环境句柄的连接数 0 128 特殊数据说明 1. BLOB BLOB 数据类型可以通过编程方式插入(参照示例说明 中的” 绑定参数为 BLOB 值” ),也可以通过调用 SQL 语句 insert into [table name] values(1,X'41424344') 进行插入。 2. CLOB 与 BLOB 类似,CLOB 数据类型可以通过编程方式插入,也可以通过调用 SQL 语句 insert into [table name] values(1, 'ABCD') 进行插入。 6 第 3 章 ODBC 特性支持约束 3.3 其它约束 a. SQLBindCol 具体的列中的类型可以转化为 C 数据类型,参见表 3.3.1。 b. SQLBindParameter 支持从 C 数据类型往 SQL 数据类型的转化,参见表 3.3.2。 列类型与 SQL 语句类型的对应关系参见表 3.3.3。 c. SQLGetData 具体的列中的类型可以转化为 C 数据类型,参见表 3.3.1。 参考以下的详细数据类型转换: • 表中的列类型到 C 数据类型的转换 • C 数据类型到 SQL 数据类型的转换 • 表中的列类型到 SQL 数据类型的映射 3.3.1 表中的列类型到 C 数据类型的转换 调用 SQLBindCol 和 SQLGetData 时可以参照该表。 表中的列定义可以是下表第一列中列出的 12 种类型,ODBC 的 C 数据类型可以是下表的第一行所列的 20 种类 型。 如果表定义为左边的某种类型,那么当调用 SQLGetData 或者 SQLBindCol 时 TargeType 参数只能是该数据类 型对应的一行中填有”Y” 的 C 数据类型。 例如, 当表中的列定义为 date,那么调用 SQLGetData 或者 SQLBindCol 时,TargetType 参数就可以 是 SQL_C_DEFAULT,SQL_C_CHAR,SQL_C_DATE,SQL_C_TIME,SQL_C_TIMESTAMP,而不能是 SQL_C_TINYINT。 7 第 3 章 ODBC 特性支持约束 表 3.3.1: 列类型到 C 数据类型的转换表 表中的列定 义 C 数据类型 S S S S S S S S S S S S S S S S S S S S Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q L L L L L L L L L L L L L L L L L L L L _C _C _C _C _C _C _C _C _C _C _C _C _C _C _C _C _C _C _C _C _ _ _ DE CH TI _ _ _ _ _ UT ST SH US SS _ _ _ _ _ _ _ _ _ _ _ _ LO UL SL SB UB DO FL BI BI DA TI TI FA AR NY IN IN OR HO HO NG ON ON IG IG UB OA NA T UL IN YI YI T IN IN LE T T NT NT T T RT RT G G T TE ME ME RY ST AM P BIGINT Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y INTEGER Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y SMALLINT Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y TINYINT Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y NUMERIC Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y DECIMAL FLOAT DOUBLE REAL BIT Y BYTEA Y Y Y BLOB BOOL Y Y BOOLEAN DATE Y Y Y Y Y Y Y Y Y Y TIME TIMESTAMP INTERVAL CHAR VARCHAR 见续表 8 第 3 章 ODBC 特性支持约束 表 3.3.1 – 续表 表中的列定 义 C 数据类型 S S S S S S S S S S S S S S S S S S S S Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q L L L L L L L L L L L L L L L L L L L L _C _C _C _C _C _C _C _C _C _C _C _C _C _C _C _C _C _C _C _C _ _ _ DE CH TI _ _ _ _ _ UT ST SH US SS _ _ _ _ _ _ _ _ _ _ _ _ LO UL SL SB UB DO FL BI BI DA TI TI FA AR NY IN IN OR HO HO NG ON ON IG IG UB OA NA T UL IN YI YI T IN IN LE T T NT NT T T RT RT G G T RY TE ME ME ST AM P TEXT Y Y CLOB 3.3.2 C 数据类型到 SQL 数据类型的转换 调用 SQLBindParameter 时可以参照该表。 ODBC 的 C 数据类型可以使用下表的第一行所列的 18 种类型,SQL 语句类型可以使用下表第一列中列出的 19 种类型。 如果绑定参数的 ValueType 为某种 C 数据类型,那么当调用 SQLBindParameter 时,ParameterType 参数只能 是该 C 数据类型对应的一列中填有”Y” 的 SQL 数据类型。如: 如果绑定参数的 ValueType 为 SQL_C_CHAR,那么调用 SQLBindParameter 时,ParameterType 参数就可以 是 SQL_CHAR,SQL_VARCHAR,SQL_LONGVARCHAR,而不能是 SQL_DECIMAL。 9 第 3 章 ODBC 特性支持约束 表 3.3.2: C 数据类型到 SQL 数据类型的转换表 SQL 数据类型 C 数据类型 S S S S S S S S S S S S S S S S S S Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q L L L L L L L L L L L L L L L L L L _C _C _C _C _C _C _C _C _C _C _C _C _C _C _C _C _C _C _ _ _ DE CH TI _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ UT ST SH US SS LO UL SL DO FL BI BI DA TI TI FA AR NY IN IN OR HO HO NG ON ON UB OA NA T UL IN YI YI T T T NT NT RT RT G G LE T TE ME ME RY ST AM P SQL_CHAR Y Y Y Y Y SQL_VARCHAR Y Y Y Y Y SQL_LONGVARCHAR Y Y SQL_DECIMAL Y Y Y Y Y Y Y Y Y Y Y Y SQL_NUMERIC Y Y Y Y Y Y Y Y Y Y Y Y SQL_BIT Y SQL_TINYINT Y Y Y Y Y Y Y Y Y Y Y Y SQL_SMALLINT Y Y Y Y Y Y Y Y Y Y Y Y SQL_INTEGER Y Y Y Y Y Y Y Y Y Y Y SQL_BIGINT Y Y Y Y Y Y Y Y Y Y Y Y SQL_REAL Y Y Y Y Y Y Y Y Y Y Y Y SQL_FLOAT Y Y Y Y Y Y Y Y Y Y Y Y SQL_DOUBLE Y Y Y Y Y Y Y Y Y Y Y Y SQL_BINARY Y Y SQL_VARBINARY Y Y SQL_LONGVARBINARY Y Y SQL_TYPE_DATE Y Y Y Y SQL_TYPE_TIME Y Y Y Y Y 见续表 10 第 3 章 ODBC 特性支持约束 表 3.3.2 – 续表 SQL 数据类型 C 数据类型 S S S S S S S S S S S S S S S S S S Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q L L L L L L L L L L L L L L L L L L _C _C _C _C _C _C _C _C _C _C _C _C _C _C _C _C _C _C _ _ _ DE CH TI _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ UT ST SH US SS LO UL SL DO FL BI BI DA TI TI FA AR NY IN IN OR HO HO NG ON ON UB OA NA T UL IN YI YI T T T NT NT RT RT G G LE T TE ME ME RY ST AM P SQL_TYPE_TIMESTAMP 3.3.3 Y Y Y Y 表中的列类型到 SQL 数据类型的映射 下表列出了调用 SQLBindParameter 时表中的列定义数据类型与 SQL 类型的对应关系: 当表中的数据类型定义为第一列的某种类型,那么当调用 SQLBindParameter 时,ParameterType 只能为其对应 行中的第二列的值。如:表中的列类型为 INTEGER(INT),那么对应的 SQL 数据类型只能为 SQL_INTEGER,而 不能为其它的 SQL 数据类型,否则数据转化将会出错。 11 第 3 章 ODBC 特性支持约束 表 3.3.3: 表中的列类型到 SQL 数据类型的映射表 表中的列定义 可转化为如下 SQL 数据类型 BIGINT SQL_BIGINT INTEGER SQL_INTEGER SMALLINT SQL_SMALLINT TINYINT SQL_TINYINT DECIMAL NUMERIC SQL_DECIMAL, SQL_NUMERIC REAL FLOAT DOUBLE SQL_REAL, SQL_FLOAT, SQL_DOUBLE BYTEA SQL_BINARY, SQL_VARBINARY BLOB SQL_LONGVARBINARY BOOL BOOLEAN SQL_BIT DATE TIME TIMESTAMP SQL_DATE, SQL_TIME, SQL_TIMESTAMP CHAR VARCHAR TEXT SQL_CHAR, SQL_VARCHAR CLOB SQL_LONGVARCHAR 12 第 4 章 创建数据源 4 第 章 创建数据源 本章节介绍了如何在不同操作系统中配置创建 KingbaseES ODBC 数据源。 • 在 Windows 中创建 KingbaseES ODBC 数据源 • 在 Linux 中创建 KingbaseES ODBC 数据源 4.1 在 Windows 中创建 KingbaseES ODBC 数据源 a. 选择『开始』�『设置』�『控制面板』菜单,在弹出窗口中双击【管理工具】(win11 版本下,双击控制面板中 的【Windows 工具】)图标进入管理工具界面,双击【数据源 (ODBC)】图标。 13 第 4 章 创建数据源 b. 选择【系统 DSN】选项卡,单击【添加 (D)…】按钮,系统弹出【创建新数据源】对话框。 c. 在 ODBC 驱动器程序列表中,选择【KingbaseES 9 ODBC Driver】,单击【完成】按钮,系统弹出【KingbaseES ODBC 数据源配置】对话框。 14 第 4 章 创建数据源 在【数据源名称】中用户可以填写任何不与现有 DSN 重名的名称。在对话框中,用户必须填写【数据库名 称】。 对于【数据库名称】和【用户名】,无论是在数据源配置界面中配置连接,还是调用 SQLDriverConnect() 方法 连接,都有如下规则: i. 如果用户名、数据库名没有用双引号引起来 • 当服务器的 case_sensitive 属性为”on” 时,则表示以大写形式的用户名登录,连接的是大写形式的数 据库名。 例如,输入用户名”SYSTEM” 数据库名”TEST”,就是以用户”SYSTEM” 连接”TEST” 数据库。 相应的 方 法 的 连 接 串 为:” DRIVER={KingbaseES SQLDriverConnect 9 ODBC Driver};SERVER=127.0.0.1;UID=SYSTEM;PWD=MANAGER;DATABASE=TEST;PORT=54321”。 • 当服务器的 case_sensitive 属性为”off” 时,则表示以与输入的用户名所含字母相同的用户名登录,连 接的是与输入的数据库名所含字母相同的数据库。 例如,输入用户名”system” 数据库名”test”,和以用户名”System” 数据库名”Test” 连接是一样的。 相应的 SQLDriverConnect 方 法 的 示 例 连 接 串 为:” DRIVER={KingbaseES 9 ODBC Driver};SERVER=127.0.0.1;UID=system;PWD=MANAGER;DATABASE=test;PORT=54321”。 ii. 如果用户名、数据库名用双引号括起来 15 第 4 章 创建数据源 • 当服务器的 case_sensitive 属性为”on” 时,则表示以和双引号中大小写一致的用户名登录,连接的是 和双引号中大小写一致的数据库名。 例如,输入用户名”system” 数据库名”test”,就是以用户”system” 连接”test” 数据库。 相应的 ODBC 方 法 的 示 例 连 接 串 为:” SQLDriverConnect Driver};SERVER=127.0.0.1;UID=” DRIVER={KingbaseES 9 system”;PWD=MANAGER;DATABASE=” test”;PORT=54321”。 • 当服务器的 case_sensitive 属性为”off” 时,则表示以和双引号中所含字母相同的用户名登录,连接的 是和双引号中所含字母相同的数据库名。 例如,输入用户名”system” 数据库名”test”,和以用户名”System” 数据库名”Test” 连接是一样的。 相应的 ODBC 方 法 的 示 例 连 接 串 为:” SQLDriverConnect Driver};SERVER=127.0.0.1;UID=” DRIVER={KingbaseES 9 system”;PWD=MANAGER;DATABASE=” test”;PORT=54321”。 iii. 如果用户名、数据库名中包含双引号 • 用户名或者数据库名必须使用双引号引起来,并且需要将包含的双引号写两遍表示转义。 例如,输入用户名”sys””tem” 和数据库名”te””st”,就是以用户 sys”tem 连接 te”st 数据库。 相应的 SQLDriverConnect 方 法 的 示 例 连 接 串 为:” DRIVER={KingbaseES Driver};SERVER=127.0.0.1;UID=” sys”” 9 ODBC tem”;PWD=MANAGER;DATABASE=” te”” st”;PORT=54321”。 d. 如果要进行高级配置,可以单击【数据源】按钮,系统弹出【高级选项】对话框。 选择或设定您需要的选项值(各选项的含义和用法请参见KingbaseES ODBC 的扩展属性 中的 6.1 章节),然 后单击【确认】按钮,【高级选项】对话框关闭,新建的 ODBC 数据源将采用该对话框中的设置。 e. 单击【保存】按钮,这样就创建了一个 KingbaseES ODBC 数据源。 f. 如果要测试与数据源的连接是否成功,可以单击【测试】,系统会根据测试的结果弹出相应的消息框。 4.2 在 Linux 中创建 KingbaseES ODBC 数据源 配置 ODBC Data Source 需要使用 odbcinst。 通过命令行方式配置 ODBC 数据源的步骤: 1. 首先检查 ODBC Driver 是否已经安装。 在系统中找到 odbcinst.ini 文件,和/usr/bin/odbcinst 对应的 odbcinst.ini 在 /etc 目录下,和/usr/local/bin/ odbcinst 对应的 odbcinst.ini 在 /usr/local/etc 目录下。在 odbcinst.ini 文件中查找 [KingbaseES 9 ODBC Driver] 这一项。如果没有,则编写一个模板文件”template_file1” ,包含如下内容: 16 第 4 章 创建数据源 [KingbaseES 9 ODBC Driver] Description = KingbaseES 9 ODBC Driver for Linux Driver = /opt/Kingbase/ES/V9/Odbc/kdbodbcw.so Debug = 0 CommLog = 1 2. 然后,执行如下命令: odbcinst -i -d -f template_file1 这样就安装了 KingbaseES 的 ODBC Driver。 3. 编写一个模板文件 template_file2,包含如下内容: [kingbase8] Description = KingbaseES Driver = KingbaseES 9 ODBC Driver Trace = No TraceFile = Database = TEST Servername = localhost Username = SYSTEM Password = 123 Port = 54321 ReadOnly = No RowVersioning = No ShowSystemTables = No ShowOidColumn = No FakeOidIndex = No ConnSettings = [kingbase8] 指定 DSN 名为 kingbase8。等号左侧为选项名,右侧为选项值。 Driver,Servername,Port,Username,Password,Database 等 6 项是必须填写的项。其中,需要注意的是用 户名和数据库名的大小写。 详细的内容请参考 在 Windows 中创建 KingbaseES ODBC 数据源部分的内容。 ”Driver = KingbaseES 9 ODBC Driver” 指明该 DSN 使用 KingbaseES 的 ODBC Driver。 更多的选项的含义和用法请参考KingbaseES ODBC 的扩展属性 中的 6.2 章节。 4. 执行如下命令: odbcinst -i -s -f template_file2 这样就创建了名为 kingbase 的 KingbaseES ODBC 数据源。 5. 如果要测试到数据源的连接是否成功,可以使用 unixODBC 自带的 isql 工具进行检测,方法如下: 17 第 4 章 创建数据源 isql 的使用方法为:isql DSN [UID [PWD]] [options],[options] 参数设置详见:isql -help 以上面配置的 ODBC 数据源为例,执行如下命令: root@root:~$ isql --v unixODBC 2.3.4 root@root:~$ isql kingbase SYSTEM MANAGER 如果连接成功会显示以下信息: +---------------------------------------+ | Connected! | | | | sql-statement | | help [tablename] | | quit | | | +---------------------------------------+ 如果连接失败会显示以下信息: [ISQL]ERROR: Could not SQLConnect 18 第5章 开发过程 5 第 章 开发过程 在正确设置了 KingbaseES ODBC 数据源以后,应用程序使用 KingbaseES ODBC API 的步骤如下: a. 调用 SQLAllocHandle 函数分配环境句柄。 b. 调用 SQLAllocHandle 函数分配连接句柄。 c. 利用分配后的连接句柄调用 SQLConnect,SQLBrowseConnect 或者 SQLDriverConnect 连接到数据源。它指定 数据源名以及完成连接所需的任何附加信息。 d. 处理一个或多个 SQL 语句: 应用程序将 SQL 文本串放置于缓冲区中。 如果语句包括参数标记,则将它设置参数值。 如果语句返回结果集,应用程序则为语句赋值游标名或者使用驱动程序缺省的游标名。应用程序为“SQLPrepare 或 SQLExecute”提交语句。 如果语句创建了结果集,应用程序则询问该结果集属性,例如列数,以及特定列的名称、类型等。它为结果集 中的每一列分配存储并取回结果。 如果语句引起错误,应用程序则从驱动程序中提取错误信息并采取相应行动。 e. 通过提交或重新操作来结束每一个事务。 f. 当应用程序与数据源之间的相互作用结束时,终止连接,释放相应的句柄。函数执行序列如下: 1) SQLAllocHandle(SQL_HANDLE_ENV,NULL,&henv)<=> SQLAllocEnv ; 2) SQLAllocHandle(SQL_HANDLE_DBC,henv,&hdbc)<=> SQLAllocConnect ; 3) SQLConnect ; 4) SQLAllocHandle(SQL_HANDLE_STMT,hdbc,&hstmt)<=> SQLAllocStmt ; 5) 处理 SQL 语句 (SQLPrepare 此步可以省略但在执行中必须调用 SQLExecDirect); 6) 如果有绑定参数则进行绑定赋值(SQLBindParameter); 7) 可以通过 SQLGetDescField, SQLColAttribute, SQLDescribeCol 等函数来获取信息(可以省略); 8) 通过 SQLExecute 或 SQLExecDirect 执行函数; 19 第5章 开发过程 9) 获取结果 (SQLFetch, SQLBindCol, SQLGetData...); 10) SQLFreeHandle(SQL_HANDLE_STMT,hstmt)<=> SQLFreeStmt ; 11) SQLDisconnect ; 12) SQLFreeHandle(SQL_HANDLE_DBC,hdbc)<=> SQLFreeConnect ; 13) SQLFreeHandle(SQL_HANDLE_ENV,henv)<=> SQLFreeEnv ; 为了让用户能更好地使用 KingbaseES ODBC 函数访问 KingbaseES 数据库,本文档还给出了一些 ODBC 的操 作示例,请参见示例说明 。 20 第 6 章 KINGBASEES ODBC 的扩展属性 6 第 章 KingbaseES ODBC 的扩展属性 • KingbaseES ODBC 数据源的高级选项 • Linux 环境下 SQLDriverConnect() 连接串中 KingbaseES ODBC 的扩展连接属性 • KingbaseES ODBC 的扩展连接属性和语句属性 6.1 KingbaseES ODBC 数据源的高级选项 这里提供在 Windows 下配置 KingbaseES 的相关说明 这里设定的选项值将对使用该 DSN 的 ODBC 连接有效,但部分选项的值可通过设置扩展的连接属性或语句属性 来改变,从而使这里设定的选项值失效而改用 ODBC 应用程序中设置的选项值。 i. 高级设置 1 对话框 21 第 6 章 KINGBASEES ODBC 的扩展属性 图 6.1.1: 配置对话框 1 • 默认:按此按钮恢复以下设置的正常默认值。 • 识别唯一索引:默认选中此选项。 • 使用 Declare/Fetch:如果勾选,则驱动程序自动使用 declare cursor/fetch 来处理 SELECT 语句,并在缓 存中保留 100 行。驱动程序不会占用大量内存来缓冲整个结果集,相对于更新数据而言,这在从数据库中 读取数据上是一个很大的优势。如果取消勾选,将不会使用游标,驱动程序将检索整个结果集。对于非常 大的表,这是非常低效的,可能会用完所有的 Windows 内存/资源。但是,这些表不会保持打开状态,就 像使用游标时一样,所以能更好的处理更新。这是旧版本 odbc32 的风格。新版本的内存分配策略有了很 大的改进,所以即使不使用游标,性能也比旧的 odbc32 更好。 • 执行一般日志输出 (C:ksqlodbc_xxxx.log):记录通讯信息的文件。调试问题可参考该文件。 • 输出详细的日志输出 (C:mylog_xxxx.log):记录调试消息的文件。调试驱动程序时可参考该文件。 • 执行语句的解析 (a): 如果应用程序在执行查询之前请求该信息,则告诉驱动程序如何收集有关查询结果列 的信息。另请参阅高级设置 2 中的 服务器端 prepare 选项。驱动程序首先检查次此选项。如果禁用,则会 检查服务器端准备选项。 如果启用此选项,驱动程序将解析 SQL 查询语句以识别列和表,并收集有关它们的统计信息,例如长度、 是否为空、别名等。然后在 SQLDescribeCol、SQLColAttributes 和 SQLNumResultCols 中报告此信息。 禁用此选项(默认)时,查询语句将发送到服务器以进行解析和描述。如果解析器不能处理一个列(因为 它是一个函数或表达式等),它会回退到描述服务器中的语句。解析器相当复杂,可以处理很多事情,例 22 第 6 章 KINGBASEES ODBC 的扩展属性 如列和表别名、带引号的标识符、文字、连接、交叉产品等。它可以正确识别函数或表达式列,无论复杂 度如何,但它不会尝试以确定这些列的数据类型或长度。 • 未知的大小行为:SQLDescribeCol 和 SQLColAttributes 返回的结果集长度未知时,控制结果集中字符数 据类型(varchar,text 和 unknown)的长度。V7 版本之前的 KingbaseES 无法返回 varchar 数据类型的 最大长度,现在可以设置该参数来返回一个长度。 – 最大化:始终返回数据类型的最大长度。 – 未指定:返回“未知”的结果,让应用程序决定。 – 采取时间最长:返回任意一列的最长字符串长度。使用游标时请注意此设置,因为缓存大小可能不是 缓存中最长列的良好表示。 • 数据类型选项:影响一些数据类型的映射方式: – 将文本视为长字符串:KingbaseES TEXT 类型映射到 SQLLongVarchar,否则映射到 SQLVarchar。 – 以长字符串处理未知:未知类型(数组等)被映射到 SQLLongVarChar,否则映射到 SQLVarchar。 – 把 Bools 当做 char:Bools 映射到 SQL_CHAR,否则映射到 SQL_BIT。 • 最大 Varchar:Varchar 和 BPChar(char [x])类型的最大长度。默认值是 254,实际上意味着 255,因为 含有空终止符。请注意,如果您将此值设置为高于 254,KingbaseES 将不会在 varchar 列上索引! • 缓存大小:使用游标时,这是元组缓存的行大小。如果不使用游标,这是在任何给定的时间分配内存的数 量。无论哪种情况,默认值为 100 行。 • 最大 Long:LongVarChar 类型的最大长度。默认值是 4094,实际上意味着 4095,因为含有空终止符。另 外,也可以指定“-4”,这是 odbc 的 SQL_NO_TOTAL 值。 • 系统表前缀:作为系统表的附加表名前缀。即使没有设置,以”sys” 开头的表格总是被视为系统表格。用 分号”;” 分隔每个前缀。 ii. 高级设置 2 对话框 23 第 6 章 KINGBASEES ODBC 的扩展属性 图 6.1.2: 配置对话框 2 • 只读:数据源是否允许更新。 • 显示系统表:驱动程序将系统表视为 SQLTables 中的常规表。你可以看到系统表。 • LF <-> CR/LF 转换:将 Unix 样式行结尾转换为 DOS 样式。 • 可更新的游标:在驱动程序中启用可更新的游标仿真。 • 将 bytea 视为 LOBs:允许使用大对象的 bytea 列。 • 版本列显示:允许应用程序在尝试更新行时检测数据是否已被其他用户修改。它还加快了更新过 程,因为不需要在 where 子句中指定每一列来更新行。驱动程序使用 KingbaseES 的“xmin”系统 字段来允许行版本控制。 • 显示可选错误消息:显示可选(详细信息、提示、语句位置等)错误消息。 • -1 为真值(true):为了与某些应用程序兼容,将 TRUE 表示为-1。 • 服务器端 Prepare(8.2 之后):如果勾选,驱动程序使用服务器端准备好的语句。另请参阅 执行语句 的解析选项。请注意,如果在执行之前需要描述查询,例如因为应用程序在 SQLExecute()之前调 用 SQLDescribeCol()或 SQLNumResultCols(),则即使禁用此选项,驱动程序也会向服务器发 送解析请求。在这种情况下,发送到服务器进行分析的查询将使用实际参数值替换参数标记,如果 值尚未知,则使用 NULL。 • Int8 替代的定义:定义什么样的数据类型来报告 int8 列。 24 第 6 章 KINGBASEES ODBC 的扩展属性 • 额外选项:如以下所列的参数。 – 0x1:强制短格式的连接字符串的输出。使用 MFC CDatabase 类时请检查此位。 – 0x2:假 MS SQL Server,以便 MS Access 将 KingbaseES 的序列类型识别为自动编号类型。 – 0x4:为应用程序的查询答复 ANSI(而不是 Unicode)字符类型。尝试检查这一点,当你的应用 程序似乎不擅长处理 Unicode 数据。 • 错误回滚级别:指定发生错误时要回滚的内容。 – 没有:不回滚任何东西,让应用程序处理错误。 – 所有取消:回滚整个 Transaction。 – 句子单独:回滚语句。 设置说明:此规范是使用 PROTOCOL 选项参数设置的。 PROTOCOL=7.4-(0|1|2) 默认值为 Statement(8.0 之前的服务器为 Transaction)。 • OID 选项: – 列栏显示:在 SQLColumns 中包含 OID。如果没有正确的密钥存在,或者密钥包含很多部分, 这就可以作为唯一标识符来更新记录。 – 举例是一个索引:这个选项在 OID 上伪造一个唯一索引。当 OID 上没有真正唯一的索引时,以 及无法询问唯一标识符应该是什么的应用程序,这是非常有用的。 • 连接设置:连接成功后,驱动程序将这些命令发送到后端。它在发送驱动程序“连接设置”之后发 送这些设置。使用分号“;”分隔命令。现在可以处理任何查询,即使它返回结果,结果将被丢弃! • TCP KEEPALIVE 设置(秒):指定 TCP 保持活动设置。 – 不要使用:不使用客户端 TCP 保持活动。 – 等待时间:TCP 应该向服务器发送一个保活消息的非活动秒数。 – 响应等待时间:服务器未确认 TCP 保持消息应重发的秒数。 iii. 高级设置 3 对话框 25 第 6 章 KINGBASEES ODBC 的扩展属性 图 6.1.3: 配置对话框 3 • MSDTC 不可能连接允许连接?:如何测试分布式事务。 – 是:MSDTC 是不必要的,除非应用程序崩溃。所以不要检查 MSDTC 的连通性。 – sslmode verify- [ca | full] 排斥反应:用 verify-ca 或 verify-full 模式拒绝 ssl 连接,因为在这种情 况下 msdtc 很难建立连接。 – 否:首先确认 MSDTC 的连通性。 • libkci 参数:用 conninfo 风格字符串指定 libkci 连接参数,例如: sslrootcert = c:\myfolder\myroot sslcert = C:\myfolder\mycert sslkey = C:\myfolder\mykey 尽 管 可 以 使 用 此 (kdbopt) 选 项 来 设 置 主 机, 端 口,dbname, 用 户, 密 码,sslmode, keepalives_idle 或 keepalive_interval 参数,但不建议使用,因为它们通常由其他选项设置。当 这些参数的某些设置与其他普通选项冲突时,连接将被拒绝。 iv. 全局配置 该对话框允许您指定预连接/默认日志记录选项: • 普通日志(C:\ksqlodbc_xxxx.log-通信日志):记录通讯信息的文件。这对调试问题很有帮助。 26 第 6 章 KINGBASEES ODBC 的扩展属性 • 详细日志(C:\mylog_xxxx.log - 详细的调试输出):将调试消息记录到该文件。这对于调试驱动 程序的问题很有帮助。 • MSDTC 日志(C:\kdbdtclog \mylog_xxxx.log - MSDTC 调试输出):将调试消息记录到该文件。 这对于调试 MSDTC 的问题很有用。 • 日志路径:配置日志的输出路径。 v. DSN 管理:该对话框允许您选择使用哪个 KingbaseES ODBC 驱动程序执行此连接。请注意,这可能不适用于 第三方驱动程序。 6.2 Linux 环境下 SQLDriverConnect() 连接串中 KingbaseES ODBC 的扩展连接属性 在连接串中除了必须设定 DSN 或 DRIVER 以及 Username(uid),Password(pwd),Database 等连接属性外, 还可以设定多个连接属性。如果连接串中不指定 ConnMode 或 ConnMode 指定为 TCP/ IP,则必须指定 Servername(server) 和 Port。 SQLDriverConnect() 方法的调用,参考疑难解答 部分的内容。其中,需要注意的是连接串中 Username(uid) 和 Database 的大小写。 设定的选项值将对该连接上的所有语句有效,但部分选项的值可通过设置连接属性或语句属性来改变,从而使这 里设定的选项值失效而改用新设置的选项值。详细的连接属性如下表所示: 参数值 参数描述 取值范围 Description 描述该数据库连接的字符串。 0 个字符至 256 个字符。默 认为空串。 Fetch 表示当使用服务器端游标时结果集在客 1 至内存允许的最大值 (保证 户端可缓存的最大元组数。 客户端机器正常运行的条件 下),一般越大越好,但太大 会影响客户端机器的整体性 能。默认值为 100。 Debug 调试日志:记录调试信息的文件。 Scoket 表示连接数据库套接字的缓存大小。 ReadOnly 表示设置连接数据库时是否以只读的方 默认值为 NO。 式。 CommLog 普通日志:记录通信信息的文件。 默认值为 0。 见续表 27 第 6 章 KINGBASEES ODBC 的扩展属性 表 6.2.1 – 续表 参数值 参数描述 取值范围 Protocol KingbaseES 的后端协议 默认值为 7.4.0。 ConnSettings 连接成功后,驱动程序将这些命令发送 到后端。在发送驱动程序“连接设置” 之后发送这些设置。使用分号“;”分 隔命令。 UniqueIndex 识别唯一索引。 默认值为 1。 UnknownSizes 当返回的结果集长度未知时,控制结果 默认值为 0。 集中字符数据类型的长度。 TextAsLongVarchar 将 文 本 视 为 长 字 符 串,KingbaseES 默认值为 1。 TEXT 类型映射到 SQLLongVarchar 。 UnknownsAsLongVarchar 以长字符串处理未知,未知类型(数组 默认值为 0。 等)被映射到 SQLLongVarchar 。 BoolsAsChar 将 Bool 类型视为 char,Bools 映射到 默认值为 1。 SQL_CHAR。 FakeOidIndex 仿造 OID 上的唯一索引。 默认值为 0。 ShowOidColumn 在 SQLColumns 中包含 OID。如果没 默认值为 0。 有正确的密钥存在,或者密钥包含很多 部分,这就可以作为唯一标识符来更新 记录。 RowVersioning 允许应用程序在尝试更新行时检测数据 默认值为 0。 是否已被其他用户更改。 ShowSystemTables 表示驱动程序将系统表视为 SQLTables 默认值为 0。 中的常规表。 Parse 表示是否在驱动程序解析 SQL 查询语 默认值为 0。 句。 ExtraSysTablePrefixes 作为系统表的附加表名前缀。 以“sys”开头的表格默认视 为系统表格。 UpdatableCursors 表示在驱动程序中启用可更新的游标。 默认值为 1。 见续表 28 第 6 章 KINGBASEES ODBC 的扩展属性 表 6.2.1 – 续表 参数值 参数描述 取值范围 LFConvertion 表示把 ODBC 应用程序的字符数据 Windows 32 位:默认值为 类型数据中的回车换行符都转换成换 1。 行符再传给后端数据库服务器,反过来 把后端数据库服务器字符数据类型数据 中的换行符都转换成回车换行符再传给 ODBC 应用程序。 MaxVarcharSize 表示 VARCHAR 数据类型的值允许的 1 至 8000。默认值为 254。 最大字符数。 MaxLongVarcharSize 表示 LongVarchar 数据类型的值允 -4 至 10485760。默认值为 许 的 最 大 长 度。 默 认 值 为 4094。 4094, 这 意味着实际可以有 4095 个字符串, 最后一个字符为空格终止符。您甚至 可以将此大小指定为 (-4),即 odbc SQL_NO_TOTAL 值。 BatchInsertSize BatchInsertSize_Ext 使用参数数组执行批处理的块大小 1 至 数 组 大 小。 默 认 值 为 (该 参 数 的 优 先 级 低 于 BatchInser 4094。注意:该参数只作用 tSize_Ext)。将此选项设置为 1 会强制 于 INSERT 语句,对其他 执行(单条语句操作)。 DML 语句不生效。 表示启用批量操作扩展协议,该协议开 1 或 true 或 t 表示使用启 启之后,会大幅度提升批量操作的性 动该协议。默认为 0,表示 能,如果在操作过程中出现错误,则提 关闭。注意:1. 一次传送的 交之前操作成功的数据。 参数总个数 (占位符个数 × 批量行数) 不能超过 32767 个;2. 该参数优先级高于 BatchInsertSize 参数; 3. 该 参数需要使用 V8R6C4 及以 上版本的 KingbaseES 数据 库才能支持。 见续表 29 第 6 章 KINGBASEES ODBC 的扩展属性 表 6.2.1 – 续表 参数值 参数描述 取值范围 UseDeclareFetch 表示执行 SQL 查询时是否使用服务器 1 或 true 或 t 表示使用 的游标。 服务器端的游标,ODBC 将 为 SQL 查询向服务器请求游 标,查询的整个结果集缓存 在服务器上,ODBC 端仅缓 存结果集的一部分元组(元 组数是 Fetch 属性的值), 这适用于结果集很大 ODBC 端一次无法缓存全部结果的 情况,总体上 fetch 结果集 元组的速度慢一些;0 或或 false 或 f 表示不使用服务器 端的游标,ODBC 将把查询 的结果集一次缓存到本地, 服务器端不再缓存结果集, fetch 结果集元组的速度会 快一些,但结果集很大时, ODBC 端将无法缓存整个结 果集。默认为 0,即不使用 服务器端游标。 TrueIsMinus1 为了与某些应用程序兼容,将 True 表 默认值为 0。 示为-1。 BI 定义什么样的数据类型来报告 int8 列。 默认值为 0。 ByteaAsLongVarBinary 允许使用大对象的 bytea 列。 默认值为 1。 见续表 30 第 6 章 KINGBASEES ODBC 的扩展属性 表 6.2.1 – 续表 参数值 参数描述 取值范围 UseServerSidePrepare 表示是否让服务器端对 SQL 命令执行 1 或 0,或者 true 或 false, 预处理以在服务器端生成并缓存查询计 或者 t 或 f 。1 或 true 划。 或 t 表示执行服务器端预 处理,ODBC 将请求服务器 对 SQL 命令进行预处理; 0 或 false 或 f 表示不执行 服务器端预处理,ODBC 将 不把 SQL 命令发送给服务 器,等到 SQLExecute() 时 才把 SQL 命令发送给服务 器直接执行。当应用不需要 参数元信息时,可以设为 0 或 false,以减少一次前后端 交互的代价。默认为 1,即 执行服务器端预处理。 LowerCaseIdentifier 小写的标识符。 默认值为 0。 SSLMode 表示是否使用 SSL 安全连接。 ”disable” 表示禁用;”allow” 表示允许;” prefer” 表示优 先;” verify-ca” 或” verifyfull” 拒绝 SSL 连接;” require” 表示按需求。默认值 为” disable” , 表示不适用 SSL 安全连接。 AB 额外选项。 CX 缩写(推荐值的简单设置)。 KeepAlive 表示是否开启 KeepAlive 功 能。 选 中 “1” 表 示 开 启 KeepAlive 功能就是服务器端和客户端 KeepAlive 功 能, 选 中 都能及时有效地检测到连接失效,然后 “0” 表 示 关 闭 优雅地完成一些清理工作并把错误报告 功 能。 如 果 此 参 数 为 关 闭 给用户。 状 态, 那 么 KeepAlive KeepAliveI- dle、KeepAliveInterval、 KeepAliveCount 会失效。默 认为 0,表示关闭 KeepAlive 功能。 见续表 31 第 6 章 KINGBASEES ODBC 的扩展属性 表 6.2.1 – 续表 参数值 参数描述 取值范围 KeepAliveIdle 表示首次探测前 TCP 连接空闲的时 大于 0 小于 2147483648 的任 间。在 KeepAliveIdle 时间里没有数据 何正整数。Windows 平台默 传输,就会发送一个探测包。Windows 认为 7200000,Linux 平台默 平台时间单位是毫秒,Linux 平台时间 认为 7200。 单位是秒。 KeepAliveInterval 表示发送探测包的间隔时间。Windows 大于 0 小于 2147483648 的任 平台单位是毫秒,Linux 平台单位是 何正整数。Windows 平台默 秒。 认为 1000,Linux 平台默认 为 75。 NumbericAS 指定从不精确的数字项到 SQL 数据类 默认值为-101。 型的映射。 OptionalErrors 显示可选(详细信息、提示、语句位置 等)错误信息。 IgnoreTimeout 忽视 SQL_ATTR_QUERY_T IMEOUT 的设置,改用 SQLSetStmtAttr() 的设置。 6.3 KingbaseES ODBC 的扩展连接属性和语句属性 提供的扩展连接属性和语句属性如下表所示: 连接参数 参数类型 参数说明 参数取值 SQL_ATTR 句 柄 类 型:connection 普 通 日 志 _PGOPT_ 数据类型:SQLUINTE- \ksqlodbc_xxxx.og): COMMLOG GER 记录通讯信息的文件。调试问题 (C: 无 时可参考此文件。 SQL_ATTR 句 柄 类 型:connection 详细日志 (C:\mylog_xxxx.log): _PGOPT 数据类型:SQLUINTE- 记录调试消息的文件。调试驱动 _DEBUG GER 程序问题时可参考此文件。 无 见续表 32 第 6 章 KINGBASEES ODBC 的扩展属性 表 6.3.1 – 续表 连接参数 参数类型 参数说明 参数取值 SQL_ATTR 句 柄 类 型:connection 如果应用程序在执行查询之前请 无 _PGOPT 数据类型:SQLUINTE- 求该信息,则告诉驱动程序如何 _PARSE GER 收集有关查询结果列的信息。另 请参阅服务器端准备选项。驱动 程序首先检查次此选项。如果禁 用,则检查服务器端准备选项。 如果启用此选项,驱动程序将解 析 SQL 查询语句以识别列和表并 收集有关它们的统计信息,例如 长度、是否为空、别名等。然后 在 SQLDescribeCol、SQLColAttributes 和 SQLNumResultCols 中报告此信息。禁用此选项(默 认)时,查询将发送到服务器以 进行解析和描述。如果解析器不 能处理一个列(因为它是一个函 数或表达式等),它会回退到描 述服务器中的语句。解析器相当 复杂,可以处理很多事情,例如 列和表别名、带引号的标识符、 文字、连接、交叉产品等。它可 以正确识别函数或表达式列,无 论复杂度如何,但它不会尝试以 确定这些列的数据类型或长度 见续表 33 第 6 章 KINGBASEES ODBC 的扩展属性 表 6.3.1 – 续表 连接参数 参数类型 参数说明 参数取值 SQL_ATTR 句 柄 类 型:connection 表示执行 SQL 查询时是否使 1 或 0。1 表示使用服务器端的 _PGOPT 数据类型:SQLUINTE- 用服务器的游标。若是设置连接 游标,ODBC 将为 SQL 查询向 _USE GER 属性,可在连接之前或之后设置 服务器请求游标,查询的整个结 _DECLAR 该值。新值对设定成功之后在该 果集缓存在服务器上,ODBC 端 EFETCH 连接句柄上新分配的语句句柄有 仅缓存结果集的一部分元组(元 效,对设定成功之前该连接句柄 组数是” Cache 大小 ( Fetch)” 上分配的语句句柄无效。 选项或 Fetch 连接属性的值), 这适用于结果集很大、ODBC 端 一次无法缓存全部结果的情况, 总体上 fetch 结果集元组的速度 慢一些;0 表示不使用服务器端 的游标,ODBC 将把查询的结果 集一次缓存到本地,服务器端不 再缓存结果集,fetch 结果集元组 的速度会快一些,但结果集很大 时 ODBC 端将无法缓存整个结果 集。 SQL_ATTR 句 柄 类 型:connection 表示当使用服务器端游标时结果 取值范围:1 至内存允许的最大 _PGOPT 数据类型:SQLUINTE- 集在客户端可缓存的最大元组 值 (保证客户端机器正常运行的 _FETCH GER 数。 条件下),一般越大越好,但太大 会影响客户端机器的整体性能。 默认值为 100。 SQL_ATTR 句 柄 类 型:connection 表示是否让服务器端对 SQL 命 1 或 0。1 表示执行服务器端 _PGOPT 数据类型:SQLUINTE- 令执行预处理在服务器端生成并 预处理,ODBC 将请求服务器对 _SERVER GER 缓存查询计划。若是设置连接属 SQL 命令进行预处理;0 表示不 _SIDE _PRE- 性,可在连接之前或之后设置该 执行服务器端预处理,ODBC 将 PARE 值。新值对设定成功之后在该连 不把 SQL 命令发送给服务器,等 接句柄上新分配的语句句柄有 到 SQLExecute() 时才把 SQL 命 效,对设定成功之前该连接句柄 令发送给服务器直接执行。当应 上分配的语句句柄无效。若是设 用不需要参数元信息时,可以设 置语句属性,新值对设定成功之 为 0,以减少一次前后端交互的 后在该语句句柄上执行的 SQL 代价。 语句有效,对设定成功之前在该 语句句柄上执行的 SQL 语句无 效。 见续表 34 第 6 章 KINGBASEES ODBC 的扩展属性 表 6.3.1 – 续表 连接参数 参数类型 参数说明 参数取值 SQL_ATTR 句 柄 类 型:connection 控制着 SQLDescribeCol 和 SQL- _PGOPT 数据类型:SQLUINTE- ColAttributes 返回长度未知时的 _UNKNOWN GER 结果集中的字符数据类型(var- • 最大化 始终返回数据类型的最大长度。 char ,text 和 unknown)的长 SIZES • 未指定 度。V7 版本之前的 KingbaseES 返回“未知”的结果,让应用程 无法返回 varchar 数据类型的长 序决定。 度,现在可以设置该参数来返回 一个长度。 • 采取时间最长 返回任意一列的最长字符串长 度。使用游标时请注意此设置, 因为缓存大小可能不是缓存中最 长列的良好表示。 SQL_ATTR 句 柄 类 型:connection KingbaseES _PGOPT 数据类型:SQLUINTE- 到 SQLLongVarchar,否则映射 _TEXT GER 到 SQLVarchar。 SQL_ATTR 句 柄 类 型:connection 未知类型映射到 SQLLongVar- _PGOPT_ 数据类型:SQLUINTE- char,否则映射到 SQLVarchar。 UNKNOWNS GER TEXT 类型映射 无 ASLONG VARCHAR 无 ASLONG VARCHAR SQL_ATTR 句 柄 类 型:connection KingbaseES BOOL 类型映射到 _PGOPT_ 数据类型:SQLUINTE- CHAR。 BOOLS GER 无 ASCHAR SQL_ATTR 句 柄 类 型:connection Varchar 和 BPChar(char[x])类 默认值是 _PGOPT_ 数据类型:SQLUINTE- 型的最大长度。 255,因为 包含 空 终止符。 请 注 MAXVAR GER CHARSIZE 254, 实 际 上 意 味 着 意, 如 果 您 将 此 值 设 置 为 高 于 254,将不会在 varchar 列上索 引! 见续表 35 第 6 章 KINGBASEES ODBC 的扩展属性 表 6.3.1 – 续表 连接参数 参数类型 参数说明 参数取值 SQL_ATTR 句 柄 类 型:connection LongVarChar 类型的最大长度。 默认值是 4094,实际上意味着 _PGOPT_ 数据类型:SQLUINTE- 4095,因为包含空终止符。你也 MAXLONG GER 可以指定(-4)这个大小,这是 odbc 的 SQL_NO_TOTAL 值 VARCHAR SIZE SQL_ATTR 句 柄 类 型:connection _PGOPT 数据类型:SQLUINTE- _WCSDE- GER 无 无 BUG 36 第 7 章 KINGABSEES ODBC 驱动使用 7 第 章 KingabseES ODBC 驱动使用 • Windows 中 ODBC 驱动使用步骤(VS2013) • Linux 下调用 ODBC 驱动步骤 7.1 Windows 中 ODBC 驱动使用步骤(VS2013) 1. 打开 VS2013; 2. 选择“文件”-> “新建”-> “项目”, 在项目中选择如下图所示,单击“确定”后,再单击“完成”; 图 7.1.1: 新建项目 37 第 7 章 KINGABSEES ODBC 驱动使用 3. 创建连接、断开数据库的程序,示例参见示例说明 中的” 连接样例”; 4. 在 ODBC 数据源管理工具中配置 DNS,配置步骤参考创建数据源 中的 Windows 操作; 5. 右键单击『解决方案资源管理器』中的 ODBC 项目,选择【生成】进行编译;选择菜单栏『调试』下的【启动 调试】或者按”F5” 键,执行程序。执行结果如下图所示: 7.2 Linux 下调用 ODBC 驱动步骤 1. 编译安装 unixodbc(建议使用 2.3.4 版本): 编译完成之后,生成文件夹如下: 38 第 7 章 KINGABSEES ODBC 驱动使用 2. 配置 ODBC 数据源-odbcinst.ini,odbc.ini; obcinst.ini 配置示例如下图: odbc.ini 配置示例如下图: 配置完成之后执行以下命令: export ODBCSYSINI=. export ODBCINSTINI=./odbcinst.ini export ODBCINI=./odbc.ini 3. 配置完成之后,使用 odbcinst –j 查看信息: 39 第 7 章 KINGABSEES ODBC 驱动使用 4. 编写测试用例,参考示例说明 中的” 连接样例”; 5. 编写 MakeFile: 6. 执行 make 进行编译,编译后文件夹如下图所示: 7. 执行用例: 40 第8章 示例说明 8 第 章 示例说明 本章节列举了几个 ODBC 常用到的示例程序: a. 常用的 ODBC 连接串 介绍不同的开发工具中使用的 ODBC 连接串。 b. 字典函数的应用 本示例调用的字典函数为 SQLTables。 c. 绑定参数为 BLOB 值 调 用 的 函 数 涉 及:SQLBindParameter,SQLParamData,SQLPutData,SQLPrepare,SQLExecute 等。 d. 获取 BLOB 列的值 调用的函数涉及:SQLFetch,SQLGetData,SQLExecDirect。 • 常用的 ODBC 连接串 • 连接样例 • 字典函数的应用 • 绑定参数为 BLOB 值 • 获取 BLOB 列的值 • 批量 DML 您可前往 人大金仓官网 下载 ODBC 测试用例 。 8.1 常用的 ODBC 连接串 本示例介绍不同的开发工具中使用的 ODBC 连接串。 下面的示例中均设定数据库名为 SAMPLES,用户名为 SYSTEM,密码为 MANAGER。在系统中已经配置了名 为 KingbaseES 的 ODBC 数据源。 41 第8章 示例说明 例 8.1-1. .NET .NET 环境下 ODBC 连接串的最大长度是 1024 个字符。一旦设置,就会被按原样传递给 ODBC Driver Manager 和 KingbaseES ODBC Driver。因此,连接串的语法必须与 ODBC Driver Manager 和 KingbaseES ODBC Driver 所 支持的语法完全匹配。 • ASP.NET 使用 ODBC 驱动程序名 using System.Data.Odbc; OdbcConnection conn = new OdbcConnection(); conn.ConnectionString = "Driver={KingbaseES 9 ODBC Driver};\ Server=127.0.0.1;\ Database=SAMPLES;\ Uid=SYSTEM;\ Pwd=MANAGER;"; conn.Open(); 使用 ODBC 数据源 using System.Data.Odbc; OdbcConnection conn = new OdbcConnection(); conn.ConnectionString = "Dsn=KingbaseES;Uid=SYSTEM;Pwd=MANAGER;"; conn.Open(); • VB.NET 使用 ODBC 驱动程序名 Imports System.Data.Odbc Dim conn As OdbcConnection = New OdbcConnection() conn.ConnectionString = "Driver={KingbaseES 9 ODBC Driver};\ Server=127.0.0.1;\ Database=SAMPLES;\ Uid=SYSTEM;\ Pwd=MANAGER;" conn.Open() 使用 ODBC 数据源 Imports System.Data.Odbc Dim conn As OdbcConnection = New OdbcConnection() conn.ConnectionString = "Dsn=KingbaseES;Uid=SYSTEM;Pwd=MANAGER;" conn.Open() 例 8.1-2. ASP • VBScript 42 第8章 示例说明 使用 ODBC 驱动程序名 <% Set conn = Server.CreateObject("ADODB.Connection") conn.Open "DRIVER={KingbaseES 9 ODBC Driver};\ DATABASE=SAMPLES;\ SERVER=127.0.0.1;\ UID=SYSTEM;\ PWD=MANAGER;" %> 使用 ODBC 数据源 <% Set conn = Server.CreateObject("ADODB.Connection") conn.Open "Dsn=KingbaseES;Uid=SYSTEM;Pwd=MANAGER;" %> • JavaScript 使用 ODBC 驱动程序名 <% var conn = new ActiveXObject("ADODB.Connection"); conn.Open("DRIVER={KingbaseES 9 ODBC Driver};\ DATABASE=SAMPLES;\ SERVER=127.0.0.1;\ UID=SYSTEM;\ PWD=MANAGER;"); %> 使用 ODBC 数据源 <% var conn = new ActiveXObject("ADODB.Connection"); conn.Open("Dsn=KingbaseES;Uid=SYSTEM;Pwd=MANAGER;"); %> 例 8.1-3. Delphi • ADO 组件 使用 ODBC 驱动程序名 ADOConnection1: TADOConnection; ADOConnection1.ConnectionString := 'DRIVER={KingbaseES 9 ODBC Driver};\ DATABASE=SAMPLES;\ SERVER=127.0.0.1;\ 43 第8章 示例说明 UID=SYSTEM;\ PWD=MANAGER;'; ADOConnection1.Open; 使用 ODBC 数据源 ADOConnection1: TADOConnection; ADOConnection1.ConnectionString := 'Provider=MSDASQL.1;\ Persist Security Info=False;\ User ID=SYSTEM;\ Data Source=KingbaseES'; ADOConnection1.Open; 8.2 连接样例 本示例展示了初始化创建连接和释放断开连接 #include #include#include#include #ifdef WIN32 #include #endif #include #include SQLHENV env; SQLHDBC conn; SQLHSTMT hstmt ; void test_connect_ext(char *extraparams) { SQLRETURN ret; SQLCHAR str[1024]; SQLSMALLINT strl; char dsn[1024]; const char * const test_dsn = "kingbase8"; char *envvar; snprintf(dsn, sizeof(dsn), "DSN=%s;%s", 44 第8章 示例说明 test_dsn, extraparams ? extraparams : ""); SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env); SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void *)SQL_OV_ODBC3, 0); SQLAllocConnect(env, &conn); ret = SQLDriverConnect(conn, NULL, (SQLCHAR*)dsn, SQL_NTS, str, sizeof(str), &strl, SQL_DRIVER_COMPLETE); if (SQL_SUCCEEDED(ret)) { SQLAllocHandle(SQL_HANDLE_STMT, conn, &hstmt); printf("connected\n"); } else { print_diag("SQLDriverConnect failed.", SQL_HANDLE_DBC, conn); exit(1); } } void test_disconnect(void) { SQLRETURN rc; printf("disconnecting\n"); rc = SQLDisconnect(conn); if (!SQL_SUCCEEDED(rc)) { print_diag("SQLDisconnect failed", SQL_HANDLE_DBC, conn); fflush(stdout); exit(1); } rc = SQLFreeHandle(SQL_HANDLE_DBC, conn); if (!SQL_SUCCEEDED(rc)) { print_diag("SQLFreeHandle failed", SQL_HANDLE_DBC, conn); fflush(stdout); exit(1); } 45 第8章 示例说明 conn = NULL; rc = SQLFreeHandle(SQL_HANDLE_ENV, env); if (!SQL_SUCCEEDED(rc)) { print_diag("SQLFreeHandle failed", SQL_HANDLE_ENV, env); fflush(stdout); exit(1); } env = NULL; } 字典函数的应用 8.3 本示例通过 SQLTables 的调用来说明对字典函数的使用。 #define STR_LEN 256 void TESTSQLTables(SQLPOINTER hdbc) { SQLCHAR szCatalog[STR_LEN] = ""; SQLCHAR szSchema[STR_LEN] = ""; SQLCHAR szTableName[STR_LEN] = ""; SQLCHAR szTableType[STR_LEN] = ""; SQLCHAR szRemarks[STR_LEN] = ""; SQLRETURN retcode; SQLHSTMT hstmt; SQLLEN cbCatalog, cbSchema, cbTableName, cbTableType, cbRemarks; retcode = SQLAllocStmt((SQLHDBC*)hdbc, &hstmt); retcode = SQLExecDirect(hstmt, (SQLCHAR *)"CREATE TABLE T(col int)", SQL_NTS); retcode = SQLTables(hstmt, NULL, 0, NULL, 0, (SQLCHAR*)"T", SQL_NTS, NULL, 0); if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) { 46 第8章 示例说明 SQLBindCol(hstmt, 1, SQL_C_CHAR, szCatalog, STR_LEN, &cbCatalog); SQLBindCol(hstmt, 2, SQL_C_CHAR, szSchema, STR_LEN, &cbSchema); SQLBindCol(hstmt, 3, SQL_C_CHAR, szTableName, STR_LEN, &cbTableName); SQLBindCol(hstmt, 4, SQL_C_CHAR, szTableType, STR_LEN, &cbTableType); SQLBindCol(hstmt, 5, SQL_C_CHAR, szRemarks, STR_LEN, &cbRemarks); while (1) { retcode = SQLFetch(hstmt); if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) printf("Catalog = %s\tSchema=%s\tTableName=%s\tTableType=%s\tRemarks=%s\n", szCatalog, szSchema, szTableName, szTableType, szRemarks); else break; } } else printf("Error!\n"); retcode = SQLFreeStmt(hstmt, SQL_CLOSE); retcode = SQLExecDirect(hstmt, (SQLCHAR *)"DROP TABLE T", SQL_NTS); retcode = SQLFreeStmt(hstmt, SQL_DROP); } 8.4 绑定参数为 BLOB 值 该函数通过绑定 BLOB 值的形式可将大于 1K 的文件插入到表 LargeObject 中。 调用的函数涉及:SQLBindParameter,SQLParamData,SQLPutData,SQLPrepare,SQLExecute 等。 #define MAX_DATA_LEN 8192 #define MAX_FILE_NAME_LEN 1024 int InitUserData(SWORD sParam, FILE **fp) { 47 第8章 char 示例说明 szPhotoFile[MAX_FILE_NAME_LEN]; switch (sParam) { case 1: strcpy(szPhotoFile, "c:\\col1.txt"); break; case 2: strcpy(szPhotoFile, "c:\\col2.txt"); break; default: printf("ERROR\n"); return -1; } printf("file name is: %s\n", szPhotoFile); *fp = fopen(szPhotoFile, "rb"); if (*fp == NULL) { printf(" 打开文件错误\n"); return (-1); } return 0; } int GetUserData( FILE *fp, SWORD sParam, SQLCHAR *Data, SQLLEN *cbData) { *cbData = fread(Data, 1, MAX_DATA_LEN, fp); if (*cbData < 0) { printf(" 从文件中读数据出错\n"); fclose(fp); return 0; } if (*cbData == 0) { printf(" 读到文件尾\n"); *cbData = SQL_NULL_DATA; 48 第8章 示例说明 fclose(fp); } return 1; } int INSERT_BLOB(SQLPOINTER hdbc) { SQLLEN cbCol1, cbCol2, cbData; SQLPOINTER pToken; SQLCHAR Data[MAX_DATA_LEN]; SQLRETURN retcode; SQLHSTMT hstmt; FILE *fp; retcode = SQLAllocStmt((SQLHDBC)(hdbc), &hstmt); retcode = SQLExecDirect(hstmt, (SQLCHAR *)"CREATE TABLE LargeObject(col1 blob, col2 blob)", SQL_NTS); if (SQLPrepare(hstmt, (SQLCHAR *)"INSERT INTO LargeObject VALUES (?, ?)", SQL_NTS) < 0) { printf("SQLPrepare err...\n"); return SQL_ERROR; } /* * 设置值,以便参数的数据将在执行时传递。 * 注意, SQL_LEN_DATA_AT_EXEC 中的长度参数为 0。 */ cbCol1 = cbCol2 = SQL_LEN_DATA_AT_EXEC(0); if (SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARBINARY, 0, 0, (SQLPOINTER)(1), 0, &cbCol1) < 0) { printf("SQLBindParameter binding para err...\n"); return SQL_ERROR; } if (SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARBINARY, 0, 0, (SQLPOINTER)(2), 0, &cbCol2) < 0) 49 第8章 示例说明 { printf("SQLBindParameter binding para err...\n"); return SQL_ERROR; } retcode = SQLExecute(hstmt); /* * 对于执行时的数据参数,调用 SQLParamdata 获取由 * SQLBindParameter 设置的参数。 * 调用 InitUserData. 循环调用 GetUserData 和 SQLPutData * 来获取和放置参数的所有数据。 * 然后调用 SQLParamData 来完成该参数的处理。 */ while (retcode == SQL_NEED_DATA){ retcode = SQLParamData(hstmt, &pToken); if (retcode == SQL_NEED_DATA) { if (InitUserData((SQLLEN)pToken, &fp) < 0) return (-1); while (GetUserData(fp, (SQLLEN)pToken, Data, &cbData)) { if (SQLPutData(hstmt, Data, cbData) < 0) { printf("SQLPutData error.......\n"); return SQL_ERROR; } if (cbData < MAX_DATA_LEN || cbData == SQL_NULL_DATA) break; } } } retcode = SQLFreeStmt(hstmt, SQL_DROP); return SQL_SUCCESS; } 50 第8章 示例说明 获取 BLOB 列的值 8.5 该示例从包括一个 BLOB 列的 LargeObject 表中取得 BLOB 列的值,并且将取得的 BLOB 列数据存储到 文件中。假设 LargeObject 中有 3 个元组,那么最后通过该程序获得的 BLOB 列值分别存储在以下六个文件中: Blob_row1_col1,Blob_row1_col2,Blob_row2_col1,Blob_row2_col2,Blob_row3_col1,Blob_row3_col2。 调用的函数涉及:SQLFetch,SQLGetData,SQLExecDirect。 #define BUF_LEN 8192 void MultiBlobQuery(SQLPOINTER hdbc) { SQLRETURN ret; SQLHSTMT hstmt; char buffer[BUF_LEN]; SQLLEN real_len; short col_count, errlen; int i, j; FILE *fp = NULL; unsigned char sqlstate[6] = ""; char filename[50] = ""; printf("---------Test Multi Blob--------\n"); ret = SQLAllocStmt((SQLHDBC*)hdbc, &hstmt); memset(buffer, '\0', BUF_LEN); ret = SQLExecDirect(hstmt, (SQLCHAR *)"SELECT col1, col2 FROM LargeObject", SQL_NTS); ret = SQLNumResultCols(hstmt, &col_count); j = 1; while ((ret = SQLFetch(hstmt)) != SQL_NO_DATA_FOUND) { for(i = 0; i < col_count; i++) { ret = SQLGetData(hstmt, (SQLUSMALLINT)(i+1), SQL_C_BINARY, buffer, BUF_LEN, &real_len); if (real_len != SQL_NULL_DATA) { sprintf(filename, "c:\\Blob_row%d_col%d.txt", j, i+1); 51 第8章 示例说明 fp = fopen(filename, "wb"); if (real_len > BUF_LEN) real_len = BUF_LEN; fwrite(buffer, real_len, 1, fp); printf(" COL%d's name: %s\n", i+1, filename); } else { printf(" COL%d: NULL", i+1); } while (ret == SQL_SUCCESS_WITH_INFO) { ret = SQLError(NULL, NULL, hstmt, sqlstate, NULL, NULL, 0, &errlen); ret = SQLGetData(hstmt, (SQLUSMALLINT)(i+1), SQL_C_BINARY, buffer, BUF_LEN, &real_len); if (ret != SQL_ERROR) { if (real_len > BUF_LEN) real_len = BUF_LEN; fwrite(buffer, real_len, 1, fp); } } } j++; } fclose(fp); ret = SQLFreeStmt(hstmt, SQL_DROP); } 8.6 批量 DML 调用的函数涉及:SQLSetConnectAttr,SQLPrepare,SQLSetStmtAttr,SQLBindParameter,SQLExecute。 #define ARRAY_SIZE 100 52 第8章 示例说明 void print_diag(char *msg, SQLSMALLINT htype, SQLHANDLE handle) { char sqlstate[32]; char message[1000]; SQLINTEGER nativeerror; SQLSMALLINT textlen; SQLRETURN ret; SQLSMALLINT recno = 0; if (msg) printf("%s\n", msg); do { recno++; ret = SQLGetDiagRec(htype, handle, recno, (SQLCHAR*)sqlstate, &nativeerror, (SQLCHAR*)message, sizeof(message), &textlen); if (ret == SQL_INVALID_HANDLE) printf("Invalid handle\n"); else if (SQL_SUCCEEDED(ret)) printf("%s=%s\n", sqlstate, message); } while (ret == SQL_SUCCESS); if (ret == SQL_NO_DATA && recno == 1) printf("No error information\n"); } int Batch_inset_all_sucess() { SQLRETURN rc; HSTMT hstmt = SQL_NULL_HSTMT; char *sql; int i; SQLUINTEGER int_array[ARRAY_SIZE]; char *param1_blob; char *param1_clob; char *param1_float; char *param1_timestamp; char *param1_char; char *param1_varchar; SQLLEN nCount = 0; 53 第8章 示例说明 SQLLEN int_ind_array[ARRAY_SIZE]; SQLLEN str_ind_array[ARRAY_SIZE]; SQLUSMALLINT status_array[ARRAY_SIZE]; SQLULEN nprocessed; struct timeval start, end; long mtime, seconds, useconds; rc = SQLAllocHandle(SQL_HANDLE_STMT, conn, &hstmt); if (!SQL_SUCCEEDED(rc)) { print_diag("failed to allocate stmt handle", SQL_HANDLE_DBC, conn); exit(1); } rc = SQLExecDirect(hstmt, (SQLCHAR *)"drop table if exists tmptable", SQL_NTS); if (!SQL_SUCCEEDED(rc)) { print_diag("SQLExecDirect failed while creating temp table", SQL_HANDLE_STMT, hstmt); exit(1); } sql = "CREATE TABLE tmptable (c1 int4 primary key, c2 varchar, c3 char(2) \ , c4 NUMBER(4,2), c5 NUMBER(4, 2), c6 timestamp, c7 blob, c8 bytea, c9 char(4) \ , c10 char(4), c11 char(4), c12 char(4), c13 char(4))"; rc = SQLExecDirect(hstmt, (SQLCHAR *)sql, SQL_NTS); if (!SQL_SUCCEEDED(rc)) { print_diag("SQLExecDirect failed while creating temp table", SQL_HANDLE_STMT, hstmt); exit(1); } rc = SQLFreeStmt(hstmt, SQL_CLOSE); if (!SQL_SUCCEEDED(rc)) { print_diag("SQLFreeStmt failed", SQL_HANDLE_STMT, hstmt); exit(1); } 54 第8章 示例说明 int nVarcharLength = 0; int nCharLength = 0; int nLength_time = 0; int nLength_lob = 0; int param1_blob_length = 4097; int param1_clob_length = 5; int param1_float_length = 5; int param1_timestamp_length = 21; int param1_varchar_length = 5; int param1_char_length = 3; param1_blob = (char *)malloc(ARRAY_SIZE * sizeof(char) * param1_blob_length); memset(param1_blob, 0, ARRAY_SIZE * sizeof(char) * param1_blob_length); param1_clob = (char *)malloc(ARRAY_SIZE * sizeof(char) * param1_clob_length); memset(param1_clob, 0, ARRAY_SIZE * sizeof(char) * param1_clob_length); param1_float = (char*)malloc(ARRAY_SIZE * param1_float_length); memset(param1_float, 0, ARRAY_SIZE * param1_float_length * sizeof(char)); param1_timestamp = (char*)malloc(ARRAY_SIZE * param1_timestamp_length * sizeof(char)); memset(param1_timestamp, 0, ARRAY_SIZE * param1_timestamp_length * sizeof(char)); param1_varchar = (char*)malloc(ARRAY_SIZE * param1_varchar_length * sizeof(char)); memset(param1_varchar, 0, ARRAY_SIZE * param1_varchar_length * sizeof(char)); param1_char = (char*)malloc(ARRAY_SIZE * param1_char_length * sizeof(char)); memset(param1_char, 0, ARRAY_SIZE * param1_char_length * sizeof(char)); for (i = 0; i < ARRAY_SIZE; i++) { int_array[i] = i + 1; int_ind_array[i] = 0; int str_array2_length = 5; int str_array3_length = 4097; int str_array4_length = 5; char *str_array2 = (char *)malloc(str_array2_length); char *str_array3 = (char *)malloc(str_array3_length); char *str_array4 = (char *)malloc(str_array4_length); char a = 'a' + i % 26; memset(str_array2, 0, str_array2_length); memset(str_array2, 'a', str_array2_length - 1); 55 第8章 示例说明 memset(str_array3, 0, str_array3_length); memset(str_array3, 'a', str_array3_length - 1); memset(str_array4, 0, str_array4_length); memset(str_array4, 'b', str_array4_length - 1); str_ind_array[i] = SQL_NTS; strncpy(param1_varchar + nVarcharLength, (const char *)str_array2, str_array2_length); strncpy(param1_blob + nLength_lob, (const char *)str_array3, str_array3_length); strncpy(param1_clob + nVarcharLength, (const char *)str_array4, str_array4_length); strncpy(param1_float + nVarcharLength, "3.40", 4); strncpy(param1_timestamp + nLength_time, "2017-02-23 11:34:46", 20); strncpy(param1_char + nCharLength, "cc", 2); nVarcharLength += 5; nCharLength += 3; nLength_lob += 4097; nLength_time += 21; } SQLSetStmtAttr(hstmt, SQL_ATTR_PARAM_BIND_TYPE, SQL_PARAM_BIND_BY_COLUMN, 0); SQLSetStmtAttr(hstmt, SQL_ATTR_PARAM_STATUS_PTR, status_array, 0); SQLSetStmtAttr(hstmt, SQL_ATTR_PARAMSET_SIZE, (SQLPOINTER)ARRAY_SIZE, 0); SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 5, 0, int_array, 0, int_ind_array); SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 29, 0, param1_varchar, param1_varchar_length, str_ind_array); SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 29, 0, param1_char, param1_char_length, str_ind_array); SQLBindParameter(hstmt, 4, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_FLOAT, 20, 0, param1_float, 0, str_ind_array); SQLBindParameter(hstmt, 5, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_FLOAT, 20, 0, param1_float, 0, str_ind_array); SQLBindParameter(hstmt, 6, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_TIMESTAMP, 20, 0, param1_timestamp, param1_timestamp_length, str_ind_array); SQLBindParameter(hstmt, 7, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARBINARY, 0, 0, param1_blob, param1_timestamp_length, str_ind_array); SQLBindParameter(hstmt, 8, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARBINARY, 0, 0, 56 第8章 示例说明 param1_clob, param1_clob_length, str_ind_array); SQLBindParameter(hstmt, 9, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 29, 0, param1_varchar, param1_varchar_length, str_ind_array); SQLBindParameter(hstmt, 10, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 29, 0, param1_varchar, param1_varchar_length, str_ind_array); SQLBindParameter(hstmt, 11, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 29, 0, param1_varchar, param1_varchar_length, str_ind_array); SQLBindParameter(hstmt, 12, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 29, 0, param1_varchar, param1_varchar_length, str_ind_array); SQLBindParameter(hstmt, 13, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 29, 0, param1_varchar, param1_varchar_length, str_ind_array); sql = "insert INTO tmptable VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; rc = SQLPrepare(hstmt, (SQLCHAR*)sql, SQL_NTS); rc = SQLExecute(hstmt); if (rc < 0) return nCount; if (!SQL_SUCCEEDED(rc)) { print_diag("SQLExecDirect failed", SQL_HANDLE_STMT, hstmt); exit(1); } free(param1_blob); free(param1_float); free(param1_timestamp); free(param1_char); free(param1_varchar); rc = SQLRowCount(hstmt, &nCount); return nCount; } 57 第9章 疑难解答 9 第 章 疑难解答 • Q:当行集大于 1 时,将 SQLFetchScroll 与 SQLBindCol 联合使用,为什么有时候取到的结果不正确? A:这是因为 SQLFetchScroll 在获取结果时一次获取的是行集数目的元组数,而 SQLBindCol 绑定的输出 缓冲区不够大。 如:行集为 3 时 SQLFetchScroll 绑定列为第一列,那么第一次执行了 SQLFetchScroll 之后,前三个元组 的第一列将获取到本地缓冲区;当第二次执行 SQLFetchScroll 之后,第 4-6 个元组的第一列将获取到本 地缓冲区;依此类推。 如果该列为 INT 类型,那么 SQLBindCol 绑定的输出缓冲区必须为 int val[3],或者有更多的空间,而不 能是 int val。 • Q:SQLBindParameter 的绑定参数区应该在 SQLBindParameter 调用之前赋值还是在 SQLBindParameter 调 用之后赋值? A:都可以。 例如: SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 200, 0, &col1, 200, &reallen1); strcpy(col1, "Bill Gates"); 与下面的调用效果是一样的: strcpy(col1, "Bill Gates"); SQLBindParameter(hstmt, 1, 58 第9章 疑难解答 SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 200, 0, &col1, 200, &reallen1); • Q:使用 CREATE TABLE Foo(Bar CHAR(8)); 语句创建了一个表,并插入了一条记录,列值为’ 中国’,执行下 列函数序列时,为什么执行 SQLFetch 时出错? 例如. 调用 SQLExecDirect 和 SQLFetch 获取列值 int Select(SQLHDBC hdbc) { char sqlstr[100]; SQLHSTMT hstmt; SQLRETURN rc; char szBuffer[9]; SQLINTEGER cbCol = SQL_NTS; strcpy(sqlstr, "SELECT bar FROM foo;"); rc = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt); if (rc == SQL_ERROR) return -1; rc = SQLExecDirect(hstmt, (SQLCHAR *)sqlstr, SQL_NTS); if (rc == SQL_ERROR) goto ErrorExit; rc = SQLBindCol(hstmt, 1, SQL_C_CHAR, szBuffer, 9, &cbCol); if (rc == SQL_ERROR) goto ErrorExit; rc = SQLFetch(hstmt); if (rc == SQL_ERROR) goto ErrorExit; ErrorExit: SQLFreeHandle(SQL_HANDLE_STMT, hstmt); return rc; } 59 第9章 疑难解答 A:这个错误通常出现在数据库编码为“GBK”的情况下。列定义 CHAR(n) 中的 n 表示的是 n 个字符, 如果插入的列值中有中文字符等多字节字符,则 ODBC 取出的列值长度很可能会超过 n 个字节。如果绑 定的缓冲区大小仍然按照 n 个字节提供,则它很可能不够大,导致“列值被截断”的错误。 因此,当数据库的编码为“GBK”,并且 CHAR 类型字段中可能存放多字节字符时,应用程序在绑定结 果集或者绑定参数时,应提供足够大的缓冲区。缓冲区大小至少应该为 n 的 2 倍。若考虑到 C/C++ 字 符串结尾的’0’,则缓冲区大小至少为 2*n+1。 • Q:如果不创建 ODBC 数据源,如何与数据库建立连接? A:可以调用 SQLDriverConnect 方法,在参数中指定要使用的 ODBC Driver 的名字以及需要的连接属 性。 例如: SQLDriverConnect(hdbc, NULL, "DRIVER={KingbaseES 9 ODBC Driver};SERVER= 127.0.0.1;UID=SYSTEM; PWD=MANAGER;DATABASE=TEST;PORT=54321", SQL_NTS, conn_string, sizeof(conn_string), &len, SQL_DRIVER_NOPROMPT); • Q:为什么 Windows XP + sp2 平台上不能安装 MDAC2.8?在安装过程中弹出提示信息:“This version is incompatible with the version you are attempting to install”? A:这是正常的,因为 sp2 自身已带有 MDAC 2.8。要升级 MDAC 的版本必须升级 SERVICE PACK。 • Q:如何修复 Windows XP + sp2 平台上的受损的 MDAC2.8? A:因为病毒或安装某些软件的原因,您计算机上的 MDAC2.8 组件可能被损坏,导致 ADO、OLEDB、 ODBC 等连接功能不正常等问题。这时您可以通过如下步骤修复 MDAC2.8: 首先设置资源管理器可以显示隐藏文件和系统文件,右键单击%systemroot%windowsMDAC.INF(%systemroot% 是您安装 WindowsXP 的盘符,一般是 C:),在弹出菜单上单击“安装”项,当提示您“需要 Windows XP Professional Service Pack2 CD 上的文件’adcjavas.inc’”的时候,单击“浏览”按钮,从 SP2 的安装程序光盘或目录的 I386 子目录下找到文件 ADCJAVAS.IN_ ,点击打开该文件,然后单击“确定” 按钮,完成安装。这样,MDAC2.8 就会被修复了。 60 版权声明 版权声明 北京人大金仓信息技术股份有限公司(简称:人大金仓)版权所有,并保留对本手册及本声明的一切权利。 未得到人大金仓的书面许可,任何人不得以任何方式或形式对本手册内的任何部分进行复制、摘录、备份、修 改、传播、翻译成其他语言、将其全部或部分用于商业用途。 免责声明 本手册内容依据现有信息制作,由于产品版本升级或其他原因,其内容有可能变更。人大金仓保留在没有任何通 知或者提示的情况下对手册内容进行修改的权利。 本手册仅作为使用指导,人大金仓在编写本手册时已尽力保证其内容准确可靠,但并不确保手册内容完全没有错 误或遗漏,本手册中的所有信息也不构成任何明示或暗示的担保。 技术支持 • 人大金仓官方网站:http://www.kingbase.com.cn/ • 人大金仓文档中心:http://help.kingbase.com.cn/ • 全国服务热线:400-601-1188 • 人大金仓技术支持与反馈信箱:support@kingbase.com.cn 61 服务周期承诺 服务周期承诺 由于市场需求在不断变化,技术创新和发展的进程不断加剧,产品的版本更迭不可避免。人大金仓对于产品版本 生命周期的有效管理,有助于您提前规划项目,更好地从产品服务终止上过渡。 表 1: KingbaseES 产品生命周期里程碑 关键里程碑点 定义 产品发布日期 产品正式发布版本,即 GA(general availability)版本的发布日期。 停止销售日期 正式停止销售的日期,版本停止接受订单日。该日之后,产品将不再销售。 停止功能升级日期 在该日期之后,不再提供新特性和新硬件支持。但依旧提供错误修复、安全修复、功 能维护等服务。 停止功能维护日期 在该日期之后,不再维护功能,修复问题。但依旧提供安全修复等服务 停止安全维护日期 在该日期之后,不再发布补丁版本修复中高风险漏洞,仅提供有限的支持。 产品服务终止日期 停止提供产品服务和支持的日期。包括软件维护版本,缺陷修复,以及针对该产品的 所有服务支持(包括服务热线和远程/现场支持)。 服务周期策略 金仓数据库管理系统 KingbaseES 产品确保以下的服务周期: 1)产品自发布之日起至产品停止功能升级(包含新特性、新硬件支持)之日不少于 5 年。 2)产品停止功能升级之日起至产品停止功能维护(主要包括问题修复)之日不少于 4 年。 3)产品功能维护停止之日起至产品停止安全维护(包括中高风险漏洞修复)之日不少于 2 年。 服务终止策略 金仓数据库管理系统 KingbaseES 产品确保在销售后,至少提供 6 年的服务支持。 注意: 人大金仓将会综合各方因素来确定产品服务终止日期。并将在实际产品服务终止日期之前至少 90 天,通过公 62 服务周期承诺 开方式宣布产品服务终止日期。 63

相关文章