Why do some users and not others get ORA-01400: cannot insert NULL into primary key - oracle

EDIT: I have replaced the generic SQL with the actual SQL.
I know how to fix it. I am just wondering why it worked on some developer machines and not others.
CREATE TABLE OUTPUTDEFNACTIVATION ("OUTPUTDEFNACTIVATIONID" NUMBER, "OUTPUTDEFNTYPE" NUMBER(1,0) NOT NULL, "OUTPUTDEFNID" NUMBER NOT NULL, "PROJECTVIEWID" NUMBER, "SYSTEMUSERID" NUMBER, "VISIBLE" NUMBER(3,0));
ALTER TABLE OUTPUTDEFNACTIVATION ADD CONSTRAINT OUTPUTDEFNACTIVATION_P PRIMARY KEY (OUTPUTDEFNACTIVATIONID) ENABLE;
ALTER TABLE OUTPUTDEFNACTIVATION ADD CONSTRAINT OUTPUTDEFNACTIVATION_PROJECT FOREIGN KEY (PROJECTVIEWID) REFERENCES PROJECTVIEW (PROJECTVIEWID) ON DELETE CASCADE ENABLE;
ALTER TABLE OUTPUTDEFNACTIVATION ADD CONSTRAINT OUTPUTDEFNACTIVATION_USER FOREIGN KEY (SYSTEMUSERID) REFERENCES SYSTEMUSER (SYSTEMUSERID) ON DELETE CASCADE ENABLE;
ALTER TABLE OUTPUTDEFNACTIVATION ADD CONSTRAINT UNIQUE_OUTPUTDEFNACTIVATION UNIQUE (OUTPUTDEFNTYPE, OUTPUTDEFNID, SYSTEMUSERID, PROJECTVIEWID);
CREATE SEQUENCE "OUTPUTDEFNACTIVATION_SEQ" MINVALUE 1 MAXVALUE 1.00000000000000E+27 INCREMENT BY 1 START WITH 1 CACHE 20 NOORDER NOCYCLE;
INSERT INTO OUTPUTDEFNACTIVATION (OUTPUTDEFNTYPE, OUTPUTDEFNID, SYSTEMUSERID, PROJECTVIEWID, VISIBLE)
SELECT 0, KPIDEFNID, SYSTEMUSERID, PROJECTVIEWID, VISIBLE FROM KPIDEFN, SYSTEMUSER, PROJECTVIEW, DUAL WHERE ACTIVE = 1 AND SYSTEMUSERID <> 1 AND STATUSID IN (1,4);
My fix is
INSERT INTO OUTPUTDEFNACTIVATION (OUTPUTDEFNACTIVATIONID, OUTPUTDEFNTYPE, OUTPUTDEFNID, SYSTEMUSERID, PROJECTVIEWID, VISIBLE)
SELECT OUTPUTDEFNACTIVATION_SEQ.NEXTVAL, 0, KPIDEFNID, SYSTEMUSERID, PROJECTVIEWID, VISIBLE FROM KPIDEFN, SYSTEMUSER, PROJECTVIEW, DUAL WHERE ACTIVE = 1 AND SYSTEMUSERID <> 1 AND STATUSID IN (1,4);
But why wasn't it necessary on all developer machines? They all have their own schema, but my script created this table for them all.
ORA-01400: cannot insert NULL into ("DEVF22FMT"."OUTPUTDEFNACTIVATION"."OUTPUTDEFNACTIVATIONID")

The same table behaves the same way, so - if all of them (developers) used the same INSERT statement, connected to the same database (user), they'd get the same result - either success or a failure.
However, if they have their own schemas, then it depends on the way they created target tables.
Behaviour you described could be result of
identity column (12c onwards)
database trigger
which then "automatically", in the background, populate that NOT NULL column.

Related

How do I create a foreign key on two columns that are under the primary key constraint?

CREATE TABLE "RESEARCH_DEP"."RESEARCH_TV_COMPANY"
( "CID" NUMBER(38,0) NOT NULL ENABLE,
"SOURCE_ID" NUMBER(2,0),
CONSTRAINT "PK_RESEARCH_TV_COMPANY_1" PRIMARY KEY ("CID", "SOURCE_ID")
USING INDEX (CREATE UNIQUE INDEX "RESEARCH_DEP"."IDX_TV_COMPANY_CID_SOURCE_ID" ON "RESEARCH_DEP"."RESEARCH_TV_COMPANY" ("CID", "SOURCE_ID")
CREATE TABLE "RESEARCH_DEP"."RESEARCH_METRICS_PHARMA_AUD"
( "ID" NUMBER GENERATED ALWAYS AS IDENTITY MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 1 CACHE 20 NOORDER NOCYCLE NOKEEP NOSCALE NOT NULL ENABLE,
"SOURCE_ID" NUMBER(2,0) NOT NULL ENABLE,
"MEDIA_COMPANY_ID" NUMBER(*,0) NOT NULL ENABLE
)
NEED
ALTER TABLE RESEARCH_DEP.RESEARCH_METRICS_PHARMA_AUD
ADD CONSTRAINT fk_METRICS_PHARMA_AUD_TV_COMPANY_ID
FOREIGN KEY (MEDIA_COMPANY_ID,SOURCE_ID) REFERENCES RESEARCH_DEP.RESEARCH_TV_COMPANY(CID,SOURCE_ID);
ORA-02298: parent keys not found
DO I NEED TO CREATE A COMPOSITION COLUMN: CID,SOURCE_ID?
OR
create sequence of values two column oracle CID,SOURCE_ID ?
Your code is more or less OK:
SQL> create table research_tv_company
2 (cid number,
3 source_id number,
4 --
5 constraint pk_rtc primary key (cid, source_id)
6 );
Table created.
SQL> create table research_metrics_pharma_aud
2 (id number,
3 source_id number,
4 media_company_id number
5 );
Table created.
SQL> alter table research_metrics_pharma_aud
2 add constraint fk_rmpa_rtc
3 foreign key (media_company_id, source_id)
4 references research_tv_company (cid, source_id);
Table altered.
SQL>
Note that I
removed double quotes
removed NOT NULL for primary key columns (they can't be NULL anyway)
don't have any indexes created so Oracle will - along with table creation - create a primary key constraint AND unique index to support it
as I'm on 11gXE and it doesn't support identity columns, I removed that
from the second table; I'd have to enforce it via a trigger. You don't have to do anything about it, just saying (so that you wouldn't wonder where did it go?)
Error you got:
ORA-02298: parent keys not found
means that there are combinations of (media_company_id, source_id) in the second table that do not exist as pairs of (cid, source_id) in the first table. To illustrate it:
Drop the foreign key constraint first (otherwise, I wouldn't be able to do that):
SQL> alter table research_metrics_pharma_aud drop constraint fk_rmpa_rtc;
Table altered.
Insert a row into the first (master) table:
SQL> insert into research_tv_company (cid, source_id) values (1, 1);
1 row created.
Insert two rows into the second (detail) table; the first combination is valid, the second is not as (2, 2) don't exist in research_tv_company:
SQL> insert into research_metrics_pharma_aud (id, source_id, media_company_id) values (1, 1, 1);
1 row created.
SQL> insert into research_metrics_pharma_aud (id, source_id, media_company_id) values (2, 2, 2);
1 row created.
SQL>
If we try to create a foreign key constraint:
SQL> alter table research_metrics_pharma_aud
2 add constraint fk_rmpa_rtc
3 foreign key (media_company_id, source_id)
4 references research_tv_company (cid, source_id);
add constraint fk_rmpa_rtc
*
ERROR at line 2:
ORA-02298: cannot validate (SCOTT.FK_RMPA_RTC) - parent keys not found
SQL>
See? The same error you got.
What can you do?
insert missing primary key values into the master table, or
delete detail rows that violate the constraint, or
create the constraint, but instruct Oracle not to check whether existing rows are valid or not:
SQL> alter table research_metrics_pharma_aud
2 add constraint fk_rmpa_rtc
3 foreign key (media_company_id, source_id)
4 references research_tv_company (cid, source_id)
5 enable novalidate;
Table altered.
SQL>
The enable novalidate means that foreign key constraint will be enabled for any new or modified rows, but existing rows won't be checked. If that option suits you, use it. However, I believe that one of the first two option is better, with the first one - adding missing primary keys - being the best.

add composite/ foreign key in sqlplus

I have a very basic question regarding the Keys in SQL. I am trying to write an SQL statement so I can add the foreign key to my tables, however, it would always "table not found or missing". And the reason why I can't create that table is that the next table also has foreign keys from another table that I need to reference. Is there a way around it?
create table table_name (id char (3) primary key, name varchar (8));
SQL > table created.
create table table_name_2 (table2ID char (3) primary key, CID char (3),
name varchar (8), title varchar (8), foreign key (CID) references table_name_3);
SQL > missing table (table_name_3);
create table table_name_3 (CID char (3) primary key, tTitle varchar (8),
foreign key (phone) references table_name_4);
So I was only able to create table 3. What do I need to do so that I can create the table and add the foreign keys referencing while I write the SQL statements?
I am not ALLOWED to use ALTER table.
Create foreign keys separately, using the ALTER TABLE statement. Like this:
SQL> CREATE TABLE table_name(
2 id CHAR(3)PRIMARY KEY,
3 name VARCHAR(8)
4 );
Table created.
SQL> CREATE TABLE table_name_2(
2 table2id CHAR(3)PRIMARY KEY,
3 cid CHAR(3),
4 name VARCHAR(8),
5 title VARCHAR(8)
6 );
Table created.
SQL> CREATE TABLE table_name_3(
2 cid CHAR(3)PRIMARY KEY,
3 ttitle VARCHAR(8)
4 );
Table created.
Now the foreign key:
SQL> ALTER TABLE table_name_2 ADD CONSTRAINT fk_2_3 FOREIGN KEY(cid)
2 REFERENCES table_name_3;
Table altered.
SQL>
one approach you can od is to create the table with the Primary key and then do
and add the foreign key.
ALTER TABLE child_table
ADD CONSTRAINT fk_name
FOREIGN KEY (col1) REFERENCES parent_table(col1);

In oracle on delete set null is not working

I have created two tables:
Create Table Dept
(Department_id number Constraint Depart_id_pk Primary Key
,Department_name varchar2(20));
Create table Emp
(Emp_id number Constraint Empl_id_pk Primary Key
,First_name varchar2(10)
,salary number
,Department_id number
,Constraint depart_id_fk Foreign Key (department_id)
References Dept (Department_id) on delete set null);
Then I have inserted some records in dept and Emp table. But when I try to drop dept table, instead of setting null in Emp.department_id column it shows error like this:
SQL> Drop Table Dept;
Drop Table Dept
*
ERROR at line 1:
ORA-02449: unique/primary keys in table referenced by foreign keys
The foreign key's clause say "on delete set null". Delete is a DML operation, and had you attempted to delete rows from the dept table, the corresponding emp rows would have been updated with a null dept_id.
But this isn't the case - you tried to drop the entire table, a DDL operation. This isn't allowed, because you'd be leaving behind constraints on the emp table that reference a table that no longer exists. If you want to drop these constraints too, you can use a cascade constraints clause:
DROP TABLE dept CASCADE CONSTRAINTS

Filtering child table in Db Adapter on Oracle Service Bus

I have a self-related table containing both active and historical data (field status holding 'A'(ctive) or 'H'(istorical) )
I need to create a service returning active records with all their active children.
I may add a condition to the main query but can not affect the "many" part of one-to-many relation: historical records are also retrieved. Is it possible to implement it without creating a pipeline looping through the service based on table with no relation? In pure eclipselink this may be achieved by utilizing DescriptorCustomizer, but I don't know whether this is valid solution for OSB.
Also I can not create a database view containing only active records.
BTW I'm on 12.2.1.1
Example table structure and data (for Oracle):
create table SELF_REL_TAB
(
ID number not null,
PARENT_ID number,
STATUS varchar2(1)
);
comment on column SELF_REL_TAB.ID
is 'Primary key';
comment on column SELF_REL_TAB.PARENT_ID
is 'Self reference';
comment on column SELF_REL_TAB.STATUS
is 'Status A(ctive) H(istorical)';
alter table SELF_REL_TAB
add constraint SRT_PK primary key (ID);
alter table SELF_REL_TAB
add constraint SRT_SRT_FK foreign key (PARENT_ID)
references SELF_REL_TAB (ID);
alter table SELF_REL_TAB
add constraint srt_status_chk
check (STATUS IN ('A','H'));
INSERT INTO SELF_REL_TAB VALUES (1, NULL, 'A');
INSERT INTO SELF_REL_TAB VALUES (2, 1, 'A');
INSERT INTO SELF_REL_TAB VALUES (3, 1, 'H');
Maybe you solved it, but you can use connect by clause to do that.
select
lpad(' ', 2*level) || id
from
self_rel_tab
where status = 'A'
start with
parent_id is null
connect by
prior id=parent_id
JP

How to delete rows with bi-directional dependencies?

I'm using Oracle 10g Express and trying to delete records from tables with bi-directional constraints. I'm trying to un-thread hundreds of tables and dependencies generated via Hibernate (which can't be changed at this point), but here is an extremely simplified example:
create table TableA (id number(19,0) not null, ..., rTableA_id number(19,0), primary key (id));
create table TableB (id number(19,0) not null, ..., rTableB_id number(19,0), primary key (id));
alter table TableA add constraint FKA1 foreign key (rTableA_id) references TableB;
alter table TableB add constraint FKB1 foreign key (rTableB_id) references TableA;
Trying to delete entries from either table returns the following:
EDIT: This happens in my case with foreign keys prefixed with SYS_
ORA-02292: integrity constraint (XXX.FKA1) violated - child record found
I've also tried to disable constraints but all attempts are futile:
ORA-02297: cannot disable constraint (XXX.FKA1) - dependencies exist
I have to wonder how your data got in this state in the first place, since your foreign keys are not null. If both tables were empty to start with, you'd never be able to insert a row into either table.
Ignoring that for a moment, recreating your scenario, I have no problem disabling the constraints:
CREATE TABLE tablea(id NUMBER(19, 0) NOT NULL,
rtablea_id NUMBER(19, 0) NOT NULL,
PRIMARY KEY(id))
/
CREATE TABLE tableb(id NUMBER(19, 0) NOT NULL,
rtableb_id NUMBER(19, 0) NOT NULL,
PRIMARY KEY(id))
/
INSERT INTO tablea
VALUES (1, 2)
/
INSERT INTO tableb
VALUES (2, 1)
/
ALTER TABLE tablea ADD CONSTRAINT fka1
FOREIGN KEY (rtablea_id)
REFERENCES tableb
/
ALTER TABLE tableb ADD CONSTRAINT fkb1
FOREIGN KEY (rtableb_id)
REFERENCES tablea
/
ALTER TABLE tablea MODIFY CONSTRAINT fka1 DISABLE
/
ALTER TABLE tableb MODIFY CONSTRAINT fkb1 DISABLE
/
delete tablea
/
delete tableb
/
commit
/
Result:
Table created.
Table created.
1 row created.
1 row created.
Table altered.
Table altered.
Table altered.
Table altered.
1 row deleted.
1 row deleted.
Commit complete.
I'm not sure how you'd get a ORA-02297 error when attempting to disable a foreign key. That error is typically seen when disabling a primary or unique key that a foreign key relies upon.
I suspect what you really want to do is set the constraints to initially deferred. This would allow you to perform inserts and deletes to each table individually, as long as the corresponding row was updated or deleted before the transaction is commited:
CREATE TABLE tablea(id NUMBER(19, 0) NOT NULL,
rtablea_id NUMBER(19, 0) NOT NULL,
PRIMARY KEY(id))
/
CREATE TABLE tableb(id NUMBER(19, 0) NOT NULL,
rtableb_id NUMBER(19, 0) NOT NULL,
PRIMARY KEY(id))
/
ALTER TABLE tablea ADD CONSTRAINT fka1
FOREIGN KEY (rtablea_id)
REFERENCES tableb
INITIALLY DEFERRED
/
ALTER TABLE tableb ADD CONSTRAINT fkb1
FOREIGN KEY (rtableb_id)
REFERENCES tablea
INITIALLY DEFERRED
/
INSERT INTO tablea
VALUES (1, 2)
/
INSERT INTO tableb
VALUES (2, 1)
/
INSERT INTO tableb
VALUES (3, 1)
/
COMMIT
/
DELETE tableb
WHERE id = 2
/
UPDATE tablea
SET rtablea_id = 3
WHERE id = 1
/
COMMIT
/
Result:
Table created.
Table created.
Table altered.
Table altered.
1 row created.
1 row created.
1 row created.
Commit complete.
1 row deleted.
1 row updated.
Commit complete.
Are you sure that Hibernate cannot be told to create the constraints as deferrable? If the DDL doesn't use the DEFERRABLE keyword, the constraints will be non-deferrable by default. That is going to mean that you won't be able to delete the data. If you have a schema with circular references, you would always want to declare your foreign key constraints to be deferrable.
You could drop the constraints, delete the data, and then re-create the constraints (either using Hibernate's DDL or by adding the INITIALLY DEFERRED DEFERRABLE clause at the end). But that would be a major pain if you delete data from either table with any sort of frequency. You'll also tend to have problems inserting new data if the new A row wants to reference the new B row you're creating.
I was unable to add INITIALLY DEFERRED because the databases (as well as the underlying Hibernate scripts) already exist. For new systems, this would have been an option, however, there are many tools (of which I only know several) which rely on the Database in its current form and I was too afraid of any unintended side-effects by adding this parameter to 700 tables.
Therefore, I used the following solution:
alter table TableA MODIFY CONSTRAINT FKA1 DISABLE;
alter table TableB MODIFY CONSTRAINT FKB1 DISABLE;
delete from TableA where id = 1;
delete from TableB where id = 2;
alter table TableA MODIFY CONSTRAINT FKA1 ENABLE;
alter table TableB MODIFY CONSTRAINT FKB1 ENABLE;

Resources