Oracle inserting into table with composite key - sql

I have a table, TBL_1, with the following fields:
TBL_ID NUMBER (pk),
CREATE_DATE DATE (pk),
TBL_IND VARCHAR2(1)
The primary key is on TBL_ID and CREATE_DATE, I am trying to perform an insert statement but getting an error ORA-00001: unique constraint (primary key) violated.
There is a before insert trigger setting the NEW.CREATE_DATE as SYSDATE. The insert statement looks like:
INSERT INTO TBL_1 (tbl_id,tbl_ind)
SELECT tbl_id,'Y'
FROM tbl_info;
The actual query is a little more complex but I just wanted to point out it is a INSERT INTO SELECT statement. Is it possible if there is a duplicate tbl_id the trigger used the same exact date for both rows thus causing a duplicate error? How can I avoid this?

I don't think it is a good idea to have create_date as part of the primary key. I would suggest that you use a sequence value instead.
If you don't mind reducing the number of rows, you can do:
INSERT INTO TBL_1 (tbl_id,tbl_ind)
SELECT DISTINCT tbl_id, 'Y'
FROM tbl_info;
Or, if you still want all rows inserted, then restructure your data to use a sequence instead of the creation date.

Related

Create primary key for table with period (Temporal Validity) in Oracle SQL

I have a question regarding to primary key for Oracle Table with Period.
I have created two tables like following:
create table el_temporal_try( -- Parent Table
id number(10) not null,
ColumnA varchar(10),
constraint el_temporal_try_pk primary key (id),
period for valid_period
);
create table el_temporal_try_son( -- Son Table
id number(10) not null,
ColumnA varchar(10),
parent_id number(10),
constraint el_temporal_try_FY foreign key (parent_id) references el_temporal_try(id),
period for valid_period
);
This script gone through successfully. However I have problem with inserting data:
I have executed following two insert statements into the parent table:
1st: statement
insert into el_temporal_try
(id, columnA,valid_period_start, valid_period_end)
values
(1,'A',sysdate - 10, sysdate - 9);
Result:
1 row inserted.
2nd: statement
insert into el_temporal_try
(id, columnA,valid_period_start, valid_period_end)
values
(1,'B',sysdate - 8, sysdate - 7);
Result
ORA-00001: unique constraint (PBSVW.EL_TEMPORAL_TRY_PK) violated
I understand it is because of the "ID" column. However, my issues because this two rows are for a different period, should it be allowed?
I was intended to use this period for feature to capture the change history of a record as an alternative to flashback. However, does it means that I should not use primary key at this situation?
Thanks in advance!
The problem is related to the id column like you said. it's not possible to add the registry because the primary key is unique, then your second insert statement references the same ID from the first. You need to change the ID always you insert a line.
On Oracle 12c, you can use the identity like this link.
https://www.oracletutorial.com/oracle-basics/oracle-identity-column/
in another version, you can use sequence and trigger to do this.
https://chartio.com/resources/tutorials/how-to-define-an-auto-increment-primary-key-in-oracle/
Thanks for everyone's help on this. This most likely means I cannot use Primary Key/Foreign Key to maintain the referential integrity between the parent and son for my situation within a particular timestamp, but I have to go for something else.
Thanks a lot!

inserting unique primary key exception

I was trying to insert records to a table using statement like
insert into table
(table_id, xxx,xxx)
values
(100,xxx,xxx)
and get the unique violation on the primary key.
and i did a select
select * from table where table_id = 100;
There is no record there.Thought insert before then, delete record.
And if i dont insert the table id, i got a null violation.
I was wondering if there is anyway to deal with this(maybe sequence)? I need to insert several thousands records using the inserting statement. some hundered have this prob.
Thanks in Advance!

Copy data from a table, into the same table with a different key

I was curious if it was possible to take data from a table, and duplicate it but assign a new primary key
for example, I wish to take data that has a column "question_id" which acts as the unique key for the table, and copy all of the data from the table with that question_id to the same table but with a new question_id.
any thoughts as to if this is possible using SQL?
my database is an ingres database
thanks in advance
Sure, something like this should work:
INSERT INTO YourTable (Question_Id, OtherField,...)
SELECT SomeNewQuestionId, OtherField,...
FROM YourTable
WHERE Question_Id = SomeQuestionId
Just replace SomeQuestionId and SomeNewQuestionId with the appropriate values.
It's a simple select query.
insert into mytable
(field2, field3, etc)
select field2, field3, etc
from mytable
where whatever.
This assumes that neither fields 2 nor 3 are the primary key, and that you have an autoincrement table.
Fast forward two years.... :)
I think this is the best and simplest way to do this. Inserting a row of data from the same table with a primary key will result in error because primary keys are unique for each row: Let question_id = 100.
INSERT INTO MyTable SELECT * FROM MyTable Where question_id=100;
In PostgreSQL:
ERROR: duplicate key value violates unique constraint "MyTable_pkey"
DETAIL: Key (question_id)=(100) already exists.
It is very simple to avoid the duplicate key value:
INSERT INTO MyTable SELECT (SELECT MAX(question_id)+1),Column1,Column2,etc FROM MyTable Where question_id=100;
By using MAX(question_id)+1, you are incrementing the maximum value of MyTable's question_id primary key, then add/copy the data to a new row with a unique question_id value.

Distinct not working?

I need to insert some field in a table. The table:
CREATE TABLE RADAR(
ctfoto VARCHAR2(5),
pkradar NUMBER(3,0),
sradar VARCHAR2(3),
limitvelctera NUMBER(3,0),
limitvelradar NUMBER(3,0),
CONSTRAINT radar_pk PRIMARY KEY(ctfoto, pkradar, sradar)
);
The insert operation:
INSERT INTO RADAR(ctfoto, pkradar, sradar, limitvelctera, limitvelradar)
SELECT distinct carretera_foto, pto_km_radar, sentido_radar, limit_vel_ctera, limit_vel_radar FROM gotcha
The error:
ORA-00001: unique constraint (USER4704.RADAR_PK) violated
Please help.
DISTINCT applies to the entire set of columns you are selecting.
In all probability, you have rows in GOTCHA that have the same carretera_foto, pto_km_radar, and sentido_radar values but different values for one or both of the other two columns (limit_vel_ctera and limit_vel_radar). The DISTINCT in your SELECT cannot eliminate either of the rows because at least one value is different but the primary key constraint on the RADAR table rejects rows where the first three columns are identical.
You probably have more than one record in gotcha with the same values in fields carretera_foto, pto_km_radar, sentido_radar.
DISTINCT means the whole record will not be repeated.

Can I write an insert query using data from two joined tables?

I have a SELECT query like this:
SELECT id_default_value, id_type FROM ntg_attribute, ntg_module_attribute
WHERE ntg_attribute.id_module_attribute = ntg_module_attribute.id;
This returns 2 columns, id_default_value and id_type. I'd like to then use this data as the basis of an INSERT query into another table, ntg_default_value, using id_default_value as the key, and id_type as the inserted value.
The following is nearly there, but not quite:
INSERT INTO ntg_default_value (id, id_type)
SELECT id_default_value, id_type FROM ntg_attribute, ntg_module_attribute
WHERE ntg_attribute.id_module_attribute = ntg_module_attribute.id;
This gives me:
ERROR: duplicate key value violates unique constraint "pk_ntg_default_value"
Is what I'm trying to do actually possible? If so, how do I construct the query?
(PostgreSQL 8.4.6)
The name of the constraint 'pk_ntg_default_value' probably means you are violating the primary key constraint of the table ntg_default_value.
Depending on your requirements you can either take away the primary key constraint. Or you can expand it to include both id & id_type if it doesn't already and add a GROUP BY to your query, if necessary, to prevent duplicate id_devault_value & id_type pairs. Your query becomes then :
INSERT INTO ntg_default_value (id, id_type)
SELECT id_default_value, id_type
FROM ntg_attribute, ntg_module_attribute
WHERE ntg_attribute.id_module_attribute =
ntg_module_attribute.id
GROUP BY id_default_value, id_type