《C 语言也能干大事》第十六节:数据库开发3
本课程的参考教材:杨中科的《程序员的SQL 金典》第四章
2、C 语言中访问数据库
a)
ODBC 简介。ODBC 是微软提供的访问数据库的一种标准接口,通过ODBC 可以连
接MSSQLServer、MYSQL、DB2、Oracle、Access 等各种数据库,通过统一的函数
进行访问,也就是访问各种数据库都可以使用统一的函数。屏蔽了连接不同数据
库的差异性。
b)
除了ODBC 之外还有ADO、ADO.net 等,Java 中有JDBC 等。都有连接、结果集、
游标、事务、参数化SQL 等概念,一通百通。
c)
没安装MYODBC(MYSQL 的ODBC 驱动)的首先安装MYODBC。
http://down1.rupeng.com/download/software/MYODBC.rar
d)
sql.h、sqlext.h、sqltypes.h
e)
添加连接库“odbc32.lib odbccp32.lib”。如果使用的是rupeng 的DialogBased 向
导则已经自动添加。如果使用其他向导或者C-Free、PellesC 等开发工具,则需要
手动添加
f)
看模板代码。不用关心每个函数,用的时候copy 以后改一改就可以,理解只要
流程、主要概念即可,不要深究。有兴趣的可以研究CHECKDBSTMTERROR 宏的
实现。
g)
访问数据库可能遇到的错误:连接错误、执行错误。
h)
连接数据库、执行SQL、断开连接。连接字符串。数据库错误处理。
SQLHDBC hdbc:代表一个数据库连接句柄。和Socket 里边的Socket 连接类似,
要访问数据库,先要连接到数据库。SQLHDBC:SQL、H 句柄、DB(DataBase)、
C(Connection)
SQLHSTMT hstmt:代表一个SQL 语句。STMT(Statement,语句)
SQLRETURN:执行结果。
ODBC 中字符串用SQLCHAR,SQLCHAR 其实就是char 的别名。
SQLCHAR ConnStrIn[MAXBUFLEN]和char ConnStrIn[MAXBUFLEN]一样。
ConnStrIn:连接字符串,你要连接到的数据库的驱动、ip 地址、用户名密码、数
据库名(Catalog)等等都在连接字符串里描述。DRIVER:使用的驱动名;SERVER:
ip 地址;UID:用户名(UserID);PWD(Password):密码。DataBase:数据库
名,Catalog。
SQLDriverConnect:创建到数据库的连接,使用ConnStrIn 连接。result 表示执行
结果。如果失败了SQL_ERROR==result。ShowDBConnError(hwnd,hdbc);来显示“连
接错误”。
result = SQLPrepare(hstmt,(SQLCHAR*)"insert into T_Person(FAge,FName)
values(20,'kider')",SQL_NTS)。创建SQL 语句的句柄。
result =SQLExecute(hstmt);:执行SQL 语句。
SQLFreeStmt(hstmt,SQL_CLOSE);:释放SQL 语句
SQLDisconnect(hdbc);:断开数据库连接。
课下参考《程序员的SQL 金典》进行深一步的学习和预习。
模板代码:
#include "stdafx.h"
#include
#include
#include
#include
#include
#include "resource.h"
#include "MainDlg.h"
#define LOGIN_TIMEOUT 30
#define MAXBUFLEN 255
#define CHECKDBSTMTERROR(hwnd,result,hstmt) if(SQL_ERROR==result){ShowDBStmtError(hwnd,hstmt);return;}
/*
Template designed by RuPeng.com. Please visit http://www.rupeng.com for more information
如鹏网(http://www.rupeng.com)大学生计算机学习社区,提供大量免费视频学习教程,提供个性化一对一学习指导
*/
BOOL WINAPI Main_Proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
HANDLE_MSG(hWnd, WM_INITDIALOG, Main_OnInitDialog);
HANDLE_MSG(hWnd, WM_COMMAND, Main_OnCommand);
HANDLE_MSG(hWnd,WM_CLOSE, Main_OnClose);
}
return FALSE;
}
BOOL Main_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam)
{
return TRUE;
}
void Main_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
{
switch(id)
{
case IDC_OK:
{
//、MessageBox(hwnd,TEXT("欢迎访问如鹏网 www.RuPeng.com 大学生计算机学习社区"),TEXT("问好"),MB_OK);
DBTest(hwnd);
}
break;
default:
break;
}
}
void Main_OnClose(HWND hwnd)
{
EndDialog(hwnd, 0);
}
void ShowDBError(HWND hwnd,SQLSMALLINT type,SQLHANDLE sqlHandle)
{
char pStatus[10], pMsg[101];
SQLSMALLINT SQLmsglen;
char error[200] = {0};
SQLINTEGER SQLerr;
long erg2 = SQLGetDiagRec(type, sqlHandle,1,(SQLCHAR *)pStatus,&SQLerr,(SQLCHAR *)pMsg,100,&SQLmsglen);
wsprintf(error,"%s (%d)\n",pMsg,(int)SQLerr);
MessageBox(hwnd,error,TEXT("数据库执行错误"),MB_ICONERROR|MB_OK);
}
void ShowDBConnError(HWND hwnd,SQLHDBC hdbc)
{
ShowDBError(hwnd,SQL_HANDLE_DBC,hdbc);
}
void ShowDBStmtError(HWND hwnd,SQLHSTMT hstmt)
{
ShowDBError(hwnd,SQL_HANDLE_STMT,hstmt);
}
void DBTest(HWND hwnd)
{
SQLHENV henv = NULL;
SQLHDBC hdbc = NULL;
SQLHSTMT hstmt = NULL;
SQLRETURN result;
SQLCHAR ConnStrIn[MAXBUFLEN] = "DRIVER={MySQL ODBC 5.1 Driver};SERVER=127.0.0.1;UID=root;PWD=561141;DATABASE=user;CharSet=gbk;";
SQLCHAR ConnStrOut[MAXBUFLEN];
//分配环境句柄
result = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE,&henv);
//设置管理环境属性
result = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION,
(void*)SQL_OV_ODBC3, 0);
//分配连接句柄
result = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
//设置连接属性
result = SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT,
(void*)LOGIN_TIMEOUT, 0);
//连接数据库
result = SQLDriverConnect(hdbc,NULL,ConnStrIn,SQL_NTS,ConnStrOut,MAXBUFLEN,(SQLSMALLINT *)0,SQL_DRIVER_NOPROMPT);
if(SQL_ERROR==result)
{
ShowDBConnError(hwnd,hdbc);
return;
}
//初始化语句句柄
result = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
//SQL_NTS telling the function the previous parameter is Null-Terminated String,
//please alculate the string length for me
result = SQLPrepare(hstmt,(SQLCHAR*)"insert into db_mvc(name,password) values('陈贤纳',123456)",SQL_NTS);
CHECKDBSTMTERROR(hwnd,result,hstmt);
result =SQLExecute(hstmt);
CHECKDBSTMTERROR(hwnd,result,hstmt);
SQLFreeStmt(hstmt,SQL_CLOSE);
SQLDisconnect(hdbc);
SQLFreeHandle(SQL_HANDLE_DBC,hdbc);
SQLFreeHandle(SQL_HANDLE_ENV,henv);
MessageBox(hwnd,TEXT("执行成功"),TEXT("标题"),MB_OK);
}
提示:
如何查看ODBC的版本
http://wenda.haosou.com/q/1371478204064589