ODBC API编程

ODBC  API编程

如果一个ODBC API函数执行成功,则返回SQL_SUCCESSSQL_SUCCESS_WITH_INFOSQL_SUCCESS指示可通过诊断记录获取有关操作的详细信息,SQL_SUCCESS_WITH_INFO指示应用程序执行结果带有警告信息,可通过诊断记录获取详细信息。如果函数调用失败,返回码为SQL_ERROR

一般,编写ODBC程序主要有一下几个步骤:

1、分配环境句柄:声明一个SQLHENV的变量,调用函数SQLAllocHandle

设置环境属性:完成环境分配后,用函数SQLSetEnvAttr设置环境属性,注册ODBC版本号。

释放环境句柄:完成数据访问任务时,应调用SQLFreeHandle释放前面分配的环境。

2、分配连接句柄:声明一个SQLHDBC类型的变量,调用SQLAllocHandle函数分配句柄。

设置连接属性:所有连接属性都可通过函数SQLSetConnectAttr设置,调用函数SQLGetConnectAttr可获取这些连接属性的当前设置值。

3   连接数据源:对于不同的程序和用户接口,可以用不同的函数建立连接

SQLConnect:该函数只要提供数据源名称、用户ID和口令,就可以进行连接了。

SQLDriverConnect:该函数用一个连接字符串建立至数据源的连接,它可以让用户输入必要的连接信息,使用系统中还没定义的数据源。

SQLBrowseConnect:该函数支持以一种迭代的方式获取到数据源的连接,直到最后建立连接,它基于客户机/服务器体系结构,因此本地数据库不支持该函数。

4   准备并执行SQL语句

A  分配语句句柄:语句句柄是通过调用SQLAllocHandle函数分配的。

函数SQLGetStmrrAttrSQLSetStmrrAttr用来获取和设置一个语句句柄的选项,使用完,调用SQLFreeHandle释放该句柄。

B  执行SQL语句

SQLExecDirect:该函数直接执行SQL语句,对于只执行一次的SQL语句来说,该函数是执行最快的方法。

SQLPrepare
SQLExecute:对于需要多次执行的SQL语句来说,可先调用SQLPrepare准备SQL语句的执行,用SQLExecute执行准备好的语句。

C  使用参数:使用参数可以使一条SQL语句多次执行,得到不同的结果。

函数SQLBindParameter负责为参数定义变量,将一段SQL语句中的一个参数标识符("")捆绑在一起,实现参数值的传递。

5   获取记录集

A   绑定列:首先必须分配与记录集中字段相对应的变量,然后通过函数SQLBindCol将记录字段同程序变量绑定在一起,对于长记录字段,可以通过调用函数SQLGetData直接取回数据。

绑定字段可以根据自己的需要全部绑定,也可以绑定其中的某几个字段。

通过调用函数SQLBindCol将变量地址值赋为NULL,可以结束对一个记录字段的绑定,通过调用函数SQLFreeStmt,将其中选项设为SQL_UNBIND,或者直接释放句柄,都会结束所有记录字段的绑定。

BSQLFetch:该函数用于将记录集的下一行变成当前行,并把所有捆绑过的数据字段的数据拷贝到相应的缓冲区。

C 光标:应用程序获取数据是通过光标(Cursor)来实现的,在ODBC中,主要有3种类型的光标:单向光标可滚动光标块光标

有些应用程序不支持可滚动光标和块光标,ODBC SDK提供了一个光标库(ODBCCR32.DLL),在应用程序中可通过设置连接属性(SQL_STTR_ODBC_CURSOR)激活光标库。

6  记录的添加、删除和更新:数据源数据更新可通过3种方式:通过SQLExecDirect函数使用相应的SQL语句;调用SQLSetPos函数实现记录集定义更新;调用SQLBulkOperations函数实现数据更新。

第一种方式适用于任何ODBC数据源,后两种方式有的数据源不支持,可调用SQLGetInfo确定数据源。

SQLBulkOperations:该函数操作基于当前行集,调用前,须先调用SQLFetchSQLFetchScroll获取。

函数调用后,块光标的位置变为未定义状况,因此,应该先调用函数SQLFetchScroll设定光标位置。

7、错误处理:每个ODBC API函数都能产生一系列反映操作信息的诊断记录,可以用SQLGetDiagField函数获取诊断记录中特定的域,另外,可以使用SQLGetDiagRec获取诊断记录中一些常用的域。

8、事务处理:事务提交有两种方式:自动提交模式手动提交模式。应用程序可通过调用函数SQLSetConnectAttr设定连接属性SQL_ATTR_AUTOCOMMIT,自动提交模式是默认的连接属性设置,对于所有的ODBC驱动程序都能适应这种模式下,所有语句都是作为一个独立的事务进行处理的。

手动提交模式把一组SQL语句放入一个事务中,程序必须调用函数SQLEenTran明确地终止一个事务。若使用多个激活的事务,就必须建立多个连接,每一个连接包含一个事务。

9、断开数据连接并释放环境句柄:完成数据库操作后,可调用SQLDisconnect函数关闭同数据库的连接。

 

 

 


#include <windows.h>
#include <sql.h>
#include <sqlext.h>
#include <sqltypes.h>
#include <iostream.h>
#include <iomanip.h>

SQLHENV m_henv;
SQLHDBC m_hdbc;
SQLHSTMT m_hstmt;
SQLRETURN m_retcode = SQL_SUCCESS;

void main()
{
   cout << "begin connect the database...." << endl;

   //分配环境句柄
   m_retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &m_henv);
   if ((m_retcode != SQL_SUCCESS) && (m_retcode != SQL_SUCCESS_WITH_INFO))
   {
    cout<< "分配环境句柄失败!" << endl;
    return;
   }

   /* Set the ODBC version environment attribute */
   m_retcode = SQLSetEnvAttr(m_henv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
   if ((m_retcode != SQL_SUCCESS) && (m_retcode != SQL_SUCCESS_WITH_INFO))
   {
    cout << "设置odbc版本号时失败!" << endl;
    return;
   } 
   /*分配连接句柄 */
   m_retcode = SQLAllocHandle(SQL_HANDLE_DBC, m_henv, &m_hdbc);
   if ((m_retcode != SQL_SUCCESS) && (m_retcode != SQL_SUCCESS_WITH_INFO))
   {
    cout << "分配连接句柄失败!" << endl;
    return;
   }
  
   /* 连接数据库 */
   m_retcode = SQLConnect(m_hdbc, (SQLCHAR*)"long", SQL_NTS,
                               (SQLCHAR*) "sa", SQL_NTS,
          (SQLCHAR*) "1", SQL_NTS);
    if ((m_retcode != SQL_SUCCESS) && (m_retcode != SQL_SUCCESS_WITH_INFO))
 {
    cout <<"连接数据库失败!" <<endl;
    return;
 }

 //分配句柄
    m_retcode = SQLAllocHandle(SQL_HANDLE_STMT, m_hdbc, &m_hstmt);
    if ((m_retcode != SQL_SUCCESS) && (m_retcode != SQL_SUCCESS_WITH_INFO))
 {
    cout << "分配语句句柄失败,不能执行" << endl;
    return;
 }


    //插入一条数据
 m_retcode = SQLExecDirect(m_hstmt, (unsigned char *) "insert into tab_stu values(3,'e','f')", SQL_NTS);
 if ((m_retcode != SQL_SUCCESS) && (m_retcode != SQL_SUCCESS_WITH_INFO) && (m_retcode != SQL_NO_DATA))
 {
  cout << "执行sql语句失败,不能执行" << endl;
  SQLFreeHandle(SQL_HANDLE_STMT, m_hstmt);
  m_hstmt = NULL;
  return;
 }
   
 //根据SQL语句查询信息
 m_retcode = SQLExecDirect(m_hstmt, (unsigned char *)"select * from tab_stu", SQL_NTS);
 if ((m_retcode != SQL_SUCCESS) && (m_retcode != SQL_SUCCESS_WITH_INFO))
 {
  cout << "执行sql语句失败" << endl;
  SQLFreeHandle(SQL_HANDLE_STMT, m_hstmt);
  m_hstmt = NULL;
  return;
 }
   
 SQLSMALLINT iNumCols = 0;
 m_retcode = SQLNumResultCols(m_hstmt, &iNumCols);
 if ((m_retcode != SQL_SUCCESS) && (m_retcode != SQL_SUCCESS_WITH_INFO))
 {
  cout << "取列数失败,不能执行" << endl;
  return;
 }


 cout << iNumCols << endl;

 
 SQLFreeHandle(SQL_HANDLE_STMT, m_hstmt);
 m_hstmt = NULL;
 return;


}

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值