OCCI next() 和 setDataBuffer() 访问冲突

Posted

技术标签:

【中文标题】OCCI next() 和 setDataBuffer() 访问冲突【英文标题】:Access Violation with OCCI next() and setDataBuffer() 【发布时间】:2020-01-14 09:34:47 【问题描述】:

很遗憾,我只见树木不见森林,需要帮助。我通过一个 SELECT 语句调用一个结果集,它有 70 列。我为所有 70 个字符列初始化缓冲区,并使用 setDataBuffer 设置它们。不幸的是,我只能检索 15-17 条记录。之后,我收到一条访问冲突错误消息。如果我尝试 next(1000) 它根本不起作用。我认为这与指针有关,但我没有看到错误。有谁知道我做错了什么?

            #pragma region Arrays
            char*** data_array  = new char**[70];
            for (unsigned int i = 0; i < 70; ++i)
            
                data_array[i] = new char*[1000];
                for (unsigned int j = 0; j < 1000; ++j)
                
                    data_array[i][j] = new char[500];
                
            

            ub2**   size_array  = new ub2 * [70];
            for (unsigned int i = 0; i < 70; ++i)
            
                size_array[i] = new ub2[1000];
            

            sb2**   ind_array   = new sb2 * [70];
            for (unsigned int i = 0; i < 70; ++i)
            
                ind_array[i] = new sb2[1000];
            

            ub2**   rc_array    = new ub2 * [70];
            for (unsigned int i = 0; i < 70; ++i)
            
                rc_array[i] = new ub2[1000];
            
            #pragma endregion

            #pragma region setDataBuffer
            for (unsigned int i = 0; i < 70; ++i)
            
                resultSet->setDataBuffer(i + 1, data_array[i][0], OCCI_SQLT_STR, 500, size_array[i], ind_array[i], rc_array[i]);
            
            #pragma endregion

            try
            
                ResultSet::Status resultSetStatus = resultSet->next(25);
                if (resultSetStatus == ResultSet::Status::DATA_AVAILABLE)
                
                    unsigned int rowCount = resultSet->getNumArrayRows();
                    for (unsigned int row = 0; row < rowCount; ++row)
                    
                        for (unsigned int column = 0; column < 70; ++column)
                        
                            auto value =  data_array[column][row];
                            auto vsize = *size_array[column];

                            std::string cellContent(value, vsize);
                        
                    
                
            
            catch(SQLException& sqlEx)
            
                std::string msg = sqlEx.getMessage();
                int i = 0;
            

【问题讨论】:

【参考方案1】:

问题在于您分配了data_array,因为您将其创建为jagged array,而不是setDataBuffer 所需的连续内存数组。

如果您想使用 new[] 进行动态分配,我建议改为:

using data_type = int8_t[1000][500];
auto data_array = new data_type[70];

那么data_array 的每个元素将是一个连续的内存区域,1000 * 500 大字节。


如果您想知道数组数组(如我的解决方案)和指向指针的指针(锯齿状数组)之间的区别,请参见例如this old answer of mine.

【讨论】:

以上是关于OCCI next() 和 setDataBuffer() 访问冲突的主要内容,如果未能解决你的问题,请参考以下文章

JDBC 明显快于 OCCI。我应该感到惊讶吗?

OCCI的迭代修改

OCCI开发环境搭建(Ubuntu)

使用 Oracle OCCI 回滚事务

使用 OCCI oracle 在 C++ 中执行 PL/SQL 脚本

Red Hat Enterprise Linux AS4, C++ OCCI connect Oracle 9i