zoukankan      html  css  js  c++  java
  • ODBC API编程

    ODBC  API编程

    如果一个ODBC API函数执行成功,则返回SQL_SUCCESS或SQL_SUCCESS_WITH_INFO,SQL_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函数分配的。

    函数SQLGetStmrrAttr和SQLSetStmrrAttr用来获取和设置一个语句句柄的选项,使用完,调用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,或者直接释放句柄,都会结束所有记录字段的绑定。

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

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

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

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

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

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

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

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

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

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

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

    一个简单的ODBC操作数据库的例子:

    #include "stdafx.h"   
    #include "windows.h"   
    #include "Odbcinst.h"   
    #include "Sqltypes.h"   
    #include "Sqlucode.h"   
    #include "Sql.h"   
       
    #using <mscorlib.dll>   
    using namespace System;   
       
    #define NAME_LEN 50   
    #define PHONE_LEN 50   
    int _tmain()   
    {   
        SQLRETURN   sqlrc;   
        SQLHENV     henv;   
        SQLHDBC     hdbc;   
        SQLHSTMT    hstmt;   
        SQLCHAR     sCustID[NAME_LEN],szName[NAME_LEN], szPhone[PHONE_LEN];   
        SQLINTEGER   cbCustID, cbName, cbPhone;   
           
        sqlrc = SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&henv);   
        if(!SQL_SUCCEEDED(sqlrc))    
        {   
            Console::WriteLine(S"ALlocate the environment variabl is failed");   
            return 0;   
        }   
        sqlrc = SQLSetEnvAttr(henv,SQL_ATTR_ODBC_VERSION,(SQLPOINTER)SQL_OV_ODBC3,SQL_IS_INTEGER);   
        if(!SQL_SUCCEEDED(sqlrc))    
        {   
            Console::WriteLine(S"设置ODBC的版本失败");   
            return 0;   
        }   
        sqlrc = SQLAllocHandle(SQL_HANDLE_DBC,henv,&hdbc);   
        if(!SQL_SUCCEEDED(sqlrc))    
        {   
            Console::WriteLine(S"分配连接句柄失败");   
            return 0;   
        }   
        int iLoginTime = 5;   
        SQLSetConnectAttr(hdbc,SQL_LOGIN_TIMEOUT,(SQLPOINTER*)&iLoginTime, 0); //在建立连接之前和之后设置都可以   
           
        sqlrc = SQLConnect(hdbc,(SQLCHAR*)"Space",SQL_NTS,(SQLCHAR*)"sa",SQL_NTS,(SQLCHAR*)"mother",SQL_NTS);   
           
        if(!SQL_SUCCEEDED(sqlrc))    
        {   
            Console::WriteLine(S"连接数据库失败");   
            return 0;   
        }   
        sqlrc = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);   
        if(!SQL_SUCCEEDED(sqlrc))    
        {   
            Console::WriteLine(S"创建statement 句柄失败");   
            return 0;   
        }   
        sqlrc = SQLExecDirect(hstmt,(SQLCHAR*)"SELECT emp_id, fname, minit FROM employee ",SQL_NTS);//ORDER BY 2, 1, 3   
        if(!SQL_SUCCEEDED(sqlrc))    
        {   
            Console::WriteLine(S"执行statement 失败");   
            return 0;   
        }   
        while(true)   
        {   
            sqlrc = SQLFetch(hstmt);   
            if (sqlrc == SQL_SUCCESS || sqlrc == SQL_SUCCESS_WITH_INFO)   
            {   
                //从数据库中获取相关的数据列   
                SQLGetData(hstmt, 1, SQL_C_CHAR, sCustID, NAME_LEN, &cbCustID);   
                SQLGetData(hstmt, 2, SQL_C_CHAR, szName, NAME_LEN, &cbName);   
                SQLGetData(hstmt, 3, SQL_C_CHAR, szPhone, PHONE_LEN,&cbPhone);   
                //输出数据列    
                for(int iIndex = 0; iIndex < cbCustID; iIndex ++)   
                    Console::Write(Char::ToString(sCustID[iIndex]));   
                Console::Write("    ");   
                for(int iIndex = 0; iIndex < cbName; iIndex ++)   
                    Console::Write(Char::ToString(szName[iIndex]));   
                Console::Write("    ");   
                for(int iIndex = 0; iIndex < cbPhone; iIndex ++)   
                    Console::Write(Char::ToString(szPhone[iIndex]));   
                Console::WriteLine();   
            }   
            else   
                break;   
        }   
        SQLFreeHandle(SQL_HANDLE_STMT, hstmt);   
        SQLDisconnect(hdbc);   
        SQLFreeHandle(SQL_HANDLE_DBC, hdbc);   
        SQLFreeHandle(SQL_HANDLE_ENV, henv);   
        return 0;   
    }
  • 相关阅读:
    访客登录方案设计与应用
    VS Code下载
    dockerfile COPY命令失效
    mysql排序字段值相等时,分页数据重复
    go使用json包Marshal方法得到异常结果[123 125]
    Mysql知识点概览
    dockercompose安装
    docker安装
    Shell脚本执行报错:Syntax error: "(" unexpected
    二进制数的位运算,角色权限,多种账号来源
  • 原文地址:https://www.cnblogs.com/Dageking/p/2963767.html
Copyright © 2011-2022 走看看