Part of the EllisLab Network
   
 
Oracle Nextval issue
Posted: 02 April 2009 05:42 PM   [ Ignore ]  
Summer Student
Total Posts:  8
Joined  04-02-2009

I’ve got an interesting issue going on here when grabbing the nextval from a sequence in Oracle.  The problem is that the nextval increments by 3 each time, not 1.  The increment parameter is set to 1 in Oracle, and if I do the same select from the command line, it returns the nextval incremented by only 1.  So, my question is, why and/or how is this being incremented by 3 when I run the query through CI?

$sql "select testlog.schedule_seq.nextval from dual";
$query $this->db->query($sql);
$row $query->row();
echo 
$row->NEXTVAL
Profile
 
 
Posted: 02 April 2009 06:22 PM   [ Ignore ]   [ # 1 ]  
Lab Technician
Avatar
RankRankRankRank
Total Posts:  2126
Joined  06-04-2008

Howdi, and welcome to the CI forums.

I know next to nothing about Oracle, but I’m assuming that nextval is meant to return one row?

It might be worth doing a num_rows() call in there, before you access the row, to make sure that you did in fact only get one row.  $query->row() of course will work fine with multi-row results, it’ll just blissfully return the first row only.

Profile
 
 
Posted: 02 April 2009 06:31 PM   [ Ignore ]   [ # 2 ]  
Summer Student
Total Posts:  8
Joined  04-02-2009

It’s only returning one row.  That nextval query in Oracle is the equivalent of an auto_increment field in MySQL (since Oracle doesn’t have an auto_increment feature confused ).  Somehow this query is being run 3 times.  It’s not inside any kind of loop or anything either.

Profile
 
 
Posted: 02 April 2009 06:42 PM   [ Ignore ]   [ # 3 ]  
Lab Technician
Avatar
RankRankRankRank
Total Posts:  2126
Joined  06-04-2008

Okay, the next thing I’d try (because it’s easy) is to turn on the Profiling Library - which will report, on your browser, the exact database calls being made.  This should give you a pointer as to whether it’s a weirdness with the Oracle/CI interaction (we don’t get many Oracle users around these ‘ere parts) or at the other end.  I’m guessing you can crank up some Oracle profiling tools to see if it’s getting the same request three times?

Profile
 
 
Posted: 02 April 2009 07:44 PM   [ Ignore ]   [ # 4 ]  
Summer Student
Total Posts:  8
Joined  04-02-2009

Does it need to be placed anywhere special within the controller?  I’m not getting any output…

function index() {
    
        $this
->output->enable_profiler(TRUE);
        
$data['title'"Scheduler";
        
$data['query'$this->approve_model->getDetails();
        
$data['table'$this->approve_model->getPendingTable($data['query']);
        
$this->load->view('approve_view',$data);
    
Profile
 
 
Posted: 02 April 2009 07:56 PM   [ Ignore ]   [ # 5 ]  
Lab Technician
Avatar
RankRankRankRank
Total Posts:  2126
Joined  06-04-2008

No, anywhere should be okay.  I normally put it in my constructor, just so I can easily comment / de-comment it during development.

Do you mean you get no output at all or just no profiler output - should be trailing at the end of your web page - there’s quite a bit of it, so it’s hard to miss I guess.

Profile
 
 
Posted: 02 April 2009 08:27 PM   [ Ignore ]   [ # 6 ]  
Summer Student
Total Posts:  8
Joined  04-02-2009

Sorry, I should’ve been a little more specific.  No profiler output.  There is output on the page though. 

I’ll see if I can fire up something from the Oracle side tomorrow when I’m back at work to see how many queries are coming in. 

I’m intrigued by this profiler though so I’d like to get it displaying properly if possible.

Profile
 
 
Posted: 02 April 2009 08:37 PM   [ Ignore ]   [ # 7 ]  
Summer Student
Total Posts:  8
Joined  04-02-2009

Disregard.  I got the profiler working.  It’s only running one “nextval” query so I’ll check things out from the Oracle side tomorrow.

Profile
 
 
Posted: 03 April 2009 12:27 AM   [ Ignore ]   [ # 8 ]  
Summer Student
Total Posts:  8
Joined  04-02-2009

Ok, I’d say this is definitely some sort of bug within CI.  On the Oracle side, the query shows up like this:

select testlog.schedule_seq.nextval from dualselect testlog.schedule_seq.nextval from dualselect testlog.schedule_seq.nextval from dual 

I wrote my own connection/query using the base oci php functions and the number only increments by 1 each time.

Profile
 
 
Posted: 03 April 2009 06:41 AM   [ Ignore ]   [ # 9 ]  
Lab Technician
Avatar
RankRankRankRank
Total Posts:  2126
Joined  06-04-2008

Well .. it’s time to file that bug report.  As I mentioned, we don’t see a lot of Oracle users, and I guess the same goes for the EL guys.

You could try running the query twice - it’d be fascinating it you got a result of 4 incs rather than 6.  smile  (I’m having a Joseph Heller flashback now.)

And you have stuck an echo “BOB SAYS HI” or similar in there, to really be sure that that code block only gets hit the once, right?

Profile
 
 
Posted: 03 April 2009 10:32 AM   [ Ignore ]   [ # 10 ]  
Summer Student
Total Posts:  8
Joined  04-02-2009

So this morning I was playing around and somehow it started incrementing by 4 instead of 3.  It’s back to 3 now and I’m not sure if I did anything to cause it to jump to 4, but…kinda creepy.

Here’s the test code I’ve been using:

echo "Before!<br>";
$sql 'select testlog.schedule_seq.nextval from dual';
echo 
$sql."<br>";
$query $this->db->query($sql);
echo 
"After!<br>";
$row $query->row();
echo 
"nextval: ".$row->NEXTVAL."<br>"

And the output:

Before!
select testlog.schedule_seq.nextval from dual
After
!
nextval169 

And then a refresh of the page:

Before!
select testlog.schedule_seq.nextval from dual
After
!
nextval172 

Here’s the php/oci8 code I used:

$conn oci_connect('xxxxx''xxxxx''//xxx.xxx.xxx.xxx/xxx');
$query 'select testlog.schedule_seq.nextval from dual';

$stid oci_parse($conn$query);
$r oci_execute($stidOCI_DEFAULT);

while (
$row oci_fetch_row($stid)) {
  
foreach($row as $item{
      
echo $item."<br>";
  
}
}

oci_close
($conn); 

which returns this:

177 

and after a refresh, this:

178 
Profile
 
 
Posted: 15 October 2009 11:52 AM   [ Ignore ]   [ # 11 ]  
Summer Student
Total Posts:  3
Joined  10-15-2009

I’m new to CodeIgniter and I am testing it out. At my work, we only use Oracle for DB backend. I too had this issue with oracle sequences, so I modified the insert statement in the oci8_driver.php file to handle nextval. (As far as I know, only the insert statement would have the need to access a sequence.)  tongue rolleye

/**
     * Insert statement
     *
     * Generates a platform-specific insert string from the supplied data
     *
     * @access  public
     * @param   string  the table name
     * @param   array   the insert keys
     * @param   array   the insert values
     * @return  string
     */
    
function _insert($table$keys$values)
    
{
        
//Messy fix for inserting sequences
        
$seq FALSE;
        foreach(
$values as $insertKey)
        
{
            
if (substr_count(strtoupper($insertKey), "NEXTVAL") > 0)
            
{
                $seq 
TRUE;
            
}
        }
        
        
if ($seq)
        
{
            $sqlnextval
="";
            foreach(
$values as $insertKey)
            
{
                
if (strlen($insertKey) > 8)
                
{
                    
if (strtoupper(substr($insertKey,-8,7))=="NEXTVAL")
                    
{
                        $nextval 
str_replace("'""",$insertKey);
                        
$sqlnextval="$sqlnextval,$nextval";
                    
}else{
                        $sqlnextval
="$sqlnextval,$insertKey";
                    
}
                }
            }
            $sqlnextval 
substr($sqlnextval,1,strlen($sqlnextval));
            return 
"INSERT INTO ".$table." (".implode(', '$keys).") VALUES ($sqlnextval)";
        
}else{
            
return "INSERT INTO ".$table." (".implode(', '$keys).") VALUES (".implode(', '$values).")";
        
}
    } 

I’m new to php so I thought to post this code to see if it can be cleaned up. I originally come from a Java/WebLogic/Oracle background.

Profile
 
 
Posted: 20 October 2009 06:02 PM   [ Ignore ]   [ # 12 ]  
Summer Student
Total Posts:  2
Joined  10-20-2009

I was having the same problem—calling something like:

$q $this->db->query('SELECT somesequence.NEXTVAL FROM dual');
$result $q->row();          // Increments three times
$result $q->result();       // Increments three times
$result $q->row_array();    // Increments two times
$result $q->result_array(); // Increments two times 

Looking deeper, I found that the function num_rows() in CI_DB_oci8_result (oci8_result.php) is calling ociexecute.  This seems to be what’s causing the extra DB queries that leads to the sequence getting incremented more than it should.

To remedy this, I altered the function to read as:

function num_rows()
{
    
if ( $this->num_rows )      return $this->num_rows;
    if ( 
$this->result_array )  return count($this->result_array);
        
    return 
count($this->result_array());
    ...

In addition to that, I had to overwrite CI_DB_result’s result_object() and row_object() functions for the oci8 driver.

This probably won’t cover all the use cases, but it seems to be working for my application.

Profile
 
 
Posted: 07 March 2010 07:20 PM   [ Ignore ]   [ # 13 ]  
Summer Student
Total Posts:  1
Joined  03-05-2010

Sorry to bump a 6 month old thread, but I am experiencing the same thing, increments by 3.

I did not see anything in the bug tracker for this. 
Does anyone have a complete fix for this? derp alteration of the function didnt work for me, and didnt list what else he did to fix it.

Profile
 
 
Posted: 30 October 2011 07:07 PM   [ Ignore ]   [ # 14 ]  
Summer Student
Total Posts:  1
Joined  10-30-2011

I think its must be bug , we should need to throw it in dustbin, that’s just waste of time !

Profile