Welcome Guest, Not a member yet? Register   Sign In
Read an ORACLE cursor. How?
#3

[eluser]duartix[/eluser]
Well, yesterday I managed to build a proof of concept, and I'm very happy to say that with very little OO programming, I managed to solve the problem and I spent the rest of the day moving all my SELECTS from the models to Stored Procedures in the DB that return cursors.

Since this can help someone else, Smile I'm publishing it here in condensed form.

Here's what I had to do. First thing I needed, was to create a subclass that extends CI's CI_Model (the code is stripped of exception handling for size and clarity) :

Code:
<?php

/**
* This class extends CI_Model to allow it to read ORACLE cursors
* from STORED PROCEDURES in the DB
*/

class OracleModel extends CI_Model {

    public function __construct() {
        parent::__construct();
    }
    
    public Function readCursor($storedProcedure, $binds) {

        //
        // This function needs two parameters:
        //
        // $storedProcedure - the name of the stored procedure to call a chamar. Ex:
        //  my_schema.my_package.my_proc(:param)
        //  
        // $binds - receives an array of associative arrays with: parameter names,
        // values and sizes
        //
        // WARNING: The first parameter must be consistent with the second one
        
            $conn = oci_connect('scott', 'tiger', '(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP ........');

            if ($conn) {
                
                // Create the statement and bind the variables (parameter, value, size)
                $stid = oci_parse($conn, 'begin :cursor := ' . $storedProcedure . '; end;');
                foreach ($binds as $variable)
                    oci_bind_by_name($stid, $variable["parameter"], $variable["value"], $variable["size"]);

                // Create the cursor and bind it
                $p_cursor = oci_new_cursor($conn);
                oci_bind_by_name($stid, ':cursor', $p_cursor, -1, OCI_B_CURSOR);

                // Execute the Statement and fetch the data
                oci_execute($stid);
                oci_execute($p_cursor, OCI_DEFAULT);
                oci_fetch_all($p_cursor, $data, null, null, OCI_FETCHSTATEMENT_BY_ROW);
                
                // Return the data
                return $data;
            }
      }
}
?>

Then your models will now look like this:

Code:
<?php
class myModel extends OracleModel {

    public function __construct() {
        parent::__construct();
        $this->load->database();
    }

    public function getData($param1, $param2) {
        try {
            $variables[0] = array("parameter" => "p1", "value" => $param1, "size" => 100);
            $variables[1] = array("parameter" => "p2", "value" => $param2, "size" => 100);
            return $this->readCursor("myschema.mypackage.getData(:p1, :p2)", $variables);
        }
    }
}
?>

Finally, your ORACLE DB will have a package with a function that returns a cursor with the data (I'll put just the body):

Code:
CREATE OR REPLACE PACKAGE BODY myschema.mypackage
IS

   FUNCTION getData (p1 in varchar2, p2 in varchar2)
      RETURN SYS_REFCURSOR
   AS
      theCursor   SYS_REFCURSOR;
   BEGIN
         OPEN theCursor FOR
              SELECT   *
                FROM   myTable t
               WHERE  t.id1 = p1 AND t.id2 = p2;

      RETURN theCursor;
   END getData;

END mypackage;


Messages In This Thread
Read an ORACLE cursor. How? - by El Forum - 10-28-2013, 05:19 AM
Read an ORACLE cursor. How? - by El Forum - 10-31-2013, 04:23 AM
Read an ORACLE cursor. How? - by El Forum - 11-07-2013, 05:39 AM



Theme © iAndrew 2016 - Forum software by © MyBB