windows下操作数据库主要的功能有:连接数据库,绑定插入数据,批量绑定插入(多为结构体),读取数据库数据,本文主要简单的使用实现这几个功能用到的底层函数
一.连接数据库
SQLHENV m_henv; //ODBC环境句柄
SQLHDBC m_hdbc; //ODBC连接句柄
SQLHSTMT m_hstmt; //ODBC执行句柄
ret = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &m_henv);
if (ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO)
{
cout << "分配ODBC环境句柄错误." << endl;
return -1;
}
ret = SQLSetEnvAttr(m_henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, SQL_IS_INTEGER);
if (ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO)
{
cout<< "设置ODBC环境句柄版本号错误" <<endl;
return -1;
}
ret = SQLAllocHandle(SQL_HANDLE_DBC, m_henv, &m_hdbc);
if (ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO)
{
cout << "分配ODBC连接句柄错误." << endl;
return -1;
}
ret = SQLSetConnectAttr(m_hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER)timeout, 0);
if (ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO)
{
cout<< "设置ODBC连接属性错误"<<endl;
return -1;
}
ret = SQLConnect(m_hdbc, (SQLCHAR *)m_Char_DNS, SQL_NTS,
(SQLCHAR *)m_Char_user_name, SQL_NTS,
(SQLCHAR *)m_Char_pass_word, SQL_NTS);
if (ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO)
{
cout<< "ODBC连接失败" <<endl;
return -1;
}
//这里填自己数据的DNS,username,password
ret = SQLAllocHandle(SQL_HANDLE_STMT, m_hdbc, &m_hstmt);
if (ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO)
{
cout << "分配ODBC SQL句柄错误." << endl;
return -1;
}
至此,数据库连接完毕.
二.绑定插入数据
int iInput = 100;
char szInput[5] = '大连';
SQLRETURN ret = SQLPrepare(m_hstmt, (SQLCHAR *)"insert into provider values('S1','商品',?,?)", SQL_NTS);
SQLBindParameter(m_hstmt, 1, SQL_PARAM_INPUT, SQL_C_SLONG,
SQL_INTEGER, 0, 0, &iInput, 0, NULL);
SQLBindParameter(m_hstmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR,
SQL_CHAR, 5, 0, szInput, 0, NULL);
ret = SQLExecute(m_hstmt);
绑定数据插入主要用到的函数为SQLBindParameter,注意其中参数的意义,原函数如下
SQLRETURN SQLBindParameter(
SQLHSTMT StatementHandle,
SQLUSMALLINT ParameterNumber,
SQLSMALLINT InputOutputType,
SQLSMALLINT ValueType,
SQLSMALLINT ParameterType,
SQLUINTEGER ColumnSize,
SQLSMALLINT DecimalDigits,
SQLPOINTER ParameterValuePtr,
SQLINTEGER BufferLength,
SQLINTEGER * StrLen_or_IndPtr);
StatementHandle:执行SQL语句STMT句柄。
ParameterNumber:指明要将变量与第几个参数绑定,从1开始计算。
InputOutputType:指明是输入还是输出参数。可以取值的范围为:SQL_PARAM_INPUT,SQL_PARAM_OUTPUT ,SQL_PARAM_INPUT_OUTPUT。
ValueType:指明用于和参数绑定的C语言数据类型。
ParameterType:指明在存储过程中ODBC数据类型。
ColumnSize:指明接收数据的宽度,对于字符串和结构需要指明数据的宽度,而对于普通的变量如SQLINTEGER,SQLFLOAT等设置为0就可以了。
DecimalDigits :当数据类型为SQL_NUMERIC,SQL_DECIMAL时指明数字小数点的精度,否则填0。
ParameterValuePtr:在作为输入参数指明参数的指针,在作为输出参数时指明接收数据的变量指针。
BufferLength:指明参数指针所指向的缓冲区的字节数大小。对于字符串和结构需要指明大小,而对于普通的变量如SQLINTEGER,SQLFLOAT等设置为0就可以了。
StrLen_or_IndPtr: 作为输入参数时指明数据的字节数大小,对于普通的定长变量如SQLINTEGER,SQLFLOAT等设置为0就可以了,
对于字符号串需要在此参数中指定 字符串数据的长度,或者设置为SQL_NULL_DATA表明此参数为空值,或者设置为SQL_NTS表明字符串以NULL字符结尾,
对于结构需要指明结 构的长度。当作为输出参数时,当SQL执行完毕后会在这个参数中返回拷贝的缓冲区的数据的字节数。
三.批量绑定插入
struct test
{
int a;
char b[5];
};
test szInput[5];
szInput[0].a = 1;
strcpy_s(szInput[0].b, "S1");
szInput[1].a = 2;
strcpy_s(szInput[1].b, "S2");
szInput[2].a = 3;
strcpy_s(szInput[2].b, "S3");
szInput[3].a = 4;
strcpy_s(szInput[3].b, "S4");
szInput[4].a = 5;
strcpy_s(szInput[4].b, "S5")
//简单的定义了一个结构体数组,赋值准备批量插入
ret = SQLSetStmtAttr(m_hstmt, SQL_ATTR_PARAM_BIND_TYPE, (SQLPOINTER)sizeof(test), 0);
if (ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO)
{
ShowError(SQL_HANDLE_ENV, m_henv, "结构体大小绑定错误");
return -1;
}
ret = SQLSetStmtAttr(m_hstmt, SQL_ATTR_PARAMSET_SIZE, (SQLPOINTER)5, 0);
if (ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO)
{
ShowError(SQL_HANDLE_ENV, m_henv, "结构体数量绑定错误");
return -1;
}
SQLRETURN ret = SQLPrepare(m_hstmt, (SQLCHAR *)"insert into provider values(?,'商品',?,'大连')", SQL_NTS);
SQLBindParameter(m_hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR,
SQL_CHAR, 5, 0, &szInput[0].b, 0, NULL);
SQLBindParameter(m_hstmt, 2, SQL_PARAM_INPUT, SQL_C_SLONG,
SQL_INTEGER, 0, 0, &szInput[0].a, 0, NULL);
ret = SQLExecute(m_hstmt);
//绑定函数类似
批量绑定主要用到的函数为SQLSetStmtAttr,具体函数使用比较复杂可自行百度,这里只用到了行绑定的相关内容
四.读取数据库数据
char szSQL[100] = "select SNO,SName,STATUS from provider where status = 30";
int status = 0;
char sno[20];
char sname[20];
static SQLLEN StrLen_or_Ind;
SQLRETURN ret = SQLPrepare(m_hstmt, (SQLCHAR *)szSQL, SQL_NTS);
ret = SQLExecute(m_hstmt);
SQLBindCol(m_hstmt, 1, SQL_C_CHAR, sno, 20, &StrLen_or_Ind);
SQLBindCol(m_hstmt, 2, SQL_C_CHAR, sname, 20, &StrLen_or_Ind);
SQLBindCol(m_hstmt, 3, SQL_C_SLONG, &status, sizeof(int), &StrLen_or_Ind);
int i = 0;
while (SQLFetch(m_hstmt) != SQL_NO_DATA) //循环获取数据
{
cout << i++ << endl;
cout << "STATUS:" << status << endl;
cout << "SNO:" << sno << endl;
cout << "SNAME:" << sname << endl;
}
读取数据库绑定参数用的函数是SQLBindCol,函数参数定义如下
SQLRETURN SQLBindCol(
SQLHSTMT StatementHandle,
SQLUSMALLINT ColumnNumber,
SQLSMALLINT TargetType,
SQLPOINTER TargetValuePtr,
SQLINTEGER BufferLength,
SQLLEN * StrLen_or_Ind);
StatementHandle:STMT句柄。
ColumnNumber:列的位置,从1开始计算。
TargetType:指明用于和参数绑定的C语言数据类型。
BufferLength:指明参数指针所指向的缓冲区的字节数大小。对于字符串和结构需要指明大小,而对于普通的变量如SQLINTEGER,SQLFLOAT等设置为0就可以了。
StrLen_or_IndPtr:返回拷贝的缓冲区的数据的字节数。
以上即为主要功能的介绍,其他的基本函数
SQLExecDirect 直接执行sql语句
SQLRowCount 返回操作行数
SQLSetConnectAttr 开启/关闭事物
SQLEndTran 提交/回滚
希望本文能帮助刚接触ODBC的兄弟加速对其的理解,另外比较好的资料网址:
http://blog.csdn.net/skyremember/article/details/3917562 介绍了大量基础的函数并配有代码,很给力
同时还有我上传的ODBC使用手册 网址http://download.csdn.net/detail/wpf19920229/8754257