The below insert statement is not working saying:unique primary key violated ora-0001. Do you know why it is not working ?
primary key is the seq id
INSERT INTO VITA_TRANSACTION ( VTR_SEQ_ID,VTR_QUELLE_SEQ_ID,VTR_QUELLE,
VTR_PROVIS_EXPORT_LOG_ID,VTR_DWH_EXPORT_LOG_ID,VTR_SYS_DATE,
VTR_PROCESSSTATE,VTR_IMEI_NR,VTR_IMEI_ZUORDNUNG,VTR_ZUORDNUNG_DATE,
VTR_IMEI_KNZ,VTR_SUBSCRIBER_NO,VTR_INSERT_TYPE,VTR_ERFASSUNG_DATUM,
VTR_VOID_ACTIVATE,VTR_QUELLSYSTEM,VTR_VORGANG,VTR_STORNO,VTR_SALES_PRICE,
VTR_ARTICLE_NO)
values (SEQ_VITA_TRANSACTION.nextval,418912,'M-ABVK',null,null,sysdate,
'UM','352523003062648','352523003062648',
to_date('20160118194708', 'YYYYMMDDhh24miss'),null,32927785,'AK',
to_date('20160118000000', 'YYYYMMDDhh24miss'),'60000661','Activate',
'Act','N',2000,'123123')
PK violation means that your table already contains the id that your sequence is creating. Try check the value of SEQ_VITA_TRANSACTION.nextval and the max(VTR_SEQ_ID) from VITA_TRANSACTION:
select 'seq', SEQ_VITA_TRANSACTION.nextval from dual
union all
select 'tab', max(VTR_SEQ_ID) from VITA_TRANSACTION
This may not the exact answer to your question but I am trying to debug your problem.
ORA-0000
1: unique constraint (string.string) violated
Cause: An UPDATE or INSERT statement attempted to insert a duplicate key. For Trusted Oracle configured in DBMS MAC mode, you may see this message if a duplicate entry exists at a different level.
So duplicate entry already exists in VITA_TRANSACTION table.
First you should retrieve the current value of the sequence without increment it
Sample
SELECT last_number
FROM all_sequences
WHERE sequence_owner = '<sequence owner>'
AND sequence_name = '<sequence_name>';
For detail follow this question How to retrieve the current value of an oracle sequence without increment it?
Then do a search in the VITA_TRANSACTION where VTR_SEQ_ID= retrieved current value + 1
I am quite sure you will get one row.Now to avoid this error you can increment your sequence value by executing the below sql.
select SEQ_VITA_TRANSACTION.nextval from dual;
It will increment the value of your current sequence by 1(if your sequence INCREMENT BY 1) . Then try to again execute your insert query.
Primary Key violation usually occurs if you are inserting already exist values in the table. So you can check the records on the table VITA_TRANSACTION for the next sequence i.e SEQ_VITA_TRANSACTION.nextval, you can use following query:
Select
count(*)
From **VITA_TRANSACTION**
where
VTR_SEQ_ID = **SEQ_VITA_TRANSACTION.nextval**;
If the above query returns count as 1 then there is already a record for that sequence. Then try by increasing the sequence value or you can delete the record. It's your call.
Hope this answers your question.
Related
My application can occur to insert duplicate primary key data, my doubt is what would be the most performative way, check before inserting if the key already exists or simply insert and let the bank return an error and then treat it? Which has less impact?
I thank
The most performant method would be to use an INSERT query with a ON DUPLICATE KEY UPDATE clause.
This will insert a new record if the primary key doesn't exist and will update only the specified fields for the primary key record if it already exists (it will not throw an error).
For example the following code will create a new user if the the user_id doesn't exist. If the user_id does exist, it will only update the last_visited_date.
INSERT INTO users
(user_id, last_visited_date)
VALUES
({user_id}, UTC_TIMESTAMP())
ON DUPLICATE KEY UPDATE
last_visited_date= VALUES(last_visited_date)
This approach allows you to both create new records and update already existing records with one query, which prevents the need for checking for an already existing primary key.
Note: if the primary key is an auto-incremented index, MySQL treats ON DUPLICATE UPDATE clauses the same as INSERT queries so the next ID will be incremented by 1 anytime the primary key already exists.
If you don't want to use an ON DUPLICATE KEY UPDATE clause, catching the error for already existing primary keys would be the most performant.
so I created a table with a column which I declared EmployeeID as a primary key int with auto increment, but here is the problem:
If I delete a row and then insert a new one the new increment will still count
For example:
ID Name
1 jayden
2 karen
delete karen ...
ID Name
1 jayden
insert new one
ID Name
1 jayden
3 nicolas
So it basically skips the previous ID.
This is not a mistake, it is how MySQL works with auto_increment. It stores the last value which it gave at the insertion and increments it. You can always get the last ID at your next insertion
insert into yourtable(id, Name)
select id + 1, 'foo'
from yourtable
where id = (select max(id) from yourtable);
That's because an auto increment is a independent property of your table, that is only used when assigning new IDs and does not depend on the last existent ID on your table. This is how many relational databases, not only MySQL, were designed for.
To achieve what you want (which seems to be having IDs in sequence without "holes") you would need to query the last ID and increment on it to be set manually.
Ex:
SELECT id from Users ORDER BY id DESC LIMIT 1
Or instead setting the auto_increment of your table according to your last id.
Be aware that both of this is not performatically wise. You should really stick to the auto increment default behavior, since it's optimal, unless you have some strong reason for not doing things as they were designed to be done.
This is expected behavior from the 'delete' command
What would you ever want/need an Unique Identifier that can be reaffected to someone else?
The 'Truncate' command will delete all your data and reset the ID, maybe this is what you are looking for
After delete a row use this query,
ALTER TABLE tbl_name AUTO_INCREMENT = ID;
Actually this is how MySQL works and it's not a mistake
I have 2 tables user and userinfo. userinfo table contains user_id(id of user table) column which has UNIQUE constraint.
now i have 2users(primaryUser and secondaryUser) which has records in user and userInfo tables.
The primaryInfo object contains primaryUserId and secondaryInfo object contains secondaryUserId
I want to swap the userinfo data of primaryUser to secondaryUser and viceversa. I am doing like this
primaryInfo.setUserId(secondaryUser.getId());
secondaryInfo.setUserId(primaryUser.getId());
session.update(primaryInfo);
session.update(secondaryInfo);
but when commiting the transaction it is giving error like
ERROR org.hibernate.engine.jdbc.spi.SqlExceptionHelper:147 ERROR: duplicate key value violates unique constraint "user_infos_unique_user"
Detail: Key (ui_user_id)=(52560087) already exists.
can you please tell how to do this.. Thanks
You can use the DEFERRABLE and INITIALLY DEFERRED properties on the constraint and update both records in a single transaction. DEFERRED means the constraint will not be evaluated until the transaction is commited -- at which time it should be valid again.
However: I have not figured out how to use Hibernate annotations to specify the DEFERRED properties, so you will have to use LiquiBase to maintain the database schema (not a bad idea anyway.) (Or use "raw" SQL which is not so good an idea.)
See this question for more about the annotations (alas I cannot use LiquiBase on the project I ask about there.)
For Oracle database you can create next unique constraint with special attributes 'DEFERRABLE INITIALLY DEFERRED':
ALTER TABLE table_name ADD CONSTRAINT constraint_name UNIQUE (table_field) DEFERRABLE INITIALLY DEFERRED
A possible trick to work around the unique constraint is to do 3 updates:
update row A with a value for the column that no other row can use. NULL may be used if not forbidden by a not-NULL constraint, otherwise 0 if not forbidden and assuming it's an integer, otherwise a negative value.
then update row B with its final value (the previous value from row A)
then update row A with its real final value (the previous value from row B)
As error Shows:
there is a unique constraint on userInfo table. that means user must be unique. So If you wnat to swipe the two user Id. you have to perform following steps
1. Remove the constraint
2. Swap two id's(same code as you currently have)
3. Add Constaint.
I have an table (in ORADB) containing two columns: VARCHAR unique key and NUMBER unique key generated from an sequence.
I need my Java code to constantly (and in parallel) add records to this column whenever a new VARCHAR key it gets, returning the newly generated NUMBER key. Or returns the existing NUMBER key when it gets an existing VARCHAR (it doesn't insert it then, that would throw an exception of course due to the uniq key violation).
Such procedure would be executed from many (Java) clients working in parallel.
Hope my English is understandable :)
What is the best (maybe using PL/SQL block instead of Java code...) way to do it?
I do not think you can do better than
SELECT the_number FROM the_table where the_key = :key
if found, return it
if not found, INSERT INTO the_table SELECT :key, the_seq.NEXT_VAL RETURNING the_number INTO :number and COMMIT
this could raise a ORA-00001(duplicate primary key insert)
if the timing is unlucky. In this case, SELECT again.
Not sure if JDBC supports RETURNING, so you might need to wrap it into a stored procedure (also saves database roundtrips).
You can use an index-organized table (with the_key as primary key), makes the lookup faster.
I've written this java servlet which inserts items into a table however it fails. I think it might be due to my insertion and deleting which got me in trouble some how. The java servlet runs an insert statement into sql server. In my error log, it says:
com.microsoft.sqlserver.jdbc.sqlserverexception: cannot insert duplicate key row in object 'dbo.timitem' with unique index 'XAK1timitem'.
any ideas?
UPDATE: i found there is an index called "XAK1timItem (Unique, Non-Clustered)" which I'm not really sure what to do with.. hope this helps the question.
The unique index will enforce uniqueness for the combination of the rows included in the index. So if you have a row in the database which has, for the indexed column, values equal to those you are trying to insert, you will get an error back from the database.
The AK part indicates that this is an alternative key which probably means that the table has a regular primary key, and does not need to rely on the AK for unique identification of a row.
Some options:
drop the index if not needed
add another column to the unique index
make the index not unique, so that it allows duplicate values
check if there is already a row that matches the one you are about to
insert and abort the insert, but I guess you don't want to do this