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 found, something is wrong. Inform and use the alternative getNameForObject() method
$seqname = $this->getNameForObject($table, 'id', 'seq');
}
$this->mdb->execute("DROP SEQUENCE $seqname");
$this->mdb->execute("CREATE SEQUENCE $seqname START WITH $value INCREMENT BY 1 NOMAXVALUE CACHE $this->sequence_cache_size");
INSERT
should do the needed to use the correct sequence value. Do you have triggers already ? If no, the above should be best solution for you. You're asking US if the sequence is imported ? Well, do YOU import it ?