I've got a solution currently working, and I'm working on a more elegant solution (based off your ideas in the Description), but I honestly don't know which would be the preferred method of doing things.
My currently working solution was to just patch Zend_Db_Statement_Oracle. This seemed "right" because Oracle is the only RDBMS that uses REF CURSORS in this manner (to my limited knowledge). I added a new protected variable:
/**
* Cursor pointer.
*/
protected $_cursor;
Then I modified _bindParam() to create and bind a cursor when one is passed in:
if ($type === OCI_B_CURSOR) {
$variable = oci_new_cursor($this->_adapter->getConnection());
$this->_cursor = $variable;
}
Then I modified _execute() to look for and execute on $this->_cursor, in addition to $this->_stmt if a cursor was passed to _bindParam():
if (isset($this->_cursor)) {
@oci_execute($this->_cursor, $this->_adapter->_getExecuteMode());
}
At this point I just added a new method, fetchCursor() to see if what I had done was working, rather than modify fetch(), fetchAll(), fetchColumn() and fetchObject() to check for an active cursor pointer. This function is basically a mirror of fetch() with all occurences of $this->_stmt replaced with $this->_cursor.
At the same time, this solution doesn't feel right because Zend_Db has sought to mirror the PDOStatement API and adding the fetchCursor() function effectively breaks that.
This would be a very useful, I would almost say necessary, feature for anyone using Oracle in any kind of enterprise environment. I'm hoping to inter-operate with an ERP system which has pushed all of its business logic down into PL/SQL procedures/functions/packages, most of which return a cursor.
In an attempt to not have to scrap all of the Zend Framework code already in place (dealing with the previous non-PL/SQL ERP) I'm looking to extend Zend_Db in the manner described here (Zend_Db_Cursor_Oracle).