ODBC
ODBC(Open Database Connectivity,开放数据库互连)是由Microsoft公司基于X/OPEN CLI提出的用于访问数据库的应用程序编程接口。应用程序通过ODBC提供的API与数据库进行交互,增强了应用程序的可移植性、扩展性和可维护性。
ODBC的系统结构参见图1。
图 1 ODBC系统机构

openGauss目前在以下环境中提供对ODBC的支持。
表 1 ODBC支持平台
| 操作系统 | 平台 |
|---|---|
| CentOS 6.4/6.5/6.6/6.7/6.8/6.9/7.0/7.1/7.2/7.3/7.4 | x86_64位 |
| CentOS 7.6 | ARM64位 |
| EulerOS 2.0 SP2/SP3 | x86_64位 |
| EulerOS 2.0 SP8 | ARM64位 |
Linux下的ODBC包
从发布包中获取,包名为openGauss-*.*.0-ODBC.tar.gz。Linux环境下,开发应用程序要用到unixODBC提供的头文件(sql.h、sqlext.h等)和库libodbc.so。这些头文件和库可从unixODBC-2.3.0的安装包中获得。
配置数据源
将openGauss提供的ODBC DRIVER(psqlodbcw.so)配置到数据源中便可使用。配置数据源需要配置“odbc.ini”和“odbcinst.ini”两个文件(在编译安装unixODBC过程中生成且默认放在“/usr/local/etc”目录下),并在服务器端进行配置。
- 获取unixODBC-2.3.9源码包。
获取参考地址:<http://www.unixodbc.org/download.html> 2. 安装unixODBC。如果机器上已经安装了其他版本的unixODBC,可以直接覆盖安装。
目前不支持unixODBC-2.2.1版本。以unixODBC-2.3.0版本为例,在客户端执行如下命令安装unixODBC。默认安装到“/usr/local”目录下,生成数据源文件到 “/usr/local/etc”目录下,库文件生成在“/usr/local/lib”目录。
``` 1. tar zxvf unixODBC-2.3.9.tar.gz 2. cd unixODBC-2.3.9 3. #修改configure文件(如果不存在,那么请修改configure.ac),找到LIB_VERSION 4. #将它的值修改为"1:0:0",这样将编译出*.so.1的动态库,与psqlodbcw.so的依赖关系相同。 5. vim configure
- ./configure --enable-gui=no #如果要在ARM服务器上编译,请追加一个configure参数: --build=aarch64-unknown-linux-gnu
- make
-
安装可能需要root权限
- make install ```
-
替换客户端openGauss驱动程序。
-
将openGauss-x.x.x-ODBC.tar.gz解压到“/usr/local/lib”目录下。解压会得到“psqlodbcw.la”和“psqlodbcw.so”两个文件。
- 将openGauss-x.x.x-ODBC.tar.gz解压后lib目录中的库拷贝到“/usr/local/lib”目录下。
-
配置数据源。
-
配置ODBC驱动文件。
在“/xxx/odbc/etc/odbcinst.ini”文件中追加以下内容。
1. [GaussMPP] 2. Driver64=/xxx/odbc/lib/psqlodbcw.so 3. setup=/xxx/odbc/lib/psqlodbcw.soodbcinst.ini文件中的配置参数说明如表2所示。
表 2 odbcinst.ini文件配置参数
参数 描述 示例 [DriverName] 驱动器名称,对应数据源DSN中的驱动名。 [DRIVER_N] Driver64 驱动动态库的路径。 Driver64=/xxx/odbc/lib/psqlodbcw.so setup 驱动安装路径,与Driver64中动态库的路径一致。 setup=/xxx/odbc/lib/psqlodbcw.so 2. 配置数据源文件。 在“/usr/local/etc/odbc.ini”文件中追加以下内容。
1. [MPPODBC] 2. Driver=GaussMPP 3. Servername=10.145.130.26(数据库Server IP) 4. Database=postgres (数据库名) 5. Username=omm (数据库用户名) 6. Password= (数据库用户密码) 7. Port=8000 (数据库侦听端口) 8. Sslmode=allowodbc.ini文件配置参数说明如表3所示。
表 3 odbc.ini文件配置参数
参数 描述 示例 [DSN] 数据源的名称。 [MPPODBC] Driver 驱动名,对应odbcinst.ini中的DriverName。 Driver=DRIVER_N Servername 服务器的IP地址。 Servername=10.145.130.26 Database 要连接的数据库的名称。 Database=postgres Username 数据库用户名称。 Username=omm Password 数据库用户密码。 Password= 说明: ODBC驱动本身已经对内存密码进行过清理,以保证用户密码在连接后不会再在内存中保留。 但是如果配置了此参数,由于UnixODBC对数据源文件等进行缓存,可能导致密码长期保留在内存中。 推荐在应用程序连接时,将密码传递给相应API,而非写在数据源配置文件中。同时连接成功后,应当及时清理保存密码的内存段。 Port 服务器的端口号。 Port=8000 Sslmode 开启SSL模式 Sslmode=allow Debug 设置为1时,将会打印psqlodbc驱动的mylog,日志生成目录为/tmp/。设置为0时则不会生成。 Debug=1 UseServerSidePrepare 是否开启数据库端扩展查询协议。 可选值0或1,默认为1,表示打开扩展查询协议。 UseServerSidePrepare=1 UseBatchProtocol 是否开启批量查询协议(打开可提高DML性能);可选值0或者1,默认为1。 当此值为0时,不使用批量查询协议(主要用于与早期数据库版本通信兼容)。 当此值为1,并且数据库support_batch_bind参数存在且为on时,将打开批量查询协议。 UseBatchProtocol=1 ForExtensionConnector 这个开关控制着savepoint是否发送,savepoint相关问题可以注意这个开关。 ForExtensionConnector=1 UnamedPrepStmtThreshold 每次调用SQLFreeHandle释放Stmt时,ODBC都会向server端发送一个Deallocate plan_name语句,业务中存在大量这类语句。为了减少这类语句的发送,我们将 stmt->plan_name置空,从而使得数据库识别这个为unamed stmt。增加这个参数对unamed stmt的阈值进行控制。 UnamedPrepStmtThreshold=100 ConnectionExtraInfo GUC参数connection_info中显示驱动部署路径和进程属主用户的开关。 ConnectionExtraInfo=1 说明: 默认值为0。当设置为1时,ODBC驱动会将当前驱动的部署路径、进程属主用户上报到数据库中,记录在connection_info参数里;同时可以在PG_STAT_ACTIVITY中查询到。 BoolAsChar 设置为Yes是,Bools值将会映射为SQL_CHAR。如不设置将会映射为SQL_BIT。 BoolsAsChar = Yes RowVersioning 当尝试更新一行数据时,设置为Yes会允许应用检测数据有没有被其他用户进行修改。 RowVersioning=Yes ShowSystemTables 驱动将会默认系统表格为普通SQL表格。 ShowSystemTables=Yes 其中关于Sslmode的选项的允许值,具体信息见下表:
表 4 Sslmode的可选项及其描述
Sslmode 是否会启用SSL加密 描述 disable 否 不使用SSL安全连接。 allow 可能 如果数据库服务器要求使用,则可以使用SSL安全加密连接,但不验证数据库服务器的真实性。 prefer 可能 如果数据库支持,那么建议使用SSL安全加密连接,但不验证数据库服务器的真实性。 require 是 必须使用SSL安全连接,但是只做了数据加密,而并不验证数据库服务器的真实性。 verify-ca 是 必须使用SSL安全连接,并且验证数据库是否具有可信证书机构签发的证书。 verify-full 是 必须使用SSL安全连接,在verify-ca的验证范围之外,同时验证数据库所在主机的主机名是否与证书内容一致。openGauss不支持此模式。
说明: SSL模式: 保证client.key*系列文件为600权限: 退回根目录,创建.postgresql目录,并将root.crt,client.crt,client.key,client.key.cipher,client.key.rand,client.req,server.crt,server.key,server.key.cipher,server.key.rand,server.req放在此路径下。 Unix系统下,server.crt、server.key的权限设置必须禁止任何外部或组的访问,请执行如下命令实现这一点。1. chmod 0600 server.key将root.crt以及server开头的证书相关文件全部拷贝进数据库install/data目录下(与postgresql.conf文件在同一路径)。 修改postgresql.conf文件:
1. ssl = on 2. ssl_cert_file = 'server.crt' 3. ssl_key_file = 'server.key' 4. ssl_ca_file = 'root.crt'修改完参数后需重启数据库。 修改配置文件odbc.ini中的sslmode参数(require或verify-ca)。 5. 配置数据库服务器。
-
以操作系统用户omm登录数据库主节点。
-
执行如下命令增加对外提供服务的网卡IP或者主机名(英文逗号分隔),其中NodeName为当前节点名称:
1. gs_guc reload -N NodeName -I all -c "listen_addresses='localhost,192.168.0.100,10.11.12.13'"在DR(Direct Routing,LVS的直接路由DR模式)模式中需要将虚拟IP地址(10.11.12.13)加入到服务器的侦听地址列表中。
listen_addresses也可以配置为“*”或“0.0.0.0”,此配置下将侦听所有网卡,但存在安全风险,不推荐用户使用,推荐用户按照需要配置IP或者主机名,打开侦听。 3. 执行如下命令在数据库主节点配置文件中增加一条认证规则。(这里假设客户端IP地址为10.11.12.13,即远程连接的机器的IP地址)
1. gs_guc reload -N all -I all -h "host all jack 10.11.12.13/32 sha256"
说明:- -N all表示openGauss中的所有主机。
- -I all表示主机中的所有实例。
- -h表示指定需要在“pg_hba.conf”增加的语句。
- all表示允许客户端连接到任意的数据库。
- jack表示连接数据库的用户。
- 10.11.12.13/_32_表示只允许IP地址为10.11.12.13的主机连接。在使用过程中,请根据用户的网络进行配置修改。32表示子网掩码为1的位数,即255.255.255.255。
- sha256表示连接时jack用户的密码使用sha256算法加密。
如果将ODBC客户端配置在和要连接的数据库主节点在同一台机器上,则可使用local trust认证方式,如下:
1. local all all trust如果将ODBC客户端配置在和要连接的数据库主节点在不同机器上,则需要使用sha256认证方式,如下:
1. host all all xxx.xxx.xxx.xxx/32 sha2564. 重启openGauss。1. gs_om -t stop 2. gs_om -t start6. 在客户端配置环境变量。
1. vim ~/.bashrc
在配置文件中追加以下内容。
1. export LD_LIBRARY_PATH=/usr/local/lib/:$LD_LIBRARY_PATH
2. export ODBCSYSINI=/usr/local/etc
3. export ODBCINI=/usr/local/etc/odbc.ini
7. 执行如下命令使设置生效。
1. source ~/.bashrc
测试数据源配置
执行./isql -v MPPODBC(数据源名称)命令。
- 如果显示如下信息,表明配置正确,连接成功。
1. +---------------------------------------+
2. | Connected! |
3. | |
4. | sql-statement |
5. | help [tablename] |
6. | quit |
7. | |
8. +---------------------------------------+
9. SQL>
- 若显示ERROR信息,则表明配置错误。请检查上述配置是否正确。
开发流程
图 2 ODBC开发应用程序的流程

常用接口
表 5 相关API说明
| 功能 | API |
|---|---|
| 申请句柄资源 | SQLAllocHandle:申请句柄资源,可替代如下函数: - SQLAllocEnv:申请环境句柄 - SQLAllocConnect:申请连接句柄 - SQLAllocStmt:申请语句句柄 |
| 设置环境属性 | SQLSetEnvAttr |
| 设置连接属性 | SQLSetConnectAttr |
| 设置语句属性 | SQLSetStmtAttr |
| 连接数据源 | SQLConnect |
| 绑定缓冲区到结果集的列中 | SQLBindCol |
| 绑定SQL语句的参数标志和缓冲区 | SQLBindParameter |
| 查看最近一次操作错误信息 | SQLGetDiagRec |
| 为执行SQL语句做准备 | SQLPrepare |
| 执行一条准备好的SQL语句 | SQLExecute |
| 直接执行SQL语句 | SQLExecDirect |
| 结果集中取行集 | SQLFetch |
| 返回结果集中某一列的数据 | SQLGetData |
| 获取结果集中列的描述信息 | SQLColAttribute |
| 断开与数据源的连接 | SQLDisconnect |
| 释放句柄资源 | SQLFreeHandle:释放句柄资源,可替代如下函数: - SQLFreeEnv:释放环境句柄 - SQLFreeConnect:释放连接句柄 - SQLFreeStmt:释放语句句柄 |
说明: 数据库中收到的一次执行请求(不在事务块中),如果含有多条语句,将会被打包成一个事务,同时如果其中有一个语句失败,那么整个请求都将会被回滚。
连接数据库
1. #include <stdlib.h>
2. #include <stdio.h>
3. #include <sqlext.h>
4. #ifdef WIN32
5. #include <windows.h>
6. #endif
7. SQLHENV V_OD_Env; // Handle ODBC environment
8. SQLHDBC V_OD_hdbc; // Handle connection
9. SQLINTEGER V_OD_erg;
10. int main(int argc,char *argv[])
11. {
12. // 1. 申请环境句柄
13. V_OD_erg = SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&V_OD_Env);
14. if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
15. {
16. printf("Error AllocHandle\n");
17. exit(0);
18. }
19. // 2. 设置环境属性(版本信息)
20. SQLSetEnvAttr(V_OD_Env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
21. // 3. 申请连接句柄
22. V_OD_erg = SQLAllocHandle(SQL_HANDLE_DBC, V_OD_Env, &V_OD_hdbc);
23. if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
24. {
25. SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
26. exit(0);
27. }
28. // 4. 设置连接属性
29. SQLSetConnectAttr(V_OD_hdbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_ON, 0);
30. // 5. 连接数据源,这里的“userName”与“password”分别表示连接数据库的用户名和用户密码,请根据实际情况修改。
31. // 如果odbc.ini文件中已经配置了用户名密码,那么这里可以留空("");但是不建议这么做,因为一旦odbc.ini权限管理不善,将导致数据库用户密码泄露。
32. V_OD_erg = SQLConnect(V_OD_hdbc, (SQLCHAR*) "gaussdb", SQL_NTS,
33. (SQLCHAR*) "userName", SQL_NTS, (SQLCHAR*) "password", SQL_NTS);
34. if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
35. {
36. printf("Error SQLConnect %d\n",V_OD_erg);
37. SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
38. exit(0);
39. }
40. printf("Connected !\n");
41. // 6. 断开数据源连接并释放句柄资源
42. SQLDisconnect(V_OD_hdbc);
43. SQLFreeHandle(SQL_HANDLE_DBC,V_OD_hdbc);
44. SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
45. return(0);
46. }
创建表
1. #include <stdlib.h>
2. #include <stdio.h>
3. #include <sqlext.h>
4. #ifdef WIN32
5. #include <windows.h>
6. #endif
7. SQLHENV V_OD_Env; // Handle ODBC environment
8. SQLHSTMT V_OD_hstmt; // Handle statement
9. SQLHDBC V_OD_hdbc; // Handle connection
10. SQLINTEGER V_OD_erg;
11. int main(int argc,char *argv[])
12. {
13. V_OD_erg = SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&V_OD_Env);
14. if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
15. {
16. printf("Error AllocHandle\n");
17. exit(0);
18. }
20. SQLSetEnvAttr(V_OD_Env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
22. V_OD_erg = SQLAllocHandle(SQL_HANDLE_DBC, V_OD_Env, &V_OD_hdbc);
23. if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
24. {
25. SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
26. exit(0);
27. }
29. SQLSetConnectAttr(V_OD_hdbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_ON, 0);
31. V_OD_erg = SQLConnect(V_OD_hdbc, (SQLCHAR*) "gaussdb", SQL_NTS,
32. (SQLCHAR*) "userName", SQL_NTS, (SQLCHAR*) "password", SQL_NTS);
33. if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
34. {
35. printf("Error SQLConnect %d\n",V_OD_erg);
36. SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
37. exit(0);
38. }
39. printf("Connected !\n");
40. // 1. 设置语句属性
41. SQLSetStmtAttr(V_OD_hstmt,SQL_ATTR_QUERY_TIMEOUT,(SQLPOINTER *)3,0);
42. // 2. 申请语句句柄
43. SQLAllocHandle(SQL_HANDLE_STMT, V_OD_hdbc, &V_OD_hstmt);
44. // 3. 创建表格。
45. SQLExecDirect(V_OD_hstmt,"drop table IF EXISTS customer_t1",SQL_NTS);
46. SQLExecDirect(V_OD_hstmt,"CREATE TABLE customer_t1(c_customer_sk INTEGER, c_customer_name VARCHAR(32));",SQL_NTS);
47. printf("Done !\n");
48. // 4. 断开数据源连接并释放句柄资源
49. SQLFreeHandle(SQL_HANDLE_STMT,V_OD_hstmt);
50. SQLDisconnect(V_OD_hdbc);
51. SQLFreeHandle(SQL_HANDLE_DBC,V_OD_hdbc);
52. SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
53. return(0);
54. }
插入操作
1. #include <stdlib.h>
2. #include <stdio.h>
3. #include <sqlext.h>
4. #ifdef WIN32
5. #include <windows.h>
6. #endif
7. SQLHENV V_OD_Env; // Handle ODBC environment
8. SQLHSTMT V_OD_hstmt; // Handle statement
9. SQLHDBC V_OD_hdbc; // Handle connection
10. SQLINTEGER value = 100;
11. SQLINTEGER V_OD_erg;
12. int main(int argc,char *argv[])
13. {
14. V_OD_erg = SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&V_OD_Env);
15. if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
16. {
17. printf("Error AllocHandle\n");
18. exit(0);
19. }
21. SQLSetEnvAttr(V_OD_Env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
23. V_OD_erg = SQLAllocHandle(SQL_HANDLE_DBC, V_OD_Env, &V_OD_hdbc);
24. if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
25. {
26. SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
27. exit(0);
28. }
30. SQLSetConnectAttr(V_OD_hdbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_ON, 0);
32. V_OD_erg = SQLConnect(V_OD_hdbc, (SQLCHAR*) "gaussdb", SQL_NTS,
33. (SQLCHAR*) "userName", SQL_NTS, (SQLCHAR*) "password", SQL_NTS);
34. if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
35. {
36. printf("Error SQLConnect %d\n",V_OD_erg);
37. SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
38. exit(0);
39. }
40. printf("Connected !\n");
42. SQLSetStmtAttr(V_OD_hstmt,SQL_ATTR_QUERY_TIMEOUT,(SQLPOINTER *)3,0);
44. SQLAllocHandle(SQL_HANDLE_STMT, V_OD_hdbc, &V_OD_hstmt);
46. // 1. 直接插入
47. SQLExecDirect(V_OD_hstmt,"insert into customer_t1 values(25,li)",SQL_NTS);
49. // 2. pbe方法插入
50. // 2.1 插入占位符
51. SQLPrepare(V_OD_hstmt,"insert into customer_t1 values(?)",SQL_NTS);
52. // 2.2 绑定参数
53. SQLBindParameter(V_OD_hstmt,1,SQL_PARAM_INPUT,SQL_C_SLONG,SQL_INTEGER,0,0,
54. &value,0,NULL);
55. // 2.3 执行准备好的插入语句
56. SQLExecute(V_OD_hstmt);
58. // 3. 断开数据源连接并释放句柄资源
59. SQLFreeHandle(SQL_HANDLE_STMT,V_OD_hstmt);
60. SQLDisconnect(V_OD_hdbc);
61. SQLFreeHandle(SQL_HANDLE_DBC,V_OD_hdbc);
62. SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
63. return(0);
64. }
SELECT操作
1. #include <stdlib.h>
2. #include <stdio.h>
3. #include <sqlext.h>
4. #ifdef WIN32
5. #include <windows.h>
6. #endif
7. SQLHENV V_OD_Env; // Handle ODBC environment
8. SQLHSTMT V_OD_hstmt; // Handle statement
9. SQLHDBC V_OD_hdbc; // Handle connection
10. char typename[100];
11. SQLINTEGER V_OD_erg, V_OD_buffer, V_OD_err, V_OD_id;
12. int main(int argc,char *argv[])
13. {
14. V_OD_erg = SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&V_OD_Env);
15. if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
16. {
17. printf("Error AllocHandle\n");
18. exit(0);
19. }
21. SQLSetEnvAttr(V_OD_Env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
23. V_OD_erg = SQLAllocHandle(SQL_HANDLE_DBC, V_OD_Env, &V_OD_hdbc);
24. if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
25. {
26. SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
27. exit(0);
28. }
29. SQLSetConnectAttr(V_OD_hdbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_ON, 0);
31. V_OD_erg = SQLConnect(V_OD_hdbc, (SQLCHAR*) "gaussdb", SQL_NTS,
32. (SQLCHAR*) "userName", SQL_NTS, (SQLCHAR*) "password", SQL_NTS);
33. if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
34. {
35. printf("Error SQLConnect %d\n",V_OD_erg);
36. SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
37. exit(0);
38. }
39. printf("Connected !\n");
41. SQLSetStmtAttr(V_OD_hstmt,SQL_ATTR_QUERY_TIMEOUT,(SQLPOINTER *)3,0);
43. SQLAllocHandle(SQL_HANDLE_STMT, V_OD_hdbc, &V_OD_hstmt);
45. // 1. 执行select语句
46. SQLExecDirect(V_OD_hstmt,"select c_customer_sk from customer_t1",SQL_NTS);
47. // 2. 获取结果集某一列的属性
48. SQLColAttribute(V_OD_hstmt,1,SQL_DESC_TYPE,typename,100,NULL,NULL);
49. printf("SQLColAtrribute %s\n",typename);
50. // 3. 绑定结果集
51. SQLBindCol(V_OD_hstmt,1,SQL_C_SLONG, (SQLPOINTER)&V_OD_buffer,150,
52. (SQLLEN *)&V_OD_err);
53. // 4. 通过SQLFetch取结果集中数据
54. V_OD_erg=SQLFetch(V_OD_hstmt);
55. // 5. 通过SQLGetData获取并返回数据。
56. while(V_OD_erg != SQL_NO_DATA)
57. {
58. SQLGetData(V_OD_hstmt,1,SQL_C_SLONG,(SQLPOINTER)&V_OD_id,0,NULL);
59. printf("SQLGetData ----ID = %d\n",V_OD_id);
60. V_OD_erg=SQLFetch(V_OD_hstmt);
61. };
62. printf("Done !\n");
63. // 6. 断开数据源连接并释放句柄资源
64. SQLFreeHandle(SQL_HANDLE_STMT,V_OD_hstmt);
65. SQLDisconnect(V_OD_hdbc);
66. SQLFreeHandle(SQL_HANDLE_DBC,V_OD_hdbc);
67. SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
68. return(0);
69. }
更新操作
1. #include <stdlib.h>
2. #include <stdio.h>
3. #include <sqlext.h>
4. #ifdef WIN32
5. #include <windows.h>
6. #endif
7. SQLHENV V_OD_Env; // Handle ODBC environment
8. SQLHSTMT V_OD_hstmt; // Handle statement
9. SQLHDBC V_OD_hdbc; // Handle connection
10. SQLINTEGER V_OD_erg;
11. int main(int argc,char *argv[])
12. {
13. V_OD_erg = SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&V_OD_Env);
14. if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
15. {
16. printf("Error AllocHandle\n");
17. exit(0);
18. }
20. SQLSetEnvAttr(V_OD_Env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
22. V_OD_erg = SQLAllocHandle(SQL_HANDLE_DBC, V_OD_Env, &V_OD_hdbc);
23. if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
24. {
25. SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
26. exit(0);
27. }
29. SQLSetConnectAttr(V_OD_hdbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_ON, 0);
31. V_OD_erg = SQLConnect(V_OD_hdbc, (SQLCHAR*) "gaussdb", SQL_NTS,
32. (SQLCHAR*) "userName", SQL_NTS, (SQLCHAR*) "password", SQL_NTS);
33. if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
34. {
35. printf("Error SQLConnect %d\n",V_OD_erg);
36. SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
37. exit(0);
38. }
39. printf("Connected !\n");
41. SQLSetStmtAttr(V_OD_hstmt,SQL_ATTR_QUERY_TIMEOUT,(SQLPOINTER *)3,0);
43. SQLAllocHandle(SQL_HANDLE_STMT, V_OD_hdbc, &V_OD_hstmt);
45. // 1. 执行更新操作
46. SQLExecDirect(V_OD_hstmt,"update customer_t1 set c_customer_sk = 1000 where c_customer_name = 'li' ",SQL_NTS);
47. // 16. 断开数据源连接并释放句柄资源
48. SQLFreeHandle(SQL_HANDLE_STMT,V_OD_hstmt);
49. SQLDisconnect(V_OD_hdbc);
50. SQLFreeHandle(SQL_HANDLE_DBC,V_OD_hdbc);
51. SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
52. return(0);
53. }
删除操作
1. #include <stdlib.h>
2. #include <stdio.h>
3. #include <sqlext.h>
4. #ifdef WIN32
5. #include <windows.h>
6. #endif
7. SQLHENV V_OD_Env; // Handle ODBC environment
8. SQLHSTMT V_OD_hstmt; // Handle statement
9. SQLHDBC V_OD_hdbc; // Handle connection
10. SQLINTEGER V_OD_erg;
11. int main(int argc,char *argv[])
12. {
13. V_OD_erg = SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&V_OD_Env);
14. if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
15. {
16. printf("Error AllocHandle\n");
17. exit(0);
18. }
20. SQLSetEnvAttr(V_OD_Env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
22. V_OD_erg = SQLAllocHandle(SQL_HANDLE_DBC, V_OD_Env, &V_OD_hdbc);
23. if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
24. {
25. SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
26. exit(0);
27. }
29. SQLSetConnectAttr(V_OD_hdbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_ON, 0);
31. V_OD_erg = SQLConnect(V_OD_hdbc, (SQLCHAR*) "gaussdb", SQL_NTS,
32. (SQLCHAR*) "userName", SQL_NTS, (SQLCHAR*) "password", SQL_NTS);
33. if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
34. {
35. printf("Error SQLConnect %d\n",V_OD_erg);
36. SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
37. exit(0);
38. }
39. printf("Connected !\n");
41. SQLSetStmtAttr(V_OD_hstmt,SQL_ATTR_QUERY_TIMEOUT,(SQLPOINTER *)3,0);
43. SQLAllocHandle(SQL_HANDLE_STMT, V_OD_hdbc, &V_OD_hstmt);
45. // 1. 执行删除操作
46. SQLExecDirect(V_OD_hstmt,"delete from customer_t1 where c_customer_name = 'li'",SQL_NTS);
48. // 2. 断开数据源连接并释放句柄资源
49. SQLFreeHandle(SQL_HANDLE_STMT,V_OD_hstmt);
50. SQLDisconnect(V_OD_hdbc);
51. SQLFreeHandle(SQL_HANDLE_DBC,V_OD_hdbc);
52. SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
53. return(0);
54. }
