snippetMinor
How to set the sequence to the last used id for all tables in Oracle?
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
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:
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
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:
The script could look like this:
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.
- 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.