HiveBrain v1.2.0
Get Started
← Back to all entries
snippetMinor

How to set the sequence to the last used id for all tables in Oracle?

Submitted by: @import:stackexchange-dba··
0
Viewed 0 times
lastthetablesallusedsequenceforhoworacleset

Problem

I'm working on an open source elearning system called Moodle which usually uses MySql or Postgresql, but can also use MSSQL and Oracle.

A client wishes to use Oracle, which I have limited experience of. I've got a local install of Oracle 11g r2.

I used a script to transfer data from MySql into Oracle, including the ID to keep the references.

But now when creating a record I get the error message : ORA-00001: unique constraint (SCHEMANAME.TABLENAME_ID_PK) violated

I'm guessing the sequences weren't updated when I inserted the ID's?

Is there an easy way to update all the table sequences to the last ID number used + 1 in each table?

Unless it's something else?

UPDATE : I can use this to get the last number in the sequence

SELECT sequence_name, last_number
FROM dba_sequences
WHERE sequence_owner = 'SCHEMA_NAME'
AND sequence_name LIKE 'V_%'


The last_number column has values but it looks like they are lower than the last id used in the table.

UPDATE 2: Found some existing code in Moodle that resets the sequence, I had wrongly assumed the naming convention for the sequences was created by Oracle but its Moodle. Here is some Moodle/PHP code that will reset all the sequences:

$todb = moodle_database::get_driver_instance($dbtype, $dblibrary);
$todb->connect($dbhost, $dbuser, $dbpass, $dbname, $prefix, $dboptions);
$totables = $todb->get_tables(false);
$tomgr = $todb->get_manager();

foreach ($totables as $table) {
    mtrace($table);
    try {
        $tomgr->reset_sequence($table);
    } catch (moodle_exception $e) {
        // There are a couple of temporary tables without indexes.
        mtrace($e->getMessage());
        continue;
    }
}


UPDATE 3 : This is basically what the reset sequence function does

```
$value = (int)$this->mdb->get_field_sql('SELECT MAX(id) FROM {'.$tablename.'}');
$value++;

// Calculate a sequence name from the tablename.
$seqname = $this->getSequenceFromDB($xmldb_table);
if (!$seqname) {
// Fallback, seqname not

Solution

First you have to find out what the current sequence value is and then reset it. I would write a script which does the following tasks:

  • Get the max value from the table



  • update/recreate the sequence



The script could look like this:

declare
  maxval number;
begin
  select max(id) into maxval from ;
  execute immediate 'ALTER SEQUENCE  START WITH '|| maxval+1 ||';';

  select max(id) into maxval from ;
  execute immediate 'ALTER SEQUENCE  START WITH '|| maxval+1 ||';';
end;
/


I'm pretty sure there are better scripts but if you have to do this task frequently this might do the job without much development time.

Code Snippets

declare
  maxval number;
begin
  select max(id) into maxval from <table_1>;
  execute immediate 'ALTER SEQUENCE <sequence_name_1> START WITH '|| maxval+1 ||';';

  select max(id) into maxval from <table_2>;
  execute immediate 'ALTER SEQUENCE <sequence_name_2> START WITH '|| maxval+1 ||';';
end;
/

Context

StackExchange Database Administrators Q#87164, answer score: 3

Revisions (0)

No revisions yet.