ORACLE APEX / SQL DEVELOPER: Cannot get PK to autoincrement - oracle

I am trying to implement my SQLDeveloper DB into Oracle APEX. I cannot figure out how to get the PK's in my table to auto-increment starting from a certain value (i.e. 400001). I have tried making triggers and sequences but when I try to add a row using a form in APEX, my PK increments from 40 for some reason.
Here is my APEX form outcome
enter image description here
Here is how it inserts into SQL Developer
enter image description here
Basically, can someone describe to me how I can edit the existing trigger, or create a sequence, that would make application_id of a new entry auto-increment by 1.
Thanks!

Find max application_id:
select max(application_id) From your_Table;
Suppose it is 400010 (as screenshot suggests). Now recreate the sequence (presuming its name is seq_app):
drop sequence seq_app;
create sequence seq_app start with 400011 increment by 1 nocache;
Trigger is most probably OK, as you see values being inserted into the table.
Side note: sequences will be unique, but not necessarily gapless. CACHE (or NOCACHE) might affect that, but - for performance sake, you'd rather let Oracle cache sequence numbers (default is 20) which means that - if you don't use some of those cached numbers, they will be lost. I wouldn't worry, if I were you.

Related

How to generate table scripts with data in Toad for Oracle - 9.7.2

I wanna create a script for table that should include
Create Table statement
Data in the table
Sequence in the table(Only sequence code)
And Trigger associated to it
I have added Sequence and trigger for auto increment ID, I searched but I couldn't get enough answers for Sequence in trigger.
I understand you, partially.
In order to get CREATE TABLE statement, choose that table and on right-hand side of the screen navigate to the "Script" tab - there it is. Apart from CREATE TABLE, it contains some more statements (such as ALTER TABLE in order to add constraints, CREATE INDEX and your number 4 - CREATE TRIGGER).
As of the sequence: it is a separate object, which is not related to any table. One sequence can be used to provide unique numbers for many tables, so - I'm not sure what is it that you are looking for.
In order to get data from that table, right-click table name; in menu choose "Export data" >> "Insert statements". That'll create bunch of INSERT INTO commands. That's OK if table is small; for large ones, you'll get old before it finishes.
The last sentence leads to another suggestion: why would you want to do it that way? A proper option is to export that table, using either Data Pump or the Original EXP utility.
[EDIT]
After you insert data "as is" (i.e. no changes in ID column values), disable trigger and run additional update. If we suppose that sequence name is MY_SEQ (create it the way you want it, specifying its start value etc.), it would be as simple as
update your_table set id = my_seq.nextval;
Once it is done, enable the trigger so that it fires for newly added rows.

Oracle 12c - refreshing the data in my tables based on the data from warehouse tables

I need to update the some tables in my application from some other warehouse tables which would be updating weekly or biweekly. I should update my tables based on those. And these are having foreign keys in another tables. So I cannot just truncate the table and reinsert the whole data every time. So I have to take the delta and update accordingly based on few primary key columns which doesn't change. Need some inputs on how to implement this approach.
My approach:
Check the last updated time of those tables, views.
If it is most recent then compare each row based on the primary key in my table and warehouse table.
update each column if it is different.
Do nothing if there is no change in columns.
insert if there is a new record.
My Question:
How do I implement this? Writing a PL/SQL code is it a good and efficient way? as the expected number of records are around 800K.
Please provide any sample code or links.
I would go for Pl/Sql and bulk collect forall method. You can use minus in your cursor in order to reduce data size and calculating difference.
You can check this site for more information about bulk collect, forall and engines: http://www.oracle.com/technetwork/issue-archive/2012/12-sep/o52plsql-1709862.html
There are many parts to your question above and I will answer as best I can:
While it is possible to disable referencing foreign keys, truncate the table, repopulate the table with the updated data then reenable the foreign keys, given your requirements described above I don't believe truncating the table each time to be optimal
Yes, in principle PL/SQL is a good way to achieve what you are wanting to
achieve as this is too complex to deal with in native SQL and PL/SQL is an efficient alternative
Conceptually, the approach I would take is something like as follows:
Initial set up:
create a sequence called activity_seq
Add an "activity_id" column of type number to your source tables with a unique constraint
Add a trigger to the source table/s setting activity_id = activity_seq.nextval for each insert / update of a table row
create some kind of master table to hold the "last processed activity id" value
Then bi/weekly:
retrieve the value of "last processed activity id" from the master
table
select all rows in the source table/s having activity_id value > "last processed activity id" value
iterate through the selected source rows and update the target if a match is found based on whatever your match criterion is, or if
no match is found then insert a new row into the target (I assume
there is no delete as you do not mention it)
on completion, update the master table "last processed activity id" to the greatest value of activity_id for the source rows
processed in step 3 above.
(please note that, depending on your environment and the number of rows processed, the above process may need to be split and repeated over a number of transactions)
I hope this proves helpful

Number format not matching between Pentaho Kettle and Oracle?

I have a database table in Oracle 11g created and populated with the following code:
CREATE TABLE TEST_TABLE (CODE NUMBER(1,0));
INSERT INTO TEST_TABLE (CODE) VALUES (3);
Now, I want to use this table as a lockup table in a Pentaho Kettle transformation. I want to make sure that the value of a column comes from this table, and if not abort. I have the following setup:
The data frame has a single column called Test of type integer, and a single row. The lookup is configured like this:
However the lookup always fail and the transformation is aborted, no matter if the value of Test is 3 (should be ok), or 4 (should be aborted). However, if I check the "Load all data from table" box, it works as expected.
So my question is this: Why does it not work unless I cache the whole table?
Two further observations:
When it works, and the row is printed in log, I notice that Test is printed like [ 3] and From DB is printed like [3] (without the extra space). I don't know if this is of any significance, though.
If I change the database table so that CODE is created as INT, it works. This leads me to believe it is somehow related to the number formatting. (In my actual application, I can not change the database tables.) I guess I should change the format of Test, but to what? Setting it to Number does not help, nor does Number with length 1 and precision 0.

Oracle sequence generator within interval

I'm using oracle 11gr2 and for the product table when a new product is inserted I need to assign an autoincrement id going from 1 to 65535. Product could be then be deleted.
When I reach the 65535th, I need to scan the table to find a free hole for assigning new ID.
As I have this requirement oracle sequence could not be used, so I am using a function (tried also a trigger on insert) in order to generate a free id...
The problem is that I could not handle batch insert for example and I have concurrency problems...
How could I solve this ? By using some sort of external Id generator ?
Sounds like an arbitrary design. Is there a good reason for having a 16-bit max product id or for reusing IDs? Both constraints are bad practice.
I doubt any external generator is going to provide anything that Oracle doesn't already provide. I recommend using sequences for batch insert. The problem you have is how to recycle the IDs. Oracle plain sequences don't track the primary key, so you need a solution to find recycled keys first, then fallback to the sequence perhaps.
Product ID Recycling
Batch Inserts - Use sequence for keys the first time you load them. For this small range, set NOCACHE on the sequence to eliminate gaps.
Deletes - When a product is deleted, instead of actually deleting the row, set a DELETED = 'Y' flag on the row.
Inserts - Update the first record available with DELETED flag set, or either select the min ID from product table where DELETED = 'Y'. Update record with new product info (but same ID) and set DELETED = 'N'
This ensures you always recycle before you insert new sequence IDs
If you want to implement the logic in the database, you can create a view (VIEW$PRODUCTS) where DELETED = 'N' and an INSTEAD OF INSERT trigger to do the insert.
In any scenario, when you run out of sequences (or sequence wraps), you are out of luck for batch inserts. I'd reconsider that part of the design if I were you.

Oracle and auto_increment/identity

In modern versions of Oracle, is there some "standard" (stored procedure, additional CREATE syntax, etc.) way to setting up a table with auto_increment/identity style column, or are we still stuck manually creating the table, creating the sequence, and creating the trigger.
Update: I realize Oracle has no concept of an auto_increment. What I'm interested in is if any of the standard Oracle tools have automated away the creation of the sequence and trigger, or if the DBA is left to create the needed queries/commands to create the sequence and trigger themselves.
If you want a sequentially incrementing ordered values, then no, SEQUENCE is the only choice.
If you want just an identity, use SYS_GUID()
Oracle SQL Developer gives you an option to automatically create the "create or replace trigger" code that populates a table's primary key from a sequence. To do that, from the navigator tree, right-click on the table name > Trigger > Create (PK from Sequence). It does not create the sequence for you though.
You don't actually need a trigger, you can just reference the sequence's next value when you populate the new row into the table. You can even share a single sequence between multiple tables if you like.
Auto-increment? Nope, sorry. You're stuck with sequences (which are generally better anyway albeit slightly less convenient).
You can however use GUIDs. Oracle has a SYS_GUID() function you can use instead.

Resources