---
title: "OB-ODBC 驱动 | OceanBase 文档中心"
description: OB-ODBC 驱动 本文介绍了 OceanBase 数据库的 OB-ODBC 驱动和 MySQL 官方 MySQL-ODBC 驱动的使用说明和配置方法。 开放数据库互连（ODBC）是微软公司开放服务结构（ WOSA，Windows Open Services Architecture）中有关数据库的一个组成部分，基…
image: https://mdn.alipayobjects.com/huamei_22khvb/afts/img/A*OSPzQ6GUQF4AAAAAQHAAAAgAeiGDAQ/original
---
切换语言

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

文档反馈![](https://mdn.alipayobjects.com/huamei_22khvb/afts/img/A*P8CuR4UJ_FkAAAAAAAAAAAAADiGDAQ/original) OceanBase 数据库分布式版 - V 4.0.0 社区版

# OB-ODBC 驱动

更新时间：2026-02-16 18:32:58

[编辑](https://github.com/oceanbase/oceanbase-doc/edit/V4.0.0/zh-CN/500.administrator-guide/500.database-connection-and-routing/600.driver-management/200.ob-odbc-driver.md)  

本文介绍了 OceanBase 数据库的 OB-ODBC 驱动和 MySQL 官方 MySQL-ODBC 驱动的使用说明和配置方法。

开放数据库互连（ODBC）是微软公司开放服务结构（ WOSA，Windows Open Services Architecture）中有关数据库的一个组成部分，基本思想是为用户提供简单、标准、透明的数据库连接的公共编程接口，开发厂商根据 ODBC 的标准去实现底层的驱动程序，这个驱动对用户是透明的，并允许根据不同的 DBMS 采用不同的技术加以优化实现。

ODBC 主要由驱动程序和驱动程序管理器组成。驱动程序是一个用以支持 ODBC 函数调用的模块，每个驱动程序对应于相应的数据库，当应用程序从一个数据库系统移植到另一个时，只需更改应用程序中由 ODBC 管理程序设定的与相应数据库系统对应的别名即可。

建议使用 OceanBase 数据库的 OB-ODBC 驱动。

连接 MySQL 租户也可以使用 MySQL 官方 MySQL-ODBC 驱动。

连接 OceanBase 数据库的驱动程序管理器和驱动程序 OB-ODBC 均为 OceanBase 自研，通过该驱动可以连接访问 OceanBase 数据库。

Linux 下 OB-ODBC/MySQL-ODBC 连接 OceanBase 数据库的架构图如下所示。

![1](https://help-static-aliyun-doc.aliyuncs.com/assets/img/zh-CN/0941580461/p367293.png)

## 连接环境配置

连接数据库前，需要配置连接环境，配置方法如下：

1. 修改配置文件 `odbc.ini`，路径为 `/etc/odbc.ini`，配置文件 `odbc.ini`也可以放在除了`/etc`以外的其他目录，通过设置环境变量到相应的目录即可。

   ```shell
   [ODBC Data Sources]
   data_source_name = Name
   [Name]
   Driver=oceanbase
   Description = MyODBC 5 Driver DSN
   SERVER      = [OBProxy IP地址]
   PORT        = [OBProxy 端口]
   USER        = [用户名@租户名#集群名称]
   Password    = [用户密码]
   Database    = [数据库名]
   OPTION      = 3
   charset=UTF8

   ```
 2. 配置 `/etc/odbcinst.ini`。

   ```shell
   [oceanbase]
   Driver=/u01/mysql-odbc/lib/libmyodbc5a.so

   ```
 3. 设置环境变量。

   ```shell
   export ODBCSYSINI=/etc
   export ODBCINI=/etc/odbc.ini
   export LD_LIBRARY_PATH=/u01/mysql/lib:/usr/lib64:$LD_LIBRARY_PATH
   export PATH=$PATH:/u01/unix-odbc/bin

   ```
 4. 配置完成后使用 `odbcinst -j` 命令查看配置是否正确。

   返回结果如下所示：

   ```shell
   unixODBC 2.3.7
   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

   ```

## 使用示例

1. 以 OceanBase 数据库的 mysql 租户为测试环境，运行下述语句在数据库中创建一张示例表 **TEST。**

   ```sql
   CREATE TABLE "TEST" (
     "ID" NUMBER(38) NOT NULL,
     "NAME" VARCHAR2(32),
     CONSTRAINT "TEST_PK" PRIMARY KEY ("ID")
   ) COMPRESS FOR ARCHIVE REPLICA_NUM = 3 BLOCK_SIZE = 16384 USE_BLOOM_FILTER = FALSE TABLET_SIZE = 134217728 PCTFREE = 10

   ```
 2. 编写连接数据库的驱动程序。

   驱动程序的代码示例如下：

   ```javascript
   #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=odbctest", 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;
       }
       {
           //insert
           retcode = SQLPrepare(handler.hstmt, (SQLCHAR*)"INSERT INTO test VALUES(?,'robin')", SQL_NTS);
           if (!IS_SUCC(retcode)) {  
               checkError(retcode, "SQLPrepare", &handler);
               return -1;
           }
           SQLINTEGER id = 2;
           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;
           }
       }
       // 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;
   }

   ```
 3. 编译并执行驱动程序。

   GCC 编译时，使用 `-I`选项指定头文件， `-L`指定库文件目录， `-l`指定库名。

   示例语句如下所示：

   ```javascript
   gcc test.c -L/u01/unix-odbc/lib -lodbc -I/u01/unix-odbc/include -otest
   ./test

   ```

   检查结果：

   ```javascript
   obclient -hobproxy.oceanbase.abc.com -uhr@test0_5#obtest -p'hr' -P2883
   obclient> select * from test;
   +----+-------+
   | ID | NAME  |
   +----+-------+
   |  1 | jason |
   |  2 | robin |
   +----+-------+

   ```

 上一篇 下一篇 ![有帮助](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) 咨询热线
