ODBC API开发——初学

1、简介ODBC:

随着C/S结构体系在互联网运用广泛,不同数据库访问成了突出问题。在没有ODBC之前,不同的数据库(SQL server、MySQL、Oracle等)采用的标准不同,但当前绝大部分数据库全部或部分地遵从关系数据库概念 ,有了这些共同点,ODBC应用而生,它没有太过复杂,ODBC 是基于结构化查询语言(SQL),使用 SQL 可大大简 化其应用程序设计接口(API) 。只要数据厂商提供的开发包支持这个标准,那么开发人员通过 ODBC 开发的程序可以在不同的数据库之间自由转换。

2、ODBC结构:



3、ODBC API开发:

3.1、所需要的文件:

sql.h:包含有基本的 ODBC API 的定义。
sqlext.h:包含有扩展的 ODBC 的定义。
odbc32.lib:库文件。这些文件开发工具已提供,无需安装。

3.2、ODBC流程图:


3.3、ODBC句柄:

ODBC 中的句柄分为三类:环境句柄,数据库连接句柄, SQL 语句句柄。(每一种句柄需要申请,执行完后进行释放。详细的请 阅读ODBC API开发教程)。

3.4、部分函数:

SQLRETURN retcode;//返回值
SQLRETURN SQLSetConnectAttr(SQLHDBC ConnectionHandle,SQLINTEGER Attribute,SQLPOINTER ValuePtr,SQLINTEGER StringLength);
//连接句柄的参数设置
SQLRETURN SQLSetStmtAttr(SQLHSTMT  StatementHandle,SQLINTEGER Attribute,SQLPOINTER ValuePtr,SQLINTEGER StringLength);
//语句句柄的参数设置
SQLRETURN SQLFetchScroll(SQLHSTMT StatementHandle,SQLSMALLINT FetchOrientation, SQLINTEGER FetchOffset);
//可滑动光标进项查询(比SQLFetch多了两个参数)
SQLRETURN SQLConnect(SQLHDBC ConnecionHandle, SQLCHAR* ServerName, SQLSMALLINT NameLength1, SQLCHAR* UserName,SQLSMALLINT  NameLength2, SQLCHAR* Authentication, SQLSMALLINT NameLength3);    //SQLConnect数据库
SQLRETURN SQLExecDirect(SQLHSTMT StatementHandle,SQLCHAR* StatementText,SQLINTEGER TextLength);	
//SQLExecDirect直接执行SQL语句
SQLRETURN SQLFetch(SQLHSTMT StatementHandle); //SQLFetch移动光标  eg::while(SQL_NO_DATA!=SQLFetch(hSTMT)){}
SQLRETURN SQLGetData(SQLHSTMT StatementHandle,SQLUSMALLINT ColumNumber,SQLSMALLINT TargetType,SQLPOINTER TargetValueptr,SQLINTEGER Bufferlength,SQLINTEGER* StrLen_or_IndPtr);	
 //得到某列(ColumNumber)处的值
SQLRETURN SQLNumberResultCols(SQLHSTMT StatementHandle,SQLSMALLINT* ColumnCountPtr);  //得到结果集中列数   ColumnCountPtr返回列数
SQLRETURN SQLDescribeCol(SQLHSTMT StatementHandle,SQLSMALLINT ColumnNumber,SQLCHAR* ColumnName,SQLSMALLINT Bufferlength,SQLSMALLINT* NamelengthPtr,SQLSMALLINT* DataTypePtr,SQLUINTEGER ColumnSizePtr,SQLSMALLINT* DecimalDigitsPtr,SQLSMALLINT* NullablePtr);	
//得到结果集中列的描述


在数据库创建表(VS2015的平台下,通过可视化的窗口手动创建,)比如创建一个test的表,命令:

CREATE TABLE [dbo].[test] (
    [oky]    CHAR (8)  NOT NULL,
    [spoint]  CHAR (10) NOT NULL,
    [status] INT       NULL,
    [city]   CHAR (10) NULL,
    PRIMARY KEY CLUSTERED ([oky] ASC)
通过创建的表进行插入示例:(出入的数据key值不能相同,不然会发生插入错误)

#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*)"create table test(sky char(8) primary key,spoint char(10) not null,status int,city char(10))", SQL_NTS);
	if (retcode < 0)
	{
		cout << "creat 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;
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值