ODBC 连接 ORACLE数据库 代码

时间:2022-02-14 21:52:32
最近的任务是封装一个ODBC连接数据库的类,查找了不少资料,对ODBC的函数有所了解,记录一下心得
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