文章目录
Hive的ODBC接口driver实现
Extend Hive ODBC to support more functions
odbc源文件
odbc api说明文档
一、ODBC 简介
ODBC(Open Database Connectivity)是一个用于访问数据库的统一的接口标准。
二、ODBC 结构
三、使用 ODBC 进行数据开发基础知识
1、建立 ODBC DSN
DSN(Data Source Name)用于指定ODBC与相关的驱动程序相对应入口,DSN 包括三类:用户 DSN,系统 DSN,文件 DSN。ODBC DSN 的建立流程:
- 选择驱动程序,如 SQL Server;
- 输入 DSN 名称和数据库服务器地址或别名;
- 输入用户和口令进行连接;
- 选择默认数据库,完成。
2、ODBC所需头文件
#include <sql.h> //This is the the main include for ODBC Core functions.
#include <sqlext.h> //This is the include for applications using the Microsoft SQL Extensions
#include <sqltypes.h> //This file defines the types used in ODBC
3、ODBC句柄
ODBC 管理器和ODBC 驱动程序为 ODBC 环境、每个连接以及每个SQL语句分配描述/控制信息存储空间,并返回指向各个存储区的句柄供其使用。ODBC中的句柄分为三类:
-
环境句柄:整个ODBC上下文的根句柄。
-
连接句柄:管理有关数据库会话的所有信息。
-
语句句柄:ODBC语句包括应用访问数据源的SQL语句和语句相关的管理信息。
4、程序执行基本流程图
四、ODBC 基本功能介绍
1、ODBC API
Task | Function name | Purpose |
---|---|---|
连接到数据源 | SQLAllocHandle | 分配环境、连接、语句或者描述符句柄。 |
- | SQLConnect | 建立与驱动程序或者数据源的连接。访问数据源的连接句柄包含了包括状态、事务申明和错误信息的所有连接信息。 |
- | SQLDriverConnect | 与SQLConnect相似,用来连接到驱动程序或者数据源。但它比SQLConnect支持数据源更多的连接信息,它提 供了一个对话框来提示用户设置所有的连接信息以及系统信息表没有定义的数据源。 |
- | SQLBrowseConnect | 支持一种交互方法来检索或者列出连接数据源所需要的属性和属性值。每次调用函数可以获取一个连接属性字符串,当检索完所有的属性值,就建立起与数据源的连接,并且返回完整的连接字符串,否则提示缺少的连接属性信息,用户根据此信息重新输入连接属性值再次调用此函数进行连接。 |
获取驱动程序和数据源信息 | SQLDataSources | 能够被调用多次来获取应用程序使用的所有数据源的名字。 |
- | SQLDrivers | 返回所有安装过的驱动程序清单,包括对它们的描述以及属性关键字。 |
- | SQLGetInfo | 返回连接的驱动程序和数据源的元信息。 |
- | SQLGetFunctions | 返回指定的驱动程序是否支持某个特定函数的信息。 |
- | SQLGetTypeInfo | 返回指定的数据源支持的数据类型的信息。 |
设置或者获取驱动程序属性 | SQLSetConnectAttr | 设置连接属性值。 |
- | SQLGetConnectAttr | 返回连接属性值。 |
- | SQLSetEnvAttr | 设置环境属性值。 |
- | SQLGetEnvAttr | 返回环境属性值。 |
- | SQLSetStmtAttr | 设置语句属性值。 |
- | SQLGetStmtAttr | 返回语句属性值。 |
设置或者获取描述符字段 | SQLGetDescField | 返回单个描述符字段的值。 |
- | SQLGetDescRec | 返回当前描述符记录的多个字段的值。 |
- | SQLSetDescField | 设置单个描述符字段的值。 |
- | SQLSetDescRec | 设置描述符记录的多个字段。 |
准备SQL语句 | SQLPrepare | 准备要执行的SQL语句。 |
- | SQLBindParameter | 在SQL语句中分配参数的缓冲区。 |
- | SQLGetCursorName | 返回与语句句柄相关的游标名称。 |
- | SQLSetCursorName | 设置与语句句柄相关的游标名称。 |
- | SQLSetScrollOptions | 设置控制游标行为的选项。 |
提交SQL请求 | SQLExecute | 执行准备好的SQL语句。 |
- | SQLExecDirect | 执行一条SQL语句。 |
- | SQLNativeSql | 返回驱动程序对一条SQL语句的翻译。 |
- | SQLDescribeParam | 返回对SQL语句中指定参数的描述。 |
- | SQLNumParams | 返回SQL语句中参数的个数。 |
- | SQLParamData | 与SQLPutData联合使用在运行时给参数赋值。 |
- | SQLPutData | 在SQL语句运行时给部分或者全部参数赋值。 |
检索结果集及其相关信息 | SQLRowCount | 返回INSERT、UPDATE或者DELETE等语句影响的行数。 |
- | SQLNumResultCols | 返回结果集中列的数目。 |
- | SQLDescribeCol | 返回结果集中列的描述符记录。 |
- | SQLColAttribute | 返回结果集中列的属性。 |
- | SQLBindCol | 为结果集中的列分配缓冲区。 |
- | SQLFetch | 在结果集中检索下一行元组。 |
- | SQLFetchScroll | 返回指定的结果行。 |
- | SQLGetData | 返回结果集中当前行某一列的值。 |
- | SQLSetPos | 在取到的数据集中设置游标的位置。这个记录集中的数据能够刷新、更新或者删除。 |
- | SQLBulkOperations | 执行块插入和块书签操作,其中包括根据书签更新、删除或者取数据。 |
- | SQLMoreResults | 确定是否能够获得更多的结果集,如果能就执行下一个结果集的初始化操作。 |
- | SQLGetDiagField | 返回一个字段值或者一个诊断数据记录。 |
- | SQLGetDiagRec | 返回多个字段值或者一个诊断数据记录。 |
取得数据源系统表的信息 | SQLColumnPrivileges | 返回一个关于指定表的列的列表以及相关的权限信息。 |
- | SQLColumns | 返回指定表的列信息的列表。 |
- | SQLForeignKeys | 返回指定表的外键信息的列表。 |
- | SQLPrimaryKeys | 返回指定表的主键信息的列表。 |
- | SQLProcedureColumns | 返回指定存储过程的参数信息的列表。 |
- | SQLProcedures | 返回指定数据源的存储过程信息的列表。 |
- | SQLSpecialColumns | 返回唯一确定某一行的列的信息,或者当某一事务修改一行的时候自动更新各列的信息。 |
- | SQLStatistics | 返回一个单表的相关统计信息和索引信息。 |
- | SQLTablePrivileges | 返回相关各表的名称以及相关的权限信息。 |
- | SQLTables | 返回指定数据源中表信息。 |
终止语句执行 | SQLFreeStmt | 终止语句执行,关闭所有相关的游标,放弃没有提交的结果,选择释放与指定语句句柄相关的资源。 |
- | SQLCloseCursor | 关闭一个打开的游标,放弃没有提交的结果。 |
- | SQLCancel | 放弃执行一条SQL语句。 |
- | SQLEndTran | 提交或者回滚事务。 |
中断连接 | SQLDisconnect | 关闭指定连接。 |
- | SQLFreeHandle | 释放环境、连接、语句或者描述符句柄。 |
2、示例代码
#include <iostream>
#include <string.h>
#include <windows.h>
#include <sql.h>
#include <sqlext.h>
#include <odbcss.h>
using namespace std;
#define MAXBUFLEN 255
#define MaxNameLen 40
#define SQLBINDCOL
SQLHENV henv = SQL_NULL_HENV;//定义环境句柄
SQLHDBC hdbc1 = SQL_NULL_HDBC;//定义数据库连接句柄
SQLHSTMT hstmt1 = SQL_NULL_HSTMT;//定义语句句柄
int main()
{
RETCODE retcode;//错误返回码
retcode = SQLAllocHandle(SQL_HANDLE_ENV, NULL, &henv);
if (retcode < 0)//错误处理
{
cout << "allocate errors." << endl;
return -1;
}
retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION,(SQLPOINTER)SQL_OV_ODBC3, SQL_IS_INTEGER);//大多数情况下要设置成3.0,否则有的函数不支持
if (retcode < 0) //错误处理
{
cout << "not 3.0 " << endl;
return -1;
}
retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc1);
if (retcode < 0) //错误处理
{
cout << "connection handle errors." << endl;
return -1;
}
char* szDSN = "sqlserver_0_151";
char* szUID = "sa";//log name
char* szAuthStr = "123123";//passward
SQLSetConnectAttr(hdbc1, SQL_LOGIN_TIMEOUT, (SQLPOINTER *)5, 0);
retcode = SQLConnect(hdbc1, (SQLCHAR*)szDSN, (SWORD)strlen(szDSN), (SQLCHAR*)szUID, (SWORD)strlen(szUID), (SQLCHAR*)szAuthStr, (SWORD)strlen(szAuthStr));
if (retcode < 0) //错误处理
{
cout << "connect to ODBC datasource errors." << endl;
return -1;
}
retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc1, &hstmt1);
if (retcode < 0) //错误处理
{
cout << "allocate ODBC statement handle errors." << endl;
return -1;
}
retcode = SQLExecDirect(hstmt1, (SQLCHAR*)"insert into test values('SS0','港口','20','天津')", SQL_NTS);
if (retcode < 0)
{
cout << "ss0 insert errors." << endl;
return -1;
}
retcode = SQLExecDirect(hstmt1, (SQLCHAR*)"insert into test values('SS1','故宫','10','北京')", SQL_NTS);
if (retcode < 0)
{
cout << "ss1 insert errors." << endl;
return -1;
}
retcode = SQLExecDirect(hstmt1, (SQLCHAR*)"insert into test values('SS2','兵马俑','30','西安')", SQL_NTS);
if (retcode < 0)
{
cout << "ss2 insert errors." << endl;
return -1;
}
retcode = SQLExecDirect(hstmt1, (SQLCHAR*)"insert into test1 values('SS3','水','25',null)", SQL_NTS);
if (retcode < 0)
{
cout << "ss3 insert errors." << endl;
return -1;
}
retcode = SQLExecDirect(hstmt1, (SQLCHAR*)"SElECT spoint,city FROM test", SQL_NTS);
if (retcode < 0)
{
cout << "Executing errors." << endl;
return -1;
}
SQLCHAR city[MaxNameLen + 1];
SQLCHAR point[MaxNameLen + 1];
SQLINTEGER Len = 0;//列的长度
#ifdef SQLBINDCOL
retcode = SQLBindCol(hstmt1, 1, SQL_C_CHAR, point, MaxNameLen, &Len);
retcode = SQLBindCol(hstmt1, 2, SQL_C_CHAR, city, MaxNameLen, &Len);
while ((retcode = SQLFetch(hstmt1)) != SQL_NO_DATA)
{
if (columnLen > 0)
printf("point = %s city = %s\n", point, city);
else
printf("point = %s city = NULL\n", point, city);
}
#else
while (1)
{
retcode = SQLFetch(hstmt1);
if (retcode == SQL_NO_DATA)
break;
retcode = SQLGetData(hstmt1, 1, SQL_C_CHAR, point, MaxNameLen, &Len);
retcode = SQLGetData(hstmt1, 2, SQL_C_CHAR, city, MaxNameLen, &Len);
if (columnLen > 0)
printf("point = %s city = %s\n", point, city);
else
printf("point = %s city = NULL\n", point, city);
}
#endif
//释放
SQLFreeHandle(SQL_HANDLE_STMT, hstmt1);
SQLDisconnect(hdbc1);
SQLFreeHandle(SQL_HANDLE_DBC, hdbc1);
SQLFreeHandle(SQL_HANDLE_ENV, henv);
return 0;
}