更新时间:2024-10-08 GMT+08:00

使用ODBC连接

GaussDB(DWS)支持使用ODBC应用程序连接数据库。应用程序可以在华为云平台环境的弹性云服务器中,或者互联网环境连接数据库。

ODBC接口的使用方法,请自行查阅官方文档。

前提条件

在Linux环境使用ODBC连接

  1. 将ODBC驱动包和代码文件上传到Linux环境,并解压到指定目录。
  2. root用户登录Linux环境。
  3. 准备unixODBC。

    1. 解压unixODBC代码文件。
      tar -xvf unixODBC-2.3.0.tar.gz
    2. 编译并安装。
      1
      2
      3
      4
      cd unixODBC-2.3.0
      ./configure --enable-gui=no
      make
      make install
      
      • 此时unixODBC编译安装完成后,安装目录下会有*.so.2的库文件,如果需要编译出*.so.1的库文件,需要将configure文件中的LIB_VERSION修改为:LIB_VERSION="1:0:0"。
        1
        LIB_VERSION="1:0:0"
        
      • 在本驱动中,会动态的加载库文件libodbcinst.so.*,加载成功其中的一个则完成对该库文件的加载。其中加载的优先级为libodbcinst.so>libodbcinst.so.1>libodbcinst.so.1.0.0>libodbcinst.so.2>libodbcinst.so.2.0.0

        例如在某目录下可以动态的链接到libodbcinst.so.1、libodbcinst.so.1.0.0、libodbcinst.so.2。驱动文件会先加载libodbcinst.so,如果当前环境中无法找到libodbcinst.so,则会继续寻找优先级低的libodbcinst.so.1,当成功的加载到libodbcinst.so.1后即完成了对该动态链接库的加载。

  4. 替换驱动文件(本文以redhat操作系统的包dws_8.1.x_odbc_driver_for_x86_redhat.zip为例)。

    1. 解压“dws_8.1.x_odbc_driver_for_x86_redhat.zip”。
      unzip dws_8.1.x_odbc_driver_for_x86_redhat.zip
    2. 将“dws_8.1.x_odbc_driver_for_x86_redhat.zip”解压后“lib”目录下所有文件,替换到“/usr/local/lib”
    3. 将“dws_8.1.x_odbc_driver_for_x86_redhat.zip”解压后“odbc/lib”目录下的“psqlodbcw.la”“psqlodbcw.so”,保存到“/usr/local/lib”

  5. 执行以下命令,修改驱动文件配置。

    vi /usr/local/etc/odbcinst.ini

    将以下内容保存到配置中:

    [DWS] 
    Driver64=/usr/local/lib/psqlodbcw.so

    参数说明如下:

    • “[DWS]”:表示驱动器名称,支持自定义。
    • “Driver64”“Driver”:表示驱动动态库的路径。64位系统优先查找“Driver64”配置项,如果未配置则会继续查找“Driver”

  6. 执行以下命令,修改数据源文件。

    vi /usr/local/etc/odbc.ini

    将以下内容保存到配置文件中,并退出修改。

    [DWSODBC]
    Driver=DWS
    Servername=10.10.0.13
    Database=gaussdb
    Username=dbadmin
    Password=password
    Port=8000
    Sslmode=allow

    参数名

    说明

    参数值样例

    [DSN]

    数据源的名称。

    [DWSODBC]

    Driver

    驱动名称,对应“odbcinst.ini”中的DriverName。

    Driver=DWS

    Servername

    服务器的IP地址,当集群绑定弹性负载均衡(ELB)时,应设置为ELB的IP地址。

    Servername=10.10.0.13

    Database

    要连接的数据库的名称。

    Database=gaussdb

    Username

    数据库用户名称。

    Username=dbadmin

    Password

    数据库用户密码。

    Password=password

    Port

    服务器的端口号。

    Port=8000

    Sslmode

    SSL认证工作模式。集群默认开启。

    取值及含义:

    • disable:只尝试非SSL连接。
    • allow:首先尝试非SSL连接,如果连接失败,再尝试SSL连接。
    • prefer:首先尝试SSL连接,如果连接失败,将尝试非SSL连接。
    • require:只尝试SSL连接。如果存在CA文件,则按设置成verify-ca的方式验证。
    • verify-ca:只尝试SSL连接,并且验证服务器是否具有由可信任的证书机构签发的证书。
    • verify-full:GaussDB(DWS)不支持此模式。
    说明:

    SSL模式安全性高于普通模式,集群默认开启SSL功能允许来自客户端的SSL连接或非SSL连接,建议在使用ODBC连接GaussDB(DWS)集群时采用SSL模式。

    Sslmode=allow

    • 其中,参数“Servername”和“Port”的值,可以在GaussDB(DWS)的管理控制台查看。请登录GaussDB(DWS)管理控制台,单击“连接客户端”, 在“数据仓库连接字符串”区域,选择指定的集群,获取该集群的“内网访问地址”“公网访问地址”。具体步骤请参见获取GaussDB(DWS)集群连接地址

  7. 配置环境变量。

    vi ~/.bashrc

    在配置文件中追加以下内容。

    export LD_LIBRARY_PATH=/usr/local/lib/:$LD_LIBRARY_PATH 
    export ODBCSYSINI=/usr/local/etc 
    export ODBCINI=/usr/local/etc/odbc.ini

  8. 导入环境变量。

    source ~/.bashrc

  9. 执行以下命令,开始连接。

    /usr/local/bin/isql -v DWSODBC

    界面显示以下信息表示连接成功:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    +---------------------------------------+ 
    | Connected!                            | 
    |                                       | 
    | sql-statement                         | 
    | help [tablename]                      | 
    | quit                                  | 
    |                                       | 
    +---------------------------------------+  
    SQL> 
    

在Windows环境使用ODBC连接

  1. 解压Windows版本的ODBC驱动包“dws_odbc_driver_for_windows.zip”,并安装“psqlodbc.msi”
  2. 解压SSL证书压缩包,并准备证书文件。

    用户可以根据实际情况选择自动或手动部署方法:

    • 自动部署:
      双击“sslcert_env.bat”文件,即可完成证书的默认位置的部署。
      • 该sslcert_env.bat为了保证证书环境的纯净,在%APPDATA%\postgresql目录存在时,会提示是否需要移除相关目录。如果有需要,请备份该目录中的文件。
    • 手动部署:
      • “%APPDATA%\”目录创建一个新文件夹,并命名为“postgresql”
      • 将证书文件包中的“client.crt”“client.key”“client.key.cipher”“client.key.rand”文件保存至“%APPDATA%\postgresql”目录,并且将文件名中的client改为postgres,例如“client.key”修改为“postgres.key”
      • “cacert.pem”文件保存至“%APPDATA%\postgresql”目录,并更名为“root.crt”

  3. 打开驱动管理器。

    因为目前GaussDB(DWS)提供了32位和64位的ODBC驱动程序,用户可根据自身需求选择;在配置数据源时,请使用对应的驱动管理器(假设操作系统安装盘符为C:盘,如果是其他盘符,请对路径做相应修改):

    • 64位操作系统上进行32位程序开发,安装32位程序驱动后。使用32位的驱动管理器:C:\Windows\SysWOW64\odbcad32.exe

      请勿直接使用“控制面板> 管理工具 > 数据源(ODBC)”。

      WoW64的全称是"Windows 32-bit on Windows 64-bit",C:\Windows\SysWOW64\存放的是64位系统上的32位运行环境。

    • 64操作系统上进行64位程序开发,安装64位驱动程序后,使用64位的驱动管理器:C:\Windows\System32\odbcad32.exe

      请勿直接使用“控制面板 > 管理工具> 数据源(ODBC)”。

      C:\Windows\System32\存放的是与操作系统一致的运行环境,具体的技术信息请查阅Windows的相关技术文档。

    • 32位操作系统请使用:C:\Windows\System32\odbcad32.exe

      或者单击“计算机 > 控制面板 > 管理工具 > 数据源(ODBC)”打开驱动管理器。

  4. 配置连接数据源。

    1. 在打开的驱动管理器上,选择用户DSN > 添加 > PostgreSQL Unicode,然后进行配置。
      图1 配置连接数据源

      其中,配置项“Server”“Port”的值,可以在GaussDB(DWS)的管理控制台查看。请登录GaussDB(DWS)管理控制台,单击“连接客户端”, 在“数据仓库连接字符串”区域,选择指定的集群,获取该集群的“内网访问地址”“公网访问地址”。具体步骤请参见获取GaussDB(DWS)集群连接地址

    2. 单击“Test”验证连接正确,界面提示“Connection successful”

  5. 编写ODBC样例程序连接数据源。

    ODBC接口不提供重试连接数据库的能力,您需要在业务代码中实现重试连接的处理。

    样例代码如下:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    // 此示例演示如何通过ODBC方式获取GaussDB(DWS)中的数据。
    // DBtest.c (compile with: libodbc.so)  
    #include <stdlib.h> 
    #include <stdio.h> 
    #include <sqlext.h>
    #ifdef WIN32
    #include <windows.h>
    #endif 
    SQLHENV       V_OD_Env;        // Handle ODBC environment 
    SQLHSTMT      V_OD_hstmt;      // Handle statement 
    SQLHDBC       V_OD_hdbc;       // Handle connection     
    char          typename[100];
    SQLINTEGER    value = 100;
    SQLINTEGER    V_OD_erg,V_OD_buffer,V_OD_err,V_OD_id;
    int main(int argc,char *argv[]) 
    {         
          // 1. 申请环境句柄       
          V_OD_erg = SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&V_OD_Env);     
          if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))        
          {           
               printf("Error AllocHandle\n");           
               exit(0);        
          } 
          // 2. 设置环境属性(版本信息)         
          SQLSetEnvAttr(V_OD_Env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);      
          // 3. 申请连接句柄        
          V_OD_erg = SQLAllocHandle(SQL_HANDLE_DBC, V_OD_Env, &V_OD_hdbc);     
          if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))      
          {                     
               SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);          
               exit(0);       
          }
          // 4. 设置连接属性
          SQLSetConnectAttr(V_OD_hdbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_ON, 0);          
          // 5. 连接数据源,其中的用户名和用户密码等信息之所以能省略,是因为在odbc.ini文件中进行了配置,若没配置需要在SQLConnect函数参数中具体写明要连接数据库的用户名和用户密码等信息。      
          V_OD_erg = SQLConnect(V_OD_hdbc, (SQLCHAR*) "gaussdb", SQL_NTS,  
                               (SQLCHAR*) "", SQL_NTS,  (SQLCHAR*) "", SQL_NTS);        
          if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))      
          {           
              printf("Error SQLConnect %d\n",V_OD_erg);            
              SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);       
              exit(0);        
          }     
          printf("Connected !\n"); 
          // 6. 设置语句属性
          SQLSetStmtAttr(V_OD_hstmt,SQL_ATTR_QUERY_TIMEOUT,(SQLPOINTER *)3,0);
          // 7. 申请语句句柄
          SQLAllocHandle(SQL_HANDLE_STMT, V_OD_hdbc, &V_OD_hstmt);       
          // 8. 直接执行SQL语句。
          SQLExecDirect(V_OD_hstmt,"drop table IF EXISTS testtable",SQL_NTS);
          SQLExecDirect(V_OD_hstmt,"create table testtable(id int)",SQL_NTS);
          SQLExecDirect(V_OD_hstmt,"insert into testtable values(25)",SQL_NTS);
          // 9. 准备执行
          SQLPrepare(V_OD_hstmt,"insert into testtable values(?)",SQL_NTS); 
          // 10. 绑定参数
          SQLBindParameter(V_OD_hstmt,1,SQL_PARAM_INPUT,SQL_C_SLONG,SQL_INTEGER,0,0,
                           &value,0,NULL);
          // 11. 执行准备好的语句
          SQLExecute(V_OD_hstmt);
          SQLExecDirect(V_OD_hstmt,"select id from testtable",SQL_NTS);
          // 12. 获取结果集某一列的属性
          SQLColAttribute(V_OD_hstmt,1,SQL_DESC_TYPE,typename,100,NULL,NULL);                 
          printf("SQLColAtrribute %s\n",typename);
          // 13. 绑定结果集
          SQLBindCol(V_OD_hstmt,1,SQL_C_SLONG, (SQLPOINTER)&V_OD_buffer,150,
                    (SQLLEN *)&V_OD_err);
          // 14. 通过SQLFetch取结果集中数据
          V_OD_erg=SQLFetch(V_OD_hstmt);
          // 15. 通过SQLGetData获取并返回数据。
          while(V_OD_erg != SQL_NO_DATA)
          {
              SQLGetData(V_OD_hstmt,1,SQL_C_SLONG,(SQLPOINTER)&V_OD_id,0,NULL);
              printf("SQLGetData ----ID = %d\n",V_OD_id);
              V_OD_erg=SQLFetch(V_OD_hstmt);
          };
          printf("Done !\n");
          // 16. 断开数据源连接并释放句柄资源
          SQLFreeHandle(SQL_HANDLE_STMT,V_OD_hstmt);    
          SQLDisconnect(V_OD_hdbc);         
          SQLFreeHandle(SQL_HANDLE_DBC,V_OD_hdbc);       
          SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);  
          return(0);
     }