数据库原理 第1关:ODBC程序设计[头歌]

任务描述

本关任务:使用 ODBC 查询表中数据。

相关知识

为了完成本关任务,你需要掌握: 1.ODBC 的主要功能; 2.ODBC 接口主要函数; 3.ODBC 应用程序开发实例。

ODBC主要功能

ODBC(Open Database Connectivity,开放式数据库连接)是由 Microsoft 开发和定义的一种访问数据库的应用程序接口,其定义了访问数据库API的一组规范,这些API独立于形色各异的数据库系统和编程语言。因此,ODBC 支持不同编程语言,同时也支持不同的数据库系统。借助 ODBC 接口,应用程序能够使用相同的源代码和各种各样的数据库交互。这使得应用程序开发人员不需要考虑各类数据库系统的构造细节,只要使用相应 ODBC 驱动程序,即可通过将 SQL 语句发送到目标数据库中,可以访问和操作各类数据库中的数据。

也就是说,一个基于 ODBC 的应用程序,对数据库的操作不依赖任何数据库系统,所有的数据库操作由对应数据库的ODBC驱动程序完成。不论是 SQL Server、Access、Oracle,还是 DM 数据库,均可借助 ODBC API 进行访问。ODBC 体系结构如下图所示,ODBC 驱动程序管理器用于管理各种 ODBC 驱动程序,基于 ODBC 开发的应用程序通过 ODBC 驱动程序管理器,调用针对不同数据库的驱动程序,进行数据对象的维护、数据的查询和修改等操作。

DM8 数据库提供的 DM ODBC 3.0 接口遵照 Microsoft ODBC 3.0 规范设计与开发,实现了 ODBC 应用程序与 DM 的互连。其由 C 语言编写,其底层调用 DM DCI 接口实现。因此,应用程序开发人员可基于 ODBC 接口规范,使用 DM ODBC 驱动访问和操作 DM8 数据库。

,

ODBC接口主要函数

由于 DM ODBC 遵照 Microsoft ODBC 3.0 规范设计与开发,因此 DM ODBC 接口提供的函数与标准 ODBC 一致。由于 DM ODBC 接口函数较多,下图仅列出了 DM ODBC 接口的主要函数。

,

,

,

,

ODBC应用程序开发实例
DM ODBC应用程序开发总体流程

DM ODBC 为程序员提供了基于 ODBC 接口开发应用程序的手段,程序员使用 DM ODBC 开发应用程序时总体流程如下图所示。首先,安装 DM ODBC 驱动;其次,配置 ODBC 数据源;最后,基于 DM ODBC 编程规范,编写代码访问和操作 DM8 数据库。

,

1)安装 DM ODBC 驱动程序; 示例: 1.将附件 unixODBC-2.3.0.tar.gz 上传到 /data/workspace/userfiles 下,执行安装。

 
  1. root@educoder:~# cd /data/workspace/userfiles/
  2. [root@localhost local]# tar -xzvf unixODBC-2.3.0.tar.gz
  3. [root@localhost unixODBC-2.3.0]# cd unixODBC-2.3.0
  4. [root@localhost unixODBC-2.3.0]# ./configure --enable-gui=no
  5. [root@localhost unixODBC-2.3.0]# make
  6. [root@localhost unixODBC-2.3.0]# make install

2.查看操作系统上查看 ODBC 版本

 
  1. [dmdba@localhost]# odbc_config --version
  2. 2.3.0

3.查看 ODBC 配置文件存放的位置

 
  1. [root@localhost etc]# odbc_config --odbcini
  2. /etc/odbc.ini
  3. [root@localhost etc]# odbc_config --odbcinstini
  4. /etc/odbcinst.ini

4.修改odbc.ini文件

 
  1. [dmdba@localhost]# vi /etc/odbc.ini
  2. [dm]
  3. Description = DM ODBC DSN
  4. Driver = DM7 ODBC DRIVER
  5. SERVER = localhost
  6. UID = SYSDBA
  7. PWD = SYSDBA
  8. TCP_PORT = 5236

5.修改odbcinst.ini文件

 
  1. [dmdba@localhost]# vi /etc/odbcinst.ini
  2. [DM7 ODBC DRIVER]
  3. Description = ODBC DRIVER FOR DM7
  4. Driver = /opt/dmdbms/bin/libdodbc.so

6.测试连接

 
  1. [root@localhost]# isql dm SYSDBA SYSDBA
  2. +---------------------------------------+
  3. | Connected! |
  4. | |
  5. | sql-statement |
  6. | help [tablename] |
  7. | quit |
  8. | |
  9. +---------------------------------------+

出现上述“Connected”就代表安装成功。

2)配置 DM ODBC 数据源; 3)编写 DM ODBC 代码。

DM ODBC代码编写流程

DM ODBC 数据源配置成功后,即可编写代码访问和操作数据库。遵循 ODBC 编程规范,基于 DM ODBC 接口编写代码访问和操作数据库大致流程如下图所示。

,

首先,创建连接环境和连接数据库。主要通过调用相关函数分配环境句柄、设置环境属性、分配连接句柄和建立数据库连接等过程。 其次,访问和操作数据库。主要通过建立的连接来分配语句句柄、执行SQL语句等操作,该过程是操作数据库的主体部分,与数据库的所有交互均在该过程完成。

最后,断开连接和释放连接资源。数据库操作完成后,程序需关闭数据库连接,并释放连接资源。

DM ODBC代码编写实例

【例1】 基于 DM ODBC 编程接口,利用已配置的 DM ODBC 数据源 DM,编写程序,实现获取数据源 DM 对应数据库中 DMHR.EMPLOYEE 表的数据,包括职员 ID、姓名、手机号码等信息。

在 Visual Studio Code 集成开发环境中,创建一个项目,并为项目添加一个 .cpp 源代码文件;然后添加依赖文件“dodbc.so”和达梦数据库安装目录下的 bin 和 include 两个依赖目录;接着基于 DM ODBC 接口编写代码。

1)创建连接环境和连接数据库

应用程序与 DM 数据库进行通讯,需要和数据库建立连接。①调用函数 SQLAllocHandle 申请环境、连接句柄;②调用函数 SQLSetEnvAttr 设置环境句柄属性;③调用函数 SQLSetConnectAttr 设置连接句柄属性;⑤调用连接函数 SQLConnect、SQLDriverConnect 或 SQLBrowseConnect 连接数据源。

2)访问和操作数据库

与 ODBC 数据源建立连接后,即可通过 ODBC 函数访问和操作数据。调用 SQLAllocHandle 申请语句句柄,通过该句柄执行 SQL 语句;调用函数 SQLPrepare 对 SQL 语句和操作进行准备;调用 SQLDescribeCol、SQLDescribeParam 等函数取得相关的描述信息,依据描述信息调用 SQLBindCol、SQLBindParam 等函数绑定相关的列和参数;调用 SQLExecute 执行 SQL 语句,实现相关的 SQL 操作。应用程序也可以调用 SQLExecDirect 直接执行 SQL 语句进行相关的 SQL 操作。

3)断开数据连接和释放连接资源

数据库操作完成后,程序需关闭数据库连接,并释放连接资源。如果要终止客户程序与服务器之间的连接,客户程序应当完成以下的几个操作: (1)调用 SQLFreeHandle 释放语句句柄,关闭所有打开的游标,释放相关的语句句柄资源(在非自动提交模式下,需事先提交当前的事务); (2)调用函数 SQLDisconnect 关闭所有的连接; (3)调用 SQLFreeHandle 释放连接句柄及其相关的资源; (4)调用 SQLFreeHandle 释放环境句柄及其相关的资源。

例 1 代码如下所示,该代码可用于查询 dmhr.employee 表中所有职工姓名、id 和电话号码。

#include <sys/socket.h>
#include <unistd.h>
#include <stdio.h>
#include <sql.h>
#include <sqltypes.h>
#include <sqlext.h>
/* 检测返回代码是否为成功标志,当为成功标志返回 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;/* 返回代码 */
char szpersonid[11]; /*人员编号*/
SQLLEN cbpersonid=0;
char szname[51]; /*人员姓名*/
SQLLEN cbname=0;
char szphone[26]; /*联系电话*/
SQLLEN cbphone=0;
void main(void)
{
/* 申请一个环境句柄 */
SQLAllocHandle(SQL_HANDLE_ENV, NULL, &henv);
if(henv == NULL){
printf("ODBC 环境句柄分配失败");
return;
}
/* 设置环境句柄的 ODBC 版本 */
SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, SQL_IS_INTEGER);
/* 申请一个连接句柄 */
SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
if(hdbc == NULL){
printf("ODBC 连接句柄分配失败");
return;
}
sret=SQLConnect(hdbc, (SQLCHAR *)"DM", SQL_NTS, (SQLCHAR *)"DMHR", SQL_NTS, (SQLCHAR *)"dameng123", SQL_NTS);
if(sret == SQL_SUCCESS||sret==SQL_SUCCESS_WITH_INFO){
/* 申请一个语句句柄 */
SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hsmt);
/* 立即执行查询人员信息表的语句 */
SQLExecDirect(hsmt, (SQLCHAR *)"SELECT employee_id, employee_name, phone_num FROM dmhr.employee;", SQL_NTS);
/* 绑定数据缓冲区 */
SQLBindCol(hsmt, 1, SQL_C_CHAR, szpersonid, sizeof(szpersonid), &cbpersonid);
SQLBindCol(hsmt, 2, SQL_C_CHAR, szname, sizeof(szname), &cbname);
SQLBindCol(hsmt, 3, SQL_C_CHAR, szphone, sizeof(sazphone), &cbphone);
/* 取得数据并且打印数据 */
printf("人员编号 人员姓名 联系电话\n");

for (;;) {
sret = SQLFetchScroll(hsmt, SQL_FETCH_NEXT, 0);
if (sret == SQL_NO_DATA_FOUND)
break;
printf("%s %s %s\n", szpersonid, szname, szphone);
}
}
else{
printf("连接失败\n");
}
/* 关闭游标,终止语句执行 */
SQLCloseCursor(hsmt);
/* 释放语句句柄 */
SQLFreeHandle(SQL_HANDLE_STMT, hsmt);
/* 断开与数据源之间的连接 */
SQLDisconnect(hdbc);
/* 释放连接句柄 */
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
/* 释放环境句柄*/
SQLFreeHandle(SQL_HANDLE_ENV, henv);
}

其中 DMHR 为用户名,dameng123 为密码。

编程要求

使用右侧 VS CODE 编写 ODBC 程序,查询 test.tb_class 表中所有数据。

登录用户名为:SYSDBA;密码:SYSDBA。

操作步骤: 1.进入官网https://www.unixodbc.org/下载UnixODBC-2.3.0.tar.gz,或者你可直接进入此链接下载http://www.unixodbc.org/unixODBC-2.3.0.tar.gz,将此压缩包上传,上传文件的默认路径为/data/workspace/userfiles,然后再进行上面的安装 DM ODBC 驱动程序步骤;

2.打开 VS CODE,在 HELLOWORLD 项目下方新建 test.cpp 文件,并在该文件中实现 ODBC 程序需求; 3.编辑 HELLOWORLD 项目下的 task.json 文件,按下图所示添加依赖文件dodbc.so。

,

4.选中 test.cpp 文件,按下“Ctrl+Shift+B”,编译 test.cpp 文件; 5.点击测评。

test.tb_class 表字段信息:

字段名字段类型
idint
namevarchar(25)

实际操作[直接看这]        

        一,打开vscode,点击左侧边栏的HELLOWORLD,点击蓝色的.vscode

        

        二,点击task.json,修改内容,添加

        

        

        

        三,复制以下代码,点击操作界面右上角工具箱的复制粘贴进行复制(题目代码有问题)

        

        

#include <sys/socket.h> 
#include <unistd.h>
#include <stdio.h>
#include <sql.h>
#include <sqltypes.h>
#include <sqlext.h>
/* 检测返回代码是否为成功标志,当为成功标志返回 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;/* 返回代码 */
int szpersonid; /*人员编号*/
SQLLEN cbpersonid=0;
char szname[51]; /*人员姓名*/
SQLLEN cbname=0;
int main(void)
{
    /* 申请一个环境句柄 */
    SQLAllocHandle(SQL_HANDLE_ENV, NULL, &henv);
    if(henv == NULL){
        printf("ODBC 环境句柄分配失败");
        return -1;
    }
    /* 设置环境句柄的 ODBC 版本 */
    SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, SQL_IS_INTEGER);
    /* 申请一个连接句柄 */
    SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
    if(hdbc == NULL){
        printf("ODBC 连接句柄分配失败");
        return -1;
    }
    sret=SQLConnect(hdbc, (SQLCHAR *)"DM", SQL_NTS, (SQLCHAR *)"SYSDBA", SQL_NTS, (SQLCHAR *)"SYSDBA", SQL_NTS);
    if(sret == SQL_SUCCESS||sret==SQL_SUCCESS_WITH_INFO){
        /* 申请一个语句句柄 */
        SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hsmt);
        /* 立即执行查询人员信息表的语句 */
        SQLExecDirect(hsmt, (SQLCHAR *)"SELECT id, name FROM test.tb_class;", SQL_NTS);
        /* 绑定数据缓冲区 */
        SQLBindCol(hsmt, 1, SQL_C_CHAR, &szpersonid, sizeof(szpersonid), &cbpersonid);
        SQLBindCol(hsmt, 2, SQL_C_CHAR, szname, sizeof(szname), &cbname);
        /* 取得数据并且打印数据 */
        for (int i = 1;;++i) {
            sret = SQLFetchScroll(hsmt, SQL_FETCH_NEXT, 0);
            if (sret == SQL_NO_DATA_FOUND)
            break;
            printf("%d %s\n", i, szname);
        }
    }
    else{
            printf("连接失败\n");
        }
    /* 关闭游标,终止语句执行 */
    SQLCloseCursor(hsmt);
    /* 释放语句句柄 */
    SQLFreeHandle(SQL_HANDLE_STMT, hsmt);
    /* 断开与数据源之间的连接 */
    SQLDisconnect(hdbc);
    /* 释放连接句柄 */
    SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
    /* 释放环境句柄*/
    SQLFreeHandle(SQL_HANDLE_ENV, henv);

    return 0;
}

四,在 HELLOWORLD下建立test.cpp文件,把上面的代码直接粘贴过去,再按住Ctrl+Shift+B”,编译 test.cpp 文件,点击测评即可

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值