⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 compute.cpp

📁 关于ODBC的操作接口的使用例子
💻 CPP
📖 第 1 页 / 共 2 页
字号:
                    }
                }
            }
            

        // 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 + -