动态数据库查询与数据获取

在编程过程中,可能会遇到一些场景,直到运行时才知道数据库的模式。例如,即席查询和报告工具。在这些情况下,最终用户被允许从一系列表格中构建他们自己的SQL。正如可能已经知道的,通过ODBC执行SQL字符串并检索结果数据是非常容易的。但是,当在编写应用程序时不知道结果数据将是什么样子,该如何做呢?幸运的是,ODBC提供了几个函数,可以用于这个目的。在连接到数据源之后,接下来需要的步骤如下:

  1. 通过SQLPrepare函数准备SQL语句。
  2. 使用SQLExecute函数执行SQL语句。
  3. 调用SQLNumResultCols以找出返回结果集中的列数。
  4. 对于每一列,调用SQLDescribeCol函数以获取列类型。
  5. 对于每一列,将从SQLDescribeCol返回的SQL类型转换为C类型。
  6. 对于结果集中的每一行,根据C类型分配数据内存。
  7. 对于每一行,调用SQLGetData函数将数据读取到为该行/列分配的内存中。

说过“幸运”吗?实际上,是带着讽刺的语气说的。因此,在本文中,向提交了一个类(CODBCDynamic),它将实现上述功能所需的400多行代码减少到2行代码!以下是如何使用CODBCDynamic类的示例。

如何使用CODBCDynamic类

本文还包括一个完整的测试应用程序,但在下载、解压缩和运行别人的代码之前,能够看到将获得什么总是很好的。因此,以下是一些代码片段,展示了CODBCDynamic类是多么容易使用。

要提交SQL语句,只需实例化一个CODBCDynamic对象(传递一个有效的DSN),然后调用CODBCDynamic::ExecuteSQL成员函数(传递要执行的SQL字符串)。就是这样!

CODBCDynamic odbcDynamic(_T("YourDsn")); odbcDynamic.ExecuteSQL(_T("SELECT * from OrderHeader"));

在上面的第一个示例中,向展示了CODBCDynamic类如何允许使用ExecuteSQL成员函数提交SQL语句。然而,有时应用程序将只有HSTMT到结果集。例如,如果调用ODBC SDK函数SQLGetTypeInfo,将收到一个包含返回数据的结果集。使用CODBCDynamic类,可以使用以下两行代码将数据读取到其成员变量中。

odbcDynamic.FetchData(hstmt);

一旦调用了ExecuteSQL或FetchData成员函数,就可以以非常通用的方式从CODBCDynamic对象中检索结果数据。CODBCDynamic类有一个模板化数组(m_ODBCRecordArray),代表读取的每条记录。m_ODBCRecordArray中的每个条目是一个模板化的CMapStringToPtr映射,映射列及其在该记录中的相应值。该映射以列名(自动检索)为键,数据以CDBVariantEx对象的形式存在。

然而,永远不必担心这些技术细节。假设已经调用了ExecuteSQL或FetchData,以下是一个示例,展示了如何轻松地遍历SQL语句返回的记录。

CODBCDynamic odbcDynamic(_T("Forms Express System Database")); odbcDynamic.ExecuteSQL(_T("SELECT * from UserMaster")); CODBCRecordArray* pODBCRecordArray = &odbcDynamic.m_ODBCRecordArray; CString strInfo; for(int iRecord = 0; iRecord < pODBCRecordArray->GetSize(); iRecord++) { CODBCRecord* pODBCRecord = (*pODBCRecordArray)[iRecord]; POSITION pos; CDBVariantEx* pvarValue; CString strColName; CString strValue; for(pos = pODBCRecord->GetStartPosition(); pos != NULL;) { pODBCRecord->GetNextAssoc(pos, strColName, pvarValue); pvarValue->GetStringValue(strValue); strInfo.Format(_T("Record: %ld, Column: %s, Value: '%s'"), iRecord, strColName, strValue); AfxMessageBox(strValue); } } CODBCDynamic odbcDynamic(_T("Forms Express System Database")); odbcDynamic.ExecuteSQL(_T("SELECT * from UserMaster")); CODBCRecordArray* pODBCRecordArray = &odbcDynamic.m_ODBCRecordArray; for(int iRecord = 0; iRecord < pODBCRecordArray->GetSize(); iRecord++) { CODBCRecord* pODBCRecord = (*pODBCRecordArray)[iRecord]; CString strValue; CDBVariantEx* pvarValue = NULL; if(pODBCRecord->Lookup(_T("sUserId"), pvarValue)) { pvarValue->GetStringValue(strValue); AfxMessageBox(strValue); // 或者,如果列的数据类型是字符串或文本... AfxMessageBox(*pvarValue->m_pstring); } }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485