private bool ReadInternal() { if (_endOfData) { return(false); } int rc; int columnCount = _columnInfo.Length; int i; // Define each of the column buffers to Oracle, but only if it hasn't // been defined before. if (null == _buffer) { int templen = (_rowsToPrefetch > 1) ? _rowBufferLength : 0; // Only tell oracle about the buffer length if we intend to fetch more rows NativeBuffer buffer = new NativeBuffer_RowBuffer(_rowBufferLength); buffer.NumberOfRows = _rowsToPrefetch; for (i = 0; i < columnCount; ++i) { _columnInfo[i].Bind(_statementHandle, buffer, ErrorHandle, templen); } _buffer = buffer; } // If we still have more data in the buffers we've pre-fetched, then // we'll use it; we don't want to go to the server more than we absolutely // have to. if (_buffer.MoveNext()) { return(true); } // If we've read the last buffer, and we've exhausted it, then we're // really at the end of the data. if (_isLastBuffer) { _endOfData = true; return(false); } // Reset the buffer back to the beginning. _buffer.MoveFirst(); // For LONG and LOB data, we have to do work to prepare for each row (that's // why we don't prefetch rows that have these data types) if (1 == _rowsToPrefetch) { for (i = 0; i < columnCount; ++i) { _columnInfo[i].Rebind(_connection); } } // Now fetch the rows required. Debug.Assert(0 < _rowsToPrefetch, "fetching 0 rows will cancel the cursor"); rc = TracedNativeMethods.OCIStmtFetch( _statementHandle, // stmtp ErrorHandle, // errhp _rowsToPrefetch, // crows OCI.FETCH.OCI_FETCH_NEXT, // orientation OCI.MODE.OCI_DEFAULT // mode ); // Keep track of how many rows we actually fetched so far. int previousRowsTotal = _rowsTotal; _statementHandle.GetAttribute(OCI.ATTR.OCI_ATTR_ROW_COUNT, out _rowsTotal, ErrorHandle); if (0 == rc) { return(true); } if ((int)OCI.RETURNCODE.OCI_SUCCESS_WITH_INFO == rc) { _connection.CheckError(ErrorHandle, rc); return(true); } if ((int)OCI.RETURNCODE.OCI_NO_DATA == rc) { int rowsFetched = _rowsTotal - previousRowsTotal; if (0 == rowsFetched) { if (0 == _rowsTotal) { _hasRows = x_hasRows_False; } _endOfData = true; return(false); } _buffer.NumberOfRows = rowsFetched; _isLastBuffer = true; return(true); } _endOfData = true; _connection.CheckError(ErrorHandle, rc); return(false); }