达梦数据库ODBC编程

达梦数据库ODBC编程

技术教程gslnedu2024-12-26 13:33:1313A+A-

这两天安装试用了达梦数据库(DM8),下面记录对达梦数据库ODBC接口编程的探索过程。

Linux环境中,达梦数据库的ODBC接口依赖unixODBC库。

1.安装unixODBC库

下载:wget ftp://ftp.unixodbc.org/pub/unixODBC/unixODBC-2.3.9.tar.gz 
解压:tar -zxvf unixODBC-2.3.9.tar.gz 
进入解压目录安装:cd unixODBC-2.3.9/    
./configure --prefix=/home/dmdba/unixODBC --enable-gui=no  注:先建自定义安装目录unixODBC
make && make install

按上面安装后,unixODBC的lib、include和etc配置生成在$HOME/unixODBC下,如下图:

unixODBC安装后

但这时etc下的odbc.ini和odbcinst.ini尚且为空,需要配置。

配置后的odbc.int和odbcinst.ini文件

配置注意:odbcinst.int的节点名称(红框2)是odbc.int的Driver值。

安装完成后,把unixODBC的lib库目录加到LD_LIBRARY_PATH环境变量中。

现在LD_LIBRARY_PATH值如下:

[dmdba@wen ~]$ echo $LD_LIBRARY_PATH
/home/dmdba/dmdbms/bin:/home/dmdba/unixODBC/lib:/home/dmdba/iconv/lib

测试odbc接口是否可用:

测试odbc接口可用

2.ODBC编程接口

达梦ODBC接口用会用到转码库libiconv.so.2,若没有先安装之,自定义安装目录时要把安装位置加入LD_LIBRARY_PATH路径中。

至此环境准备完毕,可以进行测试代码编译了。

下面是改造后的代码示例:

[dmdba@wen ~]$ cat test_odbc.c

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sql.h>
#include <sqltypes.h>
#include <sqlext.h>
/*
 * SQLEndTran:提交或者回滚事务。
 * 调用 SQLFreeHandle 释放语句句柄,关闭所有打开的游标,释放相关的语句句柄( 在非自动提交模式下,需事先提交当前的事务)
 *
 * */
/* 检测返回代码是否为成功标志,当为成功标志返回 TRUE,否则返回 FALSE */
#define RC_SUCCESSFUL(rc) ((rc) == SQL_SUCCESS || (rc) == SQL_SUCCESS_WITH_INFO)
/* 检测返回代码是否为失败标志,当为失败标志返回 TRUE,否则返回 FALSE */
#define RC_NOTSUCCESSFUL(rc) (!(RC_SUCCESSFUL(rc)))
HENV henv; /* 环境句柄 */
HDBC hdbc; /* 连接句柄 */
HSTMT hsmt; /* 语句句柄 */
SQLRETURN sret; /* 返回代码 */
void main(void)
{
printf("begin\n");
	char szpersonid[11]; /*人员编号*/
	SQLLEN cbpersonid=0;
	char szname[51]; /*人员姓名*/
	SQLLEN cbname=0;
	SQLRETURN retcode=SQL_ERROR ; /* 返回代码 -1 */
	/* 申请一个环境句柄 */
	retcode= SQLAllocHandle(SQL_HANDLE_ENV, NULL, &henv);
	if (SQL_SUCCESS == retcode || SQL_SUCCESS_WITH_INFO == retcode ){
		printf("SQLAllocHandle ok\n");
	}
	else{
		printf("retcode=%d\n",retcode);
		exit(-1);
	}
	/* 设置环境句柄的 ODBC 版本 */
	SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, SQL_IS_INTEGER);
	/* 申请一个连接句柄 */
	SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
///home/dmdba/unixODBC/etc/odbc.int的[dm8]节点名
	retcode = SQLConnect(hdbc, (SQLCHAR *)"dm8", SQL_NTS, (SQLCHAR *)"dmdbuser1", SQL_NTS, (SQLCHAR *)"dmdbuser1", SQL_NTS);
	if (SQL_SUCCESS == retcode || SQL_SUCCESS_WITH_INFO == retcode ){
		printf("SQLConnect ok\n");
	}
	else{
		SQLFreeHandle(SQL_HANDLE_ENV, henv);
		printf("retcode=%d\n",retcode);
		exit(-1);
	}
	SQLINTEGER AUTOCOMMIT_MODE;
/* 设置连接句柄属性,关闭自动提交功能 */
	SQLSetConnectAttr(hdbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_OFF, SQL_IS_INTEGER);
//SQLSetConnectAttr(hdbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_ON, SQL_IS_INTEGER);  AUTOCIMMIT_ON is default 
	/* 申请一个语句句柄 */
	SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hsmt);
	SQLExecDirect(hsmt, (SQLCHAR *)"insert into city values('5','cp');", SQL_NTS);
	SQLExecDirect(hsmt, (SQLCHAR *)"insert into city values('6','北京');", SQL_NTS);
	SQLExecDirect(hsmt, (SQLCHAR *)"insert into city values('6','china');", SQL_NTS);
	/* 立即执行查询人员信息表的语句 */
	SQLExecDirect(hsmt, (SQLCHAR *)"SELECT f1, f2 FROM city;", SQL_NTS);
	/* 绑定数据缓冲区 */
	SQLBindCol(hsmt, 1, SQL_C_CHAR, szpersonid, sizeof(szpersonid), &cbpersonid);
	SQLBindCol(hsmt, 2, SQL_C_CHAR, szname, sizeof(szname), &cbname);
	/* 取得数据并且打印数据 */
	for (;;) {
		sret = SQLFetchScroll(hsmt, SQL_FETCH_NEXT, 0);
		if (sret == SQL_NO_DATA_FOUND){
			break;
		}
    /*SQLRETURN  SQL_API SQLGetData(SQLHSTMT StatementHandle,
                                  SQLUSMALLINT ColumnNumber, SQLSMALLINT TargetType,
                                  SQLPOINTER TargetValue, SQLLEN BufferLength,
                                  SQLLEN *StrLen_or_Ind);
*/
		printf("%s %s.  len=%d\n", szpersonid, szname,cbname);
		bzero(szpersonid,sizeof szpersonid);
		bzero(szname,sizeof szname);
	}
	/* 关闭游标,终止语句执行 */
	SQLCloseCursor(hsmt);
	SQLExecDirect(hsmt, (SQLCHAR *)"delete from city where f1='3';", SQL_NTS);
	SQLExecDirect(hsmt, (SQLCHAR *)"delete from city where f1='5';", SQL_NTS);
	SQLExecDirect(hsmt, (SQLCHAR *)"update city set f2='LN' where f1='2';", SQL_NTS);
	//提交连接上的事务
	SQLEndTran(SQL_HANDLE_DBC, hdbc, SQL_COMMIT);
	//回滚连接上的事务
	//SQLEndTran(SQL_HANDLE_DBC, hdbc, SQL_ROLLBACK);
	/* 释放语句句柄 */
	SQLFreeHandle(SQL_HANDLE_STMT, hsmt);
	/* 断开与数据源之间的连接 */
	SQLDisconnect(hdbc);
	/* 释放连接句柄 */
	SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
	/* 释放环境句柄*/
	SQLFreeHandle(SQL_HANDLE_ENV, henv);
printf("end ok\n");
	return 0;
}

这是编译test_odbc.c的Makefile文件:

DM_DIR=/home/dmdba
all:test_odbc
test_odbc:test_odbc.o
        gcc -ggdb  -Wall -o $@  $^ -L$(DM_DIR)/unixODBC/lib -L$(DM_DIR)/dmdbms/bin -I$(DM_DIR)/unixODBC/include -lodbc
clean:
        rm test_odbc  
        rm test_odbc.o

编译后生成test_odbc程序,可以正确读取和修改测试库(dmdbuser1)中的表数据。

ODBC接口调用存储过程、函数方法见《DM8程序员手册.pdf》,相关资料在数据库安装目录的doc里可找到。

tips:

客户端工具可用DBeaver,它依赖的驱动DmJdbcDriver17.jar可在达梦安装包的drivers目录里获取。驱动设置时:

类名:dm.jdbc.driver.DmDriver

JDBC URL: jdbc:dm://<ip>:<port>/<DBNAME>


铁锈笔记 2022-01-13

点击这里复制本文地址 以上内容由朽木教程网整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!
qrcode

朽木教程网 © All Rights Reserved.  蜀ICP备2024111239号-8