2012-02-10 55 views
0

我需要在C++/ODBC应用程序中摆脱固定数组大小。 而不是硬编码的数组大小(ROWS = 10以下)我想通过ROWS作为命令行参数。我知道如何解析命令行。 但是如何调整下面的代码?如何重构C++代码以支持动态数组大小

 
    #define ROWS 10 

    SQLINTEGER idata[ROWS] 
    SQLCHAR cdata1[ROWS][256] 
    SQLFLOAT fdata[ROWS] 
    SQL_TIMESTAMP_STRUCT ts[ROWS] 

    SQLSetStmtAttr(SQL_ATTR_ROW_ARRAY_SIZE, ROWS) 

    SQLBindCol(1, &idata) 
    SQLBindCol(2, cdata1) 
    SQLBindCol(3, fdata) 
    SQLBindCol(4, &ts) 
    SQLExecDirect("query producing a result-set") 

更新:我不能修改SQLBindCol的签名(..)

让我们说,我将创建的std ::载体,而不是SQLFLOAT FDATA [行数],但如何将其传递到SQLBindCol(),它不指望std :: vector?

+4

你不能有变长数组在C++中数组的长度必须是一个编译时constant.You可能要考虑使用'性病的动态二维阵列的解决方案: :vector'或'std :: array'而不是c-style数组。 – 2012-02-10 06:28:34

+2

C++不提供可变长度的数组,但它们当然不必是编译时常量。这就是'new []'的用途。例如'SQLINTEGER * idata = new SQLINTEGER [rows]'(并且不要忘记稍后'delete []')。多维数组cdata1是一个更大的问题,因为它不能动态分配。你可以做的最好的是一个数组或一个新的SQLCHAR [rows * 256],其中一个可能会工作,这取决于SQLBindCol在这里的工作方式。我对ODBC的了解还不够多,不仅如此。 – 2012-02-10 06:48:02

回答

1

fdata使用std::vector

size_t rowCount = /* ... */; 
std::vector<SQLFLOAT> fdata(rowCount); 
// ... 
SQLSetStmtAttr(SQL_ATTR_ROW_ARRAY_SIZE, rowCount); 
// ... 
SQLBindCol(3, &fdata[0]); 
// ... 

对于cdata1std::vector<SQLCHAR> cdata1(250 * rowCount);可能会奏效。

0

使用指针。

如您所说,接受来自命令行的ROWS参数。通过使用malloc/new来分配所有已声明的变量(如idata,cdata1等),使用动态内存分配分配所需大小的内存(ROWS参数)。就是这样!

0

我还没有设法使它与2d动态数组一起工作。 但这里是一个使用一维数组

std::set<std::string> getResults(int columnIndex, HSTMT stmt) { 
    std::set<std::string> results; 
    RETCODE rc = 0; 
    int rows = 250; 
    int colsize = 500 + 1; //Need to increment colunm size by 1 because SQLBindCol add the terminator character "\0" 

    SQLLEN *indicator1 = new SQLLEN[rows]; 
    char *buff = new char[rows*colsize]; 
    SQLSetStmtAttr(stmt, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER)rows, 0); 

    SQLUINTEGER  NumRowsFetched; 
    SQLSetStmtAttr(stmt, SQL_ATTR_ROWS_FETCHED_PTR, &NumRowsFetched, 0); 

    SQLBindCol(stmt, columnIndex, SQL_C_CHAR, buff, colsize, indicator1); 
    while (rc = SQLFetch(stmt) == SQL_SUCCESS) { 
     for (int i = 0; (SQLUINTEGER)i < NumRowsFetched; i++) { 
      results.insert(&buff[i * colsize]); 
     } 
    } 
    delete[] buff; 
    return results; 

}