我使用ODBC API编写了一个动态连接库程序,
目的就是查询数据库,(使用select语句),
想一次性返回一个结果集合.但在运行时有错误.
下面是我的程序.请大家帮我看看,感激不尽.
如能解决,另有分相送.// DF21DDll.cpp : Defines the entry point for the DLL application.
//
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <sql.h>
#include <sqlext.h>
#include <sqltypes.h>
#include <odbcss.h>#define DF21DLLAPI _declspec(dllexport)#include "DF21Dll.h"DF21DLLAPI SQLFLOAT g_exportRCS[40];
DF21DLLAPI SQLSMALLINT g_exportDist[40];SQLHENV hEnv = SQL_NULL_HENV; // handle of environment
SQLHDBC hDbc = SQL_NULL_HDBC; // handle of database connectivity
SQLHSTMT hStmt = SQL_NULL_HSTMT; // handle of statementSQLFLOAT fInputTheta; // input parameter buffer
SQLFLOAT fInputPhi; // input parameter bufferSQLINTEGER iThetaInd;
SQLINTEGER iPhiInd;/*
SQLFLOAT fOutputRcs; // output parameter buffer
SQLSMALLINT nOutputDist; // output parameter bufferSQLINTEGER nIndPtr[2];
*/SQLINTEGER nRowSetArraySize = 40;SQLSMALLINT nDistance[40];
SQLFLOAT fRcs[40];SQLUSMALLINT nRowStatusArray[40];SQLINTEGER nDisInd[40];
SQLINTEGER nRcsInd[40];SQLUINTEGER nNumRowsFetched;
BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
 )
{
    return TRUE;
}void CheckReturnCode(SQLRETURN retCode)
{
if ((retCode != SQL_SUCCESS) && (retCode != SQL_SUCCESS_WITH_INFO)) 
{
DF21CleanupDB();
}
}/*
Description: Connect to DSN server with specified 
 uername and password.
Parameter  : szDSN[input] Pointer to the DSN name
 szUID[input] Pointer to the user name 
 szPassword[input] Pointer to the password
Return     : If connecting to the DSN successfully, return TRUE,
 otherwise FALSE.
*/
DF21DLLAPI BOOL DF21StartupDB(char* szDSN, char* szUID, char* szPassword)
{
SQLRETURN retCode;

// allocate environment handle
retCode = SQLAllocHandle(SQL_HANDLE_ENV, NULL, &hEnv); if (retCode != SQL_SUCCESS 
&& retCode != SQL_SUCCESS_WITH_INFO)
{
MessageBox(NULL, "Failed to call SQLAllocHandle()!", "Error Info", MB_OK|MB_ICONERROR);
return FALSE;
}
else
{
// set ODBC attribute
retCode = SQLSetEnvAttr(hEnv, SQL_ATTR_ODBC_VERSION,
(SQLPOINTER)SQL_OV_ODBC3,
SQL_IS_INTEGER);
if (retCode != SQL_SUCCESS 
&& retCode != SQL_SUCCESS_WITH_INFO)
{
SQLFreeHandle(SQL_HANDLE_ENV, hEnv);
MessageBox(NULL, "Failed to call SQLSetEnvAttr()!", "Error Info", MB_OK|MB_ICONERROR);
return FALSE;
}
else
{
// allocate connection handle
retCode = SQLAllocHandle(SQL_HANDLE_DBC, hEnv, &hDbc);
if (retCode != SQL_SUCCESS 
&& retCode != SQL_SUCCESS_WITH_INFO)
{
SQLFreeHandle(SQL_HANDLE_ENV, hEnv);
MessageBox(NULL, "Failed to call SQLAllocHandle()!", "Error Info", MB_OK|MB_ICONERROR);
return FALSE;
}
else
{
// connect to datasource
retCode = SQLConnect(hDbc, 
 (SQLCHAR*)szDSN, (SQLSMALLINT)strlen(szDSN),
 (SQLCHAR*)szUID, (SQLSMALLINT)strlen(szUID),
 (SQLCHAR*)szPassword, (SQLSMALLINT)strlen(szPassword));
if (retCode != SQL_SUCCESS 
&& retCode != SQL_SUCCESS_WITH_INFO)
{
SQLFreeHandle(SQL_HANDLE_DBC, hDbc);
SQLFreeHandle(SQL_HANDLE_ENV, hEnv);
MessageBox(NULL, "Failed to call SQLConnect()!", "Error Info", MB_OK|MB_ICONERROR);
return FALSE;
}
else
{
retCode = SQLAllocHandle(SQL_HANDLE_STMT, hDbc, &hStmt); if (retCode != SQL_SUCCESS
&& retCode != SQL_SUCCESS_WITH_INFO)
{
SQLDisconnect(hDbc);
SQLFreeHandle(SQL_HANDLE_DBC, hDbc);
SQLFreeHandle(SQL_HANDLE_ENV, hEnv);
MessageBox(NULL, "Failed to call SQLAllocHandle()!", "Error Info", MB_OK|MB_ICONERROR);
return FALSE;
}
else
{
retCode = SQLPrepare(hStmt,
         (SQLCHAR*)"select Dist, RCS from DF21 where Theta=? and Phi=? and RCS<>0  order by Dist desc",
 SQL_NTS);

retCode = SQLSetStmtAttr(hStmt, SQL_ATTR_ROW_BIND_TYPE, SQL_BIND_BY_COLUMN, 0);
retCode = SQLSetStmtAttr(hStmt, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER)(&nRowSetArraySize), SQL_IS_POINTER);
retCode = SQLSetStmtAttr(hStmt, SQL_ATTR_ROW_STATUS_PTR, nRowStatusArray, 0);
retCode = SQLSetStmtAttr(hStmt, SQL_ATTR_ROWS_FETCHED_PTR, &nNumRowsFetched, 0); // bind SQL parameter with input buffer
retCode = SQLBindParameter(hStmt, 1, SQL_PARAM_INPUT, SQL_C_DOUBLE, SQL_DOUBLE,
   10, 0, &fInputTheta, 0, &iThetaInd);
retCode = SQLBindParameter(hStmt, 2, SQL_PARAM_INPUT, SQL_C_DOUBLE, SQL_DOUBLE,
           10, 0, &fInputPhi, 0, &iPhiInd);

// bind buffer with output colume
retCode = SQLBindCol(hStmt, 1, SQL_C_SHORT,
 nDistance, sizeof(SQLSMALLINT), nDisInd);
retCode = SQLBindCol(hStmt, 2, SQL_C_DOUBLE,
 fRcs, sizeof(SQLFLOAT), nRcsInd);

CheckReturnCode(retCode);

return TRUE;
}
}
}
}
}
}/*
Description: Get Rcs from database with specified value of Theta and Phi.
Parameter  : fTheta[input] Specified value of theta
fPhi[input] Specified value of phi.
Return     : the count of RCS in exported float array-g_expRCS.
*/
DF21DLLAPI int DF21GetRCS(double fTheta, double fPhi)
{
fInputTheta = fTheta;
fInputPhi = fPhi; memset(&g_exportRCS, 0, sizeof(g_exportRCS));   // initial output buffer
memset(&g_exportDist, 0, sizeof(g_exportDist)); // initial output buffer

SQLRETURN retCode; retCode = SQLExecute(hStmt);
CheckReturnCode(retCode);

int nCnt = 0;
         // 下面这句代码运行时有问题.
retCode = SQLFetchScroll(hStmt, SQL_FETCH_NEXT, 0);
//retCode = SQLFetch(hStmt);
/*
do
{
retCode = SQLFetch(hStmt); if (retCode == SQL_SUCCESS || retCode == SQL_SUCCESS_WITH_INFO)
{
g_exportRCS[nCnt] = fOutputRcs;
g_exportDist[nCnt++] = nOutputDist;
}
} while (retCode == SQL_SUCCESS || retCode == SQL_SUCCESS_WITH_INFO);
*/ if (nCnt == 0)
{
/* 
The specified value is not in the database.
We have to do more work.
*/
MessageBox(NULL, "&Auml;ú&Ecirc;&auml;&Egrave;&euml;&micro;&Auml;&sup2;é&Ntilde;&macr;&sup2;&raquo;&Ocirc;&Uacute;&Ecirc;&yacute;&frac34;&Yacute;&iquest;&acirc;&Ouml;&ETH;!", "Error", MB_OK | MB_ICONSTOP);
}

SQLCloseCursor(hStmt);

return nCnt;
}/*
Description: Disconnect from database and release
allocated handles.
Parameter  : NULL
Return     :    NULL
*/
DF21DLLAPI void DF21CleanupDB()
{
SQLFreeHandle(SQL_HANDLE_STMT, hStmt);
SQLDisconnect(hDbc);
SQLFreeHandle(SQL_HANDLE_DBC, hDbc);
SQLFreeHandle(SQL_HANDLE_ENV, hEnv);
}