📄 compute.cpp
字号:
}
}
}
// Create a string for bound return values if required.
if (pODBCSetInfo[nSet].pRows == NULL)
{
CreateDBBindings(&(pODBCSetInfo[nSet]));
}
// Binding must be done on each result set.
BindCols(hstmt, pODBCSetInfo[nSet].nCols,
pODBCSetInfo[nSet].pODBCColInfo, pODBCSetInfo[nSet].pRows);
// Set for ODBC row array retrieval. Fast retrieve for all sets.
SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_BIND_TYPE,
(void*) pODBCSetInfo[nSet].cbResultSet, SQL_IS_UINTEGER);
SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_ARRAY_SIZE,
(void*) pODBCSetInfo[nSet].nRows, SQL_IS_UINTEGER);
SQLSetStmtAttr(hstmt, SQL_ATTR_ROWS_FETCHED_PTR, (void*) &nRowsFetched,
sizeof(SQLINTEGER));
while (TRUE)
{
// In ODBC 3.x, SQLFetch supports arrays of bound rows or columns.
// SQLFetchScroll (or ODBC 2.x SQLExtendedFetch) is not necessary
// to support fastest retrieval of our data rows.
sRet = SQLFetch(hstmt);
if (sRet == SQL_ERROR)
{
DumpError(SQL_HANDLE_STMT, hstmt);
goto EXIT;
}
else if (sRet == SQL_NO_DATA)
{
break;
}
else if (sRet == SQL_SUCCESS_WITH_INFO)
{
DumpError(SQL_HANDLE_STMT, hstmt);
}
// Display the data. On each column, check the indicator and
// print the string "<null>" if no data available.
for (nRow = 0; nRow < (UINT) nRowsFetched; nRow++)
{
for (nCol = 0; nCol < pODBCSetInfo[nSet].nCols; nCol++)
{
_tprintf(_T("%s%s:"),
pODBCSetInfo[nSet].pODBCColInfo[nCol].szColName,
(pODBCSetInfo[nSet].pODBCColInfo[nCol].cbColName > 7 ?
_T("\t") : _T("\t\t")));
pIndicator = (SQLINTEGER*) (pODBCSetInfo[nSet].pRows +
(nRow * pODBCSetInfo[nSet].cbResultSet) +
pODBCSetInfo[nSet].pODBCColInfo[nCol].obIndicator);
if (*pIndicator == SQL_NULL_DATA)
{
_tprintf(_T("\t<null>\n"));
}
else
{
pValue = pODBCSetInfo[nSet].pRows +
((nRow * pODBCSetInfo[nSet].cbResultSet) +
pODBCSetInfo[nSet].pODBCColInfo[nCol].obValue);
switch (pODBCSetInfo[nSet].pODBCColInfo[nCol].fBindType)
{
case SQL_C_CHAR:
{
printf("\t%s\n", (char*) pValue);
break;
}
case SQL_C_SLONG:
{
printf("\t%lu\n", *(ULONG*) pValue);
break;
}
case SQL_C_DOUBLE:
{
printf("\t%f\n", *(double*) pValue);
break;
}
default:
{
_tprintf(_T("\tUnsupported conversion.\n"));
break;
}
}
}
}
_tprintf(_T("\n"));
}
}
// If another result set exists, then get the next set.
if (SQLMoreResults(hstmt) == SQL_SUCCESS)
{
// Determine the result set indicator (0 for normal result set,
// number of COMPUTE clause set).
sRet = SQLColAttribute(hstmt, 1, SQL_CA_SS_COMPUTE_ID,
NULL, 0, NULL, (SQLPOINTER) &nSet);
}
else
{
break;
}
}
EXIT:
// Cleanup and go home.
if (pODBCSetInfo != NULL)
{
for (nSet = 0; nSet < nComputes + 1; nSet++)
{
if (pODBCSetInfo[nSet].pODBCColInfo != NULL)
delete [] pODBCSetInfo[nSet].pODBCColInfo;
if (pODBCSetInfo[nSet].pRows != NULL)
delete [] pODBCSetInfo[nSet].pRows;
if (pODBCSetInfo[nSet].pByList != NULL)
{
if (pODBCSetInfo[nSet].pByList->pBys != NULL)
delete [] pODBCSetInfo[nSet].pByList->pBys;
delete [] pODBCSetInfo[nSet].pByList;
}
}
delete [] pODBCSetInfo;
}
return;
}
// GetColumnsInfo(...) -- Query the result set to determine the properties
// of result set columns.
SQLRETURN GetColumnsInfo ( SQLHSTMT hstmt, SWORD nCols, ODBCCOLINFO** ppODBCColInfo )
{
ODBCCOLINFO* pODBCColInfo;
SWORD nCol;
SQLRETURN sRet;
SQLINTEGER nComputeCol;
pODBCColInfo = new ODBCCOLINFO[nCols];
if (pODBCColInfo == NULL)
{
DumpError(_T("Out of memory"));
return (SQL_ERROR);
}
for (nCol = 0; nCol < nCols; nCol++)
{
sRet = SQLDescribeCol(hstmt, nCol+1,
pODBCColInfo[nCol].szColName,
CBCOLNAME_MAX + 1,
&pODBCColInfo[nCol].cbColName,
&pODBCColInfo[nCol].fSQLType,
&pODBCColInfo[nCol].cbColData,
&pODBCColInfo[nCol].cbScale,
&pODBCColInfo[nCol].fNullable
);
if (sRet == SQL_ERROR)
{
DumpError(SQL_HANDLE_STMT, hstmt);
break;
}
SQLColAttribute(hstmt, nCol+1, SQL_CA_SS_COLUMN_ID,
NULL, 0, NULL, (SQLPOINTER) &nComputeCol);
switch (pODBCColInfo[nCol].fSQLType)
{
case SQL_CHAR:
case SQL_VARCHAR:
case SQL_NUMERIC:
case SQL_DECIMAL:
{
pODBCColInfo[nCol].fBindType = SQL_C_CHAR;
pODBCColInfo[nCol].cbColData =
AdjustLen(pODBCColInfo[nCol].cbColData + 1);
break;
}
case SQL_REAL:
case SQL_FLOAT:
case SQL_DOUBLE:
{
pODBCColInfo[nCol].fBindType = SQL_C_DOUBLE;
pODBCColInfo[nCol].cbColData = sizeof(double);
break;
}
case SQL_INTEGER:
case SQL_SMALLINT:
case SQL_TINYINT:
case SQL_BIT:
{
pODBCColInfo[nCol].fBindType = SQL_C_SLONG;
pODBCColInfo[nCol].cbColData = sizeof(long);
break;
}
default:
{
SQLColAttribute(hstmt, nCol+1, SQL_DESC_DISPLAY_SIZE,
NULL, 0, NULL, &pODBCColInfo[nCol].cbColData);
pODBCColInfo[nCol].fBindType = SQL_C_CHAR;
pODBCColInfo[nCol].cbColData =
AdjustLen(pODBCColInfo[nCol].cbColData + 1);
break;
}
}
}
*ppODBCColInfo = pODBCColInfo;
return (sRet);
}
// CreateDBBindings(...) -- Determine the row length for bound values.
void CreateDBBindings ( PODBCSETINFO pODBCSetInfo )
{
SQLUSMALLINT nCol;
UDWORD cbRow = 0;
for (nCol = 0; nCol < pODBCSetInfo->nCols; nCol++)
{
// Set the data buffer pointer and then add the width of the
// bound buffer.
pODBCSetInfo->pODBCColInfo[nCol].obValue = cbRow;
cbRow += pODBCSetInfo->pODBCColInfo[nCol].cbColData;
// Indicators bound beyond data.
pODBCSetInfo->pODBCColInfo[nCol].obIndicator = cbRow;
cbRow += sizeof(SQLINTEGER);
}
pODBCSetInfo->pRows = new BYTE[cbRow * pODBCSetInfo->nRows];
pODBCSetInfo->cbResultSet = (SQLUINTEGER) cbRow;
return;
}
// BindCols(...) -- Bind the columns in the structure.
SQLRETURN BindCols (
SQLHSTMT hstmt,
SQLUSMALLINT nCols,
PODBCCOLINFO pODBCColInfo,
PBYTE pRows
)
{
SQLUSMALLINT nCol;
for (nCol = 0; nCol < nCols; nCol++)
{
if (SQLBindCol(hstmt, nCol + 1, pODBCColInfo[nCol].fBindType,
(SQLPOINTER) (pRows + pODBCColInfo[nCol].obValue),
pODBCColInfo[nCol].cbColData,
(SQLINTEGER*) (pRows + pODBCColInfo[nCol].obIndicator)) ==
SQL_ERROR)
{
return (SQL_ERROR);
}
}
return (SQL_SUCCESS);
}
// DumpError(PTSTR) -- printf the string to the console.
void DumpError
(
PTSTR pErrorText
)
{
_tprintf(_T("%s\n"), pErrorText);
}
// DumpError(SQLSMALLINT, SQLHANDLE) -- printf the diagnostic records for the
// handle received.
void DumpError(
SQLSMALLINT eHandleType,
SQLHANDLE hodbc
)
{
SQLTCHAR szState[SQL_SQLSTATE_SIZE + 1];
SQLTCHAR szMessage[SQL_MAX_MESSAGE_LENGTH + 1];
SQLINTEGER nServerError;
SQLSMALLINT cbMessage;
UINT nRec = 1;
while (SQL_SUCCEEDED(SQLGetDiagRec(eHandleType, hodbc, nRec, szState,
&nServerError, szMessage, SQL_MAX_MESSAGE_LENGTH + 1, &cbMessage)))
{
_tprintf(_T("SQLSTATE: %s\nNative error: %ld\nMessage: %s\n"),
(PTSTR) szState, nServerError, (PTSTR) szMessage);
nRec++;
}
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -