自從初次接觸到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
本文配套源碼