通过ODBC API实现对数据库的访问

2016-06-17

自从初次接触到vckbase,在里面学了很多东西,这跟大家无私的奉献是离不开的。在数据库方面的技术文章中,很多篇幅是用来介绍ADO或者DAO的访问方式,而关于用ODBC API访问数据库的文章却少之又少。虽然用ODBC访问数据库比较麻烦,但却很灵活,效率高,又便于了解ADO、DAO的底层封装方式,对提升整体软件思想是很有好处的。

现在就数据库的操作类型来谈谈ODBC API的使用。

1、配置数据源。例:

SQLRETURN retcode;
Retcode = SQLConfigDataSource(NULL,ODBC_ADD_SYS_DSN,"SQL Server",
			
           "DSN=master\0Server=(local)\0Database=master\0\0");
			
if(!retcode)
			
{
			
    AfxMessageBox("系统数据源配置失败!");
			
    return FALSE;
}

2、连接数据库。连接数据库看似要写的很多,其实只要写一次以后,仅仅复制一下,改下数据库名、用户名和密码即可。例:

retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv) ;
				


if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) { retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0); if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) { retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc); if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) { retcode = SQLConnect(hdbc, (SQLCHAR*)(LPCTSTR)m_strDSN, SQL_NTS, (SQLCHAR*)(LPCTSTR)m_strUSER, SQL_NTS, (SQLCHAR*)(LPCTSTR)m_strPWD, SQL_NTS); if (!(retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)) { AfxMessageBox("数据库连接失败!") ; SQLFreeHandle(SQL_HANDLE_DBC, hdbc); SQLFreeHandle(SQL_HANDLE_ENV, henv); return FALSE; } else { m_bLink = TRUE; return TRUE; } } else { AfxMessageBox("连接句柄分配出错") ; SQLFreeHandle(SQL_HANDLE_DBC, hdbc); SQLFreeHandle(SQL_HANDLE_ENV, henv); return FALSE; } } else { AfxMessageBox("属性设置出错!") ; SQLFreeHandle(SQL_HANDLE_ENV, henv); return FALSE; } } else { AfxMessageBox("环境变量分配出错!") ; SQLFreeHandle(SQL_HANDLE_ENV, henv); return FALSE; }

3、表操作。连接完数据库后,可以在数据库中执行SQL语句来实现对数据库表的查询。其具体操作类型又可以分成删除表、创建表、修改表等。例:

BOOL CDbOperator::CreateTable(CString strSQL)
			
{
			
 
		 	SQLHSTMT hstmt ;
			

			  SQLRETURN retcode;
			

			  SQLINTEGER cbLenth = 0 ;
			

			 
			
 
		 	retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
			

			  if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) 
			

			    {
			

			      retcode = SQLExecDirect(hstmt, (SQLCHAR*)(LPCTSTR)strSQL, SQL_NTS);
			

			      if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
			

			      {
			

			        SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
			

			        return TRUE;
			

			       }
			

			   else
			

			     {
			

			       SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
			

			       return FALSE;
			

			      }
			

			    }
			

			   else
			

			    {
			

			      SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
			

			      return FALSE;
			

			       }
			

			}

4、表纪录的操作。连接完数据库后,将指定的变量与相应表中的某个字段关联在一起,在数据库中执行SQL语句来实现对数据库表的查询。其具体操作类型又可以分成插入表纪录、更新表纪录、查询表纪录、删除表纪录等。注意关联的时候,变量类型必须与表字段的数据类型乡一致,详情可查看MSDN。例:

BOOL CDbOperator::GetUserIdFromObj_User(int arrUserId[], int& nUserCount) 
			
{ 
			
int nUserId = 0; 
			
nUserCount = 0; 
			
CString strSQL; 
			
  
			
SQLHSTMT hstmt ; 
			
SQLRETURN retcode;  
			
SQLINTEGER cbLenth = 0 ; 
			
strSQL = "SELECT User_Iden FROM Obj_User"; 
			
retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt); 
			
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)  
			
   { 
			
    SQLBindCol(hstmt, 1, SQL_C_ULONG, (SQLPOINTER)&nUserId, sizeof(nUserId), &cbLenth); 
			
    if (SQLExecDirect(hstmt, (SQLCHAR*)(LPCTSTR)strSQL, SQL_NTS) == SQL_ERROR) 
			
     { 
			
      AfxMessageBox("数据操作失败!") ; 
			
      SQLFreeHandle(SQL_HANDLE_STMT, hstmt); 
			
      return FALSE; 
			
      } 
			
     while((SQLFetch(hstmt) == SQL_SUCCESS) || (SQLFetch(hstmt) == SQL_SUCCESS_WITH_INFO)) 
			
      { 
			
       arrUserId[nUserCount] = nUserId; 
			
       nUserCount++;  
			
      } 
			
      SQLFreeHandle(SQL_HANDLE_STMT, hstmt); 
			
      returnTRUE; 
			
   } 
			
else 
			
  { 
			
    AfxMessageBox("数据操作失败!") ; 
			
    SQLFreeHandle(SQL_HANDLE_STMT, hstmt); 
			
    return FALSE; 
			
   } 
			
   return TRUE; 
			
}

注意:在SQL SERVER数据库中,master数据库是占有统治地位的,它纪录了所有数据库的创建信息。故在创建一个新的数据库之前可以通过连接matser数据库,并在master数据库中执行创建数据库的SQL语句来创建一个新的数据库。为了防止数据库的重复创建,必须在创建之前判断你所创建的数据库是否已经存在。如果存在的话,则退出;否则创建新的数据库。Matster数据库中其中有张表sysdatabases纪录了所有已经创建的数据库名。如果能够在该表中查询出该名字的数据库,说明数据库已经创建;否则,不创建数据库。同时,Master数据库中有一张表sysobjects纪录了所有数据库的所有表名。所以可以通过查询这个表来判断你所创建的表是否已经存在。掌握了以上几个要素,就可以动态创建数据库。很神奇吧?

若想对ODBC API访问数据进一步了解,大家可以看看我的例子(例子仅仅是个模板,并没有优化代码)。其中,程序执行后,输入用户zhengyu和密码4352729后即可创建完数据库,就这么方便。大家也可以给我发邮件跟我交流。

执行结果如下:

 

QQ:181484408