---
title: "Linux 版 ODBC 驱动安装与配置 - ODBC 驱动程序  V2.0.9 | OceanBase 文档中心"
description: Linux 版 ODBC 驱动安装与配置 获取到 Linux 版 OceanBase Connector/ODBC 安装包后，根据如下步骤进行安装与配置。 依赖版本要求 libobclient：V2.1.2 第一步：检查驱动是否安装及驱动版本 检查是否已安装 OceanBase Connector/ODBC，并查看相…
---
切换语言

- 中文站 - 简体中文
- International - English
- 日本站 - 日本語

文档反馈![](https://mdn.alipayobjects.com/huamei_22khvb/afts/img/A*0V2BT7xsMSQAAAAAAAAAAAAADiGDAQ/original) ODBC 驱动程序 V 2.0.9

# Linux 版 ODBC 驱动安装与配置

更新时间：2026-07-02 11:25:58

[编辑](https://github.com/oceanbase/connector-odbc-doc/edit/V2.0.9/zh-CN/200.installation-and-configuration/200.linux-installation-and-configuration.md)  

获取到 Linux 版 OceanBase Connector/ODBC 安装包后，根据如下步骤进行安装与配置。

## 依赖版本要求

- libobclient：V2.1.2

## 第一步：检查驱动是否安装及驱动版本

检查是否已安装 OceanBase Connector/ODBC，并查看相应版本信息。

```
rpm -qa | grep odbc
rpm -qa | grep obclient

```

如已安装，以下为返回内容：

```
# rpm -qa | grep odbc
ob-connector-odbc-2.0.9.2-20230719101407.el7.alios7.x86_64
ob-unixodbc-2.0.8.3-20231114143843.el7.alios7.x86_64

# rpm -qa | grep obclient
libobclient-2.1.2-20211201104607.el7.alios7.x86_64

```

如果需要替换其他版本，执行如下命令先删除软件包。

```
# rpm -ev ob-unixodbc
# rpm -ev ob-connector-odbc
# rpm -ev libobclient

```

如未安装，请参见下面章节，首先安装软件依赖包，再安装 ODBC 驱动。

## 第二步：安装软件依赖包

你需要安装软件依赖包 Libtool 的两个工具：libtool-ltdl 和 libreadline。

### 安装 libtool-ltdl

1. 执行下面的命令，检查是否已安装 libtool-ltdl。

   ```
   rpm -qa | grep libtool-ltdl  

   ```

   如果已安装，返回结果示例如下：

   ```
   libtool-ltdl-2.4.2-22.el7_3.x86_64

   ```
 2. 如未安装，执行下面的命令安装。

   ```
   sudo yum search libtool-ltdl
   sudo yum install libtool-ltdl

   ```

### 安装 libreadline

1. 执行下面的命令，检查是否已安装 libreadline。

   ```
   rpm -qa|grep readline  

   ```

   ```
   readline-6.2-9.1.alios7.x86_64

   ```
 2. 如未安装，请执行下面的命令安装。

   ```
   sudo yum search readline
   sudo yum install readline

   ```
 3. 安装后再次检查文件是否存在。

   ```
   ls -lth /usr/lib64/libreadline.so.6

   ```
 4. 如果 `/usr/lib64/libreadline.so.6` 文件不存在，执行下面的命令创建软连接。

   ```
   # rpm -qa|grep readline
   readline-8.0-3.ky10.x86_64

   # rpm -ql readline-8.0-3.ky10.x86_64
   /usr/lib64/libhistory.so.7
   /usr/lib64/libhistory.so.7.0
   /usr/lib64/libhistory.so.8
   /usr/lib64/libhistory.so.8.0
   /usr/lib64/libreadline.so.7
   /usr/lib64/libreadline.so.7.0
   /usr/lib64/libreadline.so.8
   /usr/lib64/libreadline.so.8.0
   /usr/share/licenses/readline
   /usr/share/licenses/readline/COPYING
   /usr/share/licenses/readline/USAGE

   # ln -s /usr/lib64/libreadline.so.8 /usr/lib64/libreadline.so.6
   # ls -lth /usr/lib64/libreadline.so.6
   lrwxrwxrwx 1 root root 27 Jan  3 14:56 /usr/lib64/libreadline.so.6 -> /usr/lib64/libreadline.so.8

   ```

## 第三步：安装 OceanBase ODBC 驱动

完成安装软件依赖包 Libtool 后，你可以依次执行下面的命令安装 ODBC 驱动。

```
sudo rpm -ivh libobclient-<version_no>.rpm
sudo rpm -ivh ob-connector-odbc-<version_no>.rpm
sudo rpm -ivh ob-unixodbc-<version_no>.rpm

```

安装完成后，再次分别执行下面的命令检查安装情况和版本。

```

如已安装，返回结果示例如下：

```
# rpm -qa | grep odbc
ob-connector-odbc-2.0.9.2-20230719101407.el7.alios7.x86_64
ob-unixodbc-2.0.9.2-20230719100704.el7.alios7.x86_64

# rpm -qa | grep obclient
libobclient-2.2.0-20221017150844.el7.alios7.x86_64

```

## 第四步：配置文件

### 配置 odbc.ini

配置 `odbc.ini` 到 `/etc/odbc.ini`（也可以自定义目录设置环境变量到相应的目录即可），执行下面的命令，编辑 `odbc.ini` 配置文件。

```
sudo vim /etc/odbc.ini

```

执行上面的命令后，即可见配置文件，配置文件内的内容和释义如下：

```
[ODBC Data Sources]
data_source_name = OBDSN

[OBDSN]
Driver=Oceanbase
Description = OceanBase Driver DSN
SERVER = 10.10.20.20
PORT = 2883
USER = ALVIN@oboracle#obcluster
Password = xxx
Database = ALVIN
OPTION = 4
charset=UTF8

[OBDSNMYSQL]
Driver=Oceanbase
Description = OceanBase Driver DSN  
SERVER = xxx.xxx.xxx.xxx
PORT = 10003
USER = tester@sys
Password = 1******
Database = unittests
OPTION = 4
charset=UTF8

[OBDSNMULTIHOST]
Driver=Oceanbase
Description = OceanBase Driver DSN with Multi-IP Support
MULTIHOST = 1
SERVER = xxx.xxx.xxx.xxx:38882,xxx.xxx.xxx.xxx:38884
USER = tester@sys

```

配置文件中的参数含义和取值约束如下表所示。

| **参数名称** | **含义** |
| --- | --- |
| Driver | odbcinst.ini 中的驱动，是用户自定义的。 |
| Description | 驱动描述。 |
| SERVER | 数据库 IP 地址。支持多 IP 配置，多个 IP 地址用逗号分隔，例如：`xxx.xxx.xxx.xxx:38882,xxx.xxx.xxx.xxx:38884`。 |
| PORT | 数据库实际端口。 |
| MULTIHOST | 多 IP 配置开关。设置为 1 开启多 IP 功能，0 关闭（默认）。 |
| USER | 数据库用户账号。 |
| Password | 数据库密码。 |
| Database | 数据库名称。 |
| OPTION | 配置选项（开启日志，OPTION=4）。 |
| charset | 数据库字符集，默认为 UTF8。 |

### 配置 odbcinst.ini

配置 `odbcinst.ini` 到 `/etc/odbcinst.ini`（也可以自定义目录设置环境变量到相应的目录即可）。执行下面的命令，编辑 `odbcinst.ini` 配置文件。

```
sudo vim /etc/odbcinst.ini

```

点击键盘上的 **i** 进入编辑状态，将下面的内容添加到文件内。需要注意的是，`[Oceanbase]`前面不能有空格。

```
[Oceanbase]
 Description = ODBC for Oceanbase
 Driver = /u01/ob-connector-odbc/lib64/mariadb/libobodbc.so

```

最后，点击键盘上的 **esc**，输入 **:wq** 保存并退出文件。

## 第五步：设置环境变量。

### 临时添加环境变量

通过该方式添加的环境变量仅对当前终端会话有效，在退出终端会话后就会失效。

```
$export ODBCSYSINI=/etc
$export ODBCINI=/etc/odbc.ini
$export LD_LIBRARY_PATH=/u01/unix-odbc/lib:/u01/obclient/lib:/u01/ob-connector-odbc/lib64/mariadb:$LD_LIBRARY_PATH

```

### 为当前用户永久添加环境变量

通过该方式添加的环境变量，在退出终端会话后，添加的环境变量对当前用户仍然生效。

```
vim ~/.bashrc

```

编辑 `.bashrc` 文件，在文件结尾处添加以下信息：

```javascript
export ODBCSYSINI=/etc
export ODBCINI=/etc/odbc.ini
export LD_LIBRARY_PATH=/u01/unix-odbc/lib:/u01/obclient/lib:/u01/ob-connector-odbc/lib64/mariadb:$LD_LIBRARY_PATH

```

保存修改并退出文件，再执行以下命令使配置生效。

```
source ~/.bashrc

```

### 为所有用户永久添加环境变量

通过该方式添加的环境变量，在退出终端会话后，添加的环境变量对所有用户仍然生效。

```
vim /etc/profile

```

编辑 `/etc/profile` 文件，在文件结尾处添加以下信息：

```shell
export ODBCSYSINI=/etc
export ODBCINI=/etc/odbc.ini
export LD_LIBRARY_PATH=/u01/unix-odbc/lib:/u01/obclient/lib:/u01/ob-connector-odbc/lib64/mariadb:$LD_LIBRARY_PATH

```

```
source /etc/profile

```

## 第六步：检查环境变量配置情况

环境变量配置完成后，使用 `odbcinst -j` 命令查看配置是否正确：

```
/u01/unix-odbc/bin/odbcinst -j

```

返回结果示例如下：

```
unixODBC 2.3.0
DRIVERS............: /etc/odbcinst.ini
SYSTEM DATA SOURCES: /etc/odbc.ini
FILE DATA SOURCES..: /etc/ODBCDataSources
USER DATA SOURCES..: /etc/odbc.ini
SQLULEN Size.......: 8
SQLLEN Size........: 8
SQLSETPOSIROW Size.: 8

```

## 第七步：检查环境依赖是否正确

执行下面的命令，检查环境依赖是否正确，确保 libobclnt.so.20 的依赖与所安装的 libobclient-xxx.rpm 包对应。

执行下面的命令切换到 ODBC 连接器库文件所在目录：

```
cd /u01/ob-connector-odbc/lib64/mariadb

```

使用 ldd 命令来列举 libobodbc.so 的依赖关系：

```
ldd /u01/ob-connector-odbc/lib64/mariadb/libobodbc.so

```

返回结果示例如下：

```
linux-vdso.so.1 =>  (0x00007ffe4d3fc000)
libobclnt.so.20 => /u01/obclient/lib/libobclnt.so.20 (0x00007f063217c000)
libodbcinst.so.2 => /u01/unix-odbc/lib/libodbcinst.so.2 (0x00007f0631f64000)
libm.so.6 => /lib64/libm.so.6 (0x00007f0631c62000)
libc.so.6 => /lib64/libc.so.6 (0x00007f0631894000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f0631690000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f0631474000)
libltdl.so.7 => /lib64/libltdl.so.7 (0x00007f063126a000)
/lib64/ld-linux-x86-64.so.2 (0x00007f0632675000)

```

## 第八步：测试连接

### ISQL 连接测试

DriverManager 相关的工具在 `/u01/unix-odbc` 目录下，运行连接命令并显示成功。

```
/u01/unix-odbc/bin/isql -v OBDSN

```

预期运行结果如下所示：

```
+-------------------------------+
|  Connected!                   |
|                               |
|  sql-statement                |
|  help [tablename]             |
|  quit                         |
|                               |
+-------------------------------+
SQL>

```

### （可选）第九步：编译 C++ 测试程序

本章节将以 C++ 通过 OceanBase Connector/ODBC 进行创建表、插入数据、查询和删除数据的为例，展示如何编译 C++ 测试程序。

使用下面的命令创建 `test.cpp` 文件。

```
vim test.cpp

```

下面的文件内容提供了配置示例，您只需将示例中的 `DSN=OBDSN` 替换为您的实际 DSN 名称。以下是本文 `/etc/odbc.ini` 文件中的 OBDSN 示例：

```
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sql.h"
#include "sqlext.h"

typedef struct tagODBCHandler {
  SQLHENV henv;
  SQLHDBC hdbc;
  SQLHSTMT hstmt;
}ODBCHandler;

int IS_SUCC(SQLRETURN retcode) {
  if  (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) return 1;
  return 0;
}
void checkError(SQLRETURN retcode, const char* msg, ODBCHandler* handler) {
  SQLCHAR message[SQL_MAX_MESSAGE_LENGTH + 1];
  SQLCHAR sqlstate[SQL_SQLSTATE_SIZE + 1];
  SQLINTEGER error;
  SQLSMALLINT len;
  SQLRETURN tmpcode;

  switch (retcode){
  case SQL_SUCCESS:
    printf("%s retcode is SQLRETURN\n", msg);
    break;
  case SQL_SUCCESS_WITH_INFO:
    printf("%s retcode is SQL_SUCCESS_WITH_INFO\n", msg);
    break;
  case SQL_ERROR:
    printf("%s retcode is SQL_ERROR\n", msg);
    tmpcode = SQLError(handler->henv, handler->hdbc, handler->hstmt, sqlstate, &error, message, sizeof(message), &len);
    if (tmpcode != SQL_SUCCESS && tmpcode != SQL_SUCCESS_WITH_INFO) {
      printf("get sqlerror failed %d", tmpcode);
    } else {
      printf("error is %d, meeesage is %s, sqlstate is %s, len is %d\n", error, message, sqlstate, len);
    }
    break;
  case SQL_INVALID_HANDLE:
    printf("%s retcode is SQL_INVALID_HANDLE\n", msg);
    break;
  case SQL_STILL_EXECUTING:
    printf("%s retcode is SQL_STILL_EXECUTING\n", msg);
    break;
  case SQL_NO_DATA:
    printf("%s retcode is SQL_NO_DATA\n", msg);
    break;
  default:
    printf("%s retcode is UNKNOWN retcode\n", msg);
    break;
  }
}

int main(int argc, char** argv) {
  ODBCHandler handler;
  SQLRETURN retcode;
#define MAX_NAME_LEN 255
  SQLCHAR   connOut[MAX_NAME_LEN+1];
  SQLSMALLINT len;
  //Allocate environment handle
  retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &handler.henv);
  // Set the ODBC version environment attribute  
  if (!IS_SUCC(retcode)) {
    checkError(retcode, "SQLAllocHandle", &handler);
    return -1;
  }
  retcode = SQLSetEnvAttr(handler.henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3_80, 0);
  // Allocate connection handle  
  if (!IS_SUCC(retcode)) {  
    checkError(retcode, "SQLSetEnvAttr", &handler);
    return -1;
  }
  retcode = SQLAllocHandle(SQL_HANDLE_DBC, handler.henv, &handler.hdbc);  
  if (!IS_SUCC(retcode)) {  
    checkError(retcode, "SQLAllocHandle", &handler);
    return -1;
  }
  // Set login timeout to 5 seconds  
  SQLSetConnectAttr(handler.hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, 0);  
  // Connect to data source  
  retcode = SQLDriverConnect(handler.hdbc, NULL, (SQLCHAR*)"DSN=OBDSN", SQL_NTS, connOut, MAX_NAME_LEN, &len,SQL_DRIVER_NOPROMPT);
  if (!IS_SUCC(retcode)) {  
    checkError(retcode, "SQLDriverConnect", &handler);
    return -1;
  }
  retcode = SQLAllocHandle(SQL_HANDLE_STMT, handler.hdbc, &handler.hstmt);
  if (!IS_SUCC(retcode)) {  
    checkError(retcode, "SQLAllocHandle", &handler);
    return -1;
  }
  {
    //drop
    SQLExecDirect(handler.hstmt, (SQLCHAR*)"drop table PERSON", SQL_NTS);
    SQLFreeStmt(handler.hstmt, SQL_CLOSE);
  }
  {
    //create
    retcode = SQLExecDirect(handler.hstmt, (SQLCHAR*)"create table PERSON(id int, num int, name varchar2(100))", SQL_NTS);
    if (!IS_SUCC(retcode)) {
      checkError(retcode, "SQLExecDirect", &handler);
      return -1;
    }
    SQLFreeStmt(handler.hstmt, SQL_CLOSE);
  }
  {
    //insert
    retcode = SQLPrepare(handler.hstmt, (SQLCHAR*)"insert into PERSON values(?,?,'test')", SQL_NTS);
    if (!IS_SUCC(retcode)) {  
      checkError(retcode, "SQLPrepare", &handler);
      return -1;
    }
    SQLINTEGER id = 0;
    SQLINTEGER num = 0;
    retcode = SQLBindParameter(handler.hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &id, 0, NULL);
    if (!IS_SUCC(retcode)) {  
      checkError(retcode, "SQLBindParameter", &handler);
      return -1;
    }
    retcode = SQLBindParameter(handler.hstmt, 2, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &num, 0, NULL);
    if (!IS_SUCC(retcode)) {  
      checkError(retcode, "SQLBindParameter", &handler);
      return -1;
    }
    retcode = SQLExecute(handler.hstmt);
    if (!IS_SUCC(retcode)) {  
      checkError(retcode, "SQLExecute", &handler);
      return -1;
    }
    SQLFreeStmt(handler.hstmt, SQL_CLOSE);
  }
  {
    //update
    SQLINTEGER id = 0;
    retcode = SQLPrepare(handler.hstmt, (SQLCHAR*)"update PERSON set num=2, name='hello' where id=?", SQL_NTS);
    if (!IS_SUCC(retcode)) {
      checkError(retcode, "SQLPrepare", &handler);
      return -1;
    }
    retcode = SQLBindParameter(handler.hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &id, 0, NULL);
    if (!IS_SUCC(retcode)) {
      checkError(retcode, "SQLBindParameter", &handler);
      return -1;
    }
    retcode = SQLExecute(handler.hstmt);
    if (!IS_SUCC(retcode)) {
      checkError(retcode, "SQLExecute", &handler);
      return -1;
    }
    SQLFreeStmt(handler.hstmt, SQL_CLOSE);
  }

  {
    //select
    retcode = SQLPrepare(handler.hstmt, (SQLCHAR*)"select * from PERSON", SQL_NTS);
    if (!IS_SUCC(retcode)) {  
      checkError(retcode, "SQLPrepare", &handler);
      return -1;
    }
    retcode = SQLExecute(handler.hstmt);
    if (!IS_SUCC(retcode)) {
      checkError(retcode, "SQLExecute", &handler);
      return -1;
    }

    SQLINTEGER id = 0;
    SQLINTEGER num = 0;
    char name[100] = { 0 };
    retcode = SQLBindCol(handler.hstmt, 1, SQL_INTEGER, &id, sizeof(id), NULL);
    if (!IS_SUCC(retcode)) {
      checkError(retcode, "SQLBindCol", &handler);
      return -1;
    }
    retcode = SQLBindCol(handler.hstmt, 2, SQL_INTEGER, &num, sizeof(num), NULL);
    if (!IS_SUCC(retcode)) {
      checkError(retcode, "SQLBindCol", &handler);
      return -1;
    }
    retcode = SQLBindCol(handler.hstmt, 3, SQL_CHAR, name, sizeof(name), NULL);
    if (!IS_SUCC(retcode)) {  
      checkError(retcode, "SQLBindCol", &handler);
      return -1;
    }
    retcode = SQLFetch(handler.hstmt);
    if (!IS_SUCC(retcode)) {
      checkError(retcode, "SQLFetch", &handler);
      return -1;
    }
    SQLFreeStmt(handler.hstmt, SQL_CLOSE);
    printf("id=%d, num=%d, name=%s", id, num, name);
  }

  {
    //delete
    SQLINTEGER id = 0;
    retcode = SQLPrepare(handler.hstmt, (SQLCHAR*)"delete from PERSON where id=?", SQL_NTS);
    if (!IS_SUCC(retcode)) {
      checkError(retcode, "SQLPrepare", &handler);
      return -1;
    }
    retcode = SQLBindParameter(handler.hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &id, 0, NULL);
    if (!IS_SUCC(retcode)) {
      checkError(retcode, "SQLBindParameter", &handler);
      return -1;
    }
    retcode = SQLExecute(handler.hstmt);
    if (!IS_SUCC(retcode)) {
      checkError(retcode, "SQLExecute", &handler);
      return -1;
    }
    SQLFreeStmt(handler.hstmt, SQL_CLOSE);
  }

  // clean handle
  SQLFreeHandle(SQL_HANDLE_STMT, handler.hstmt);
  SQLDisconnect(handler.hdbc);
  SQLFreeHandle(SQL_HANDLE_DBC, handler.hdbc);
  SQLFreeHandle(SQL_HANDLE_ENV, handler.henv);
  return 0;
}

```

通过如下命令测试：

```
g++ -I /u01/unix-odbc/include/ test.cpp -L/u01/ob-connector-odbc/lib64/mariadb -lobodbc -o test
./test

```

```
#./test
id=0, num=2, name=hello

```

 上一篇 下一篇 ![有帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*y6ocSqN8cqsAAAAAAAAAAAAAARQnAQ)![无帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*BG9IQJyLHF8AAAAAAAAAAAAAARQnAQ)![反馈](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*eTWdQKCRKHwAAAAAAAAAAAAAARQnAQ)[AI](https://www.oceanbase.com/obi) 咨询热线
