SQL: ORA-02291: integrity constraint violated - parent key not found - oracle

I am creating this code SQL code and I keep getting the same error from every line of the insert statements after the errors begin here statement. the error is, ORA-02291: integrity constraint violated - parent key not found. I think it has something to do with the employee section constraint EMPSUPERVRFK but, that is the only constraint that the error message would lead to.
-- keep these two commands at the top of every sql file
set echo on
set linesize 120
delete from Employee;
commit;
-- insert only managers first with their dno is null
INSERT INTO Employee VALUES
('James','E','Borg',888665555,'10-NOV-1937','450 Stone, Houston, TX','M',55000,null,null);
INSERT INTO Employee VALUES
('Franklin','T','Wong',333445555, to_date('1955-12-08', 'YYYY-MM-DD'), '638 Voss, Houston, TX','M',40000,888665555,null);
INSERT INTO Employee VALUES
('Jennifer','J','Zelaya',987654321,'20-JUN-1941','291 Berry, Bellaire, TX','F',43000,888665555,null);
delete from Department;
commit;
insert into Department values ('Research',5,333445555,'22-MAY-1988');
insert into Department values ('Headquarters',1,888665555,'19-JUN-1981');
insert into Department values ('Administration',1,888665555,'01-JAN-1995');
-- now, update employee.dno for managers
UPDATE Employee SET dno = 1 WHERE ssn = 888665555;
UPDATE Employee SET dno = 5 WHERE ssn = 333445555;
-- need to update the rest of managers
-- insert the rest of non-manager employees, supervisors first
--errors begin here
delete from Employee;
commit;
INSERT INTO Employee VALUES ('John','B','Smith',123456789,'09-JAN-1965','731 Fondren, Houston, TX','M',30000,333445555,5);
insert into Employee values ('Alica','J','Zelya',999887777,'19-JAN-1968','3321 Castle, Spring, TX','F',25000,987654321,4);
insert into Employee values ('Ramesh','K','Narayan',666884444,'15-SEP-1962', '975 Fire Oak, Humnle, TX','M',38000,333445555,5);
insert into Employee values ('Joyce','A','English',453453453,'31-JUL-1972','5631 Rice, Houston, TX','F',25000,333445555,5);
insert into Employee values ('Ahmad','V','Jabbar',987987987,'29-MAR-1969','980 Dallas, Houston, TC','M',25000,987654321,4);
--Project
delete from PROJECT;
commit;
insert into PROJECT values ('ProductY',2,'Sugarland',5);
insert into PROJECT values ('ProductZ',3,'Houston',5);
insert into PROJECT values ('Computerication',10,'Stafford',4);
insert into PROJECT values ('Reorganization',20,'Houston',1);
insert into PROJECT values ('Newbenefits',30,'Stafford',4);
--dept_Locations
delete from DEPT_LOCATIONS;
commit;
insert into DEPT_LOCATIONS values (1, 'Houston');
insert into DEPT_LOCATIONS values (4,'Stafford');
insert into DEPT_LOCATIONS values (5,'Bellaire');
insert into DEPT_LOCATIONS values (5,'Sugarland');
insert into DEPT_LOCATIONS values (5,'Houston');
--works_on 16
delete from WORKS_ON;
commit;
insert into WORKS_ON values (123456789,1,32.5);
insert into WORKS_ON values (123456789,2,7.5);
insert into WORKS_ON values (666884444,3,40.0);
insert into WORKS_ON values (453453453,1,20.0);
insert into WORKS_ON values (453453453,2,20.0);
insert into WORKS_ON values (333445555,2,10.0);
insert into WORKS_ON values (333445555,3,10.0);
insert into WORKS_ON values (333445555,10,10.0);
insert into WORKS_ON values (333445555,20,10.0);
insert into WORKS_ON values (999887777,30,30.0);
insert into WORKS_ON values (999887777,10,10.0);
insert into WORKS_ON values (987987987,10,35.0);
insert into WORKS_ON values (987987987,30,5.0);
insert into WORKS_ON values (987654321,30,20.0);
insert into WORKS_ON values (987654321,20,15.0);
insert into WORKS_ON values (888665555,20,null);
--dependent 7
delete from DEPENDENT;
commit;
insert into DEPENDENT values (333445555,'Alice','F','05-APR-1986','Daughter');
insert into DEPENDENT values (333445555,'Theodore','M','25-OCT-1983','Son');
insert into DEPENDENT values (333445555,'Joy','F', '03-MAY-1958','Spouse');
insert into DEPENDENT values (987654321,'Abner','M', '28-FEB-1942','Spouse');
insert into DEPENDENT values (123456789,'Michael','M','04-JAN-1988','Son');
insert into DEPENDENT values (123456789,'Alice','F','30-DEC-1988','Daughter');
insert into DEPENDENT values (123456789,'Elizabeth','F', '05-MAY-1967','Spouse');
-----------------------------------------------------------------------------------
set echo on
set linesize 120
drop table Employee cascade constraints;
commit;
create table Employee
(
fname varchar2(15),
minit varchar2(1), -- can be char
lname varchar2(15),
ssn number,
bdate date,
address varchar2(50),
sex varchar2(1) CHECK(Sex = 'M' or Sex = 'F'),
salary number CHECK(20000 <= salary AND 100000 >= salary),
superssn number,
dno number DEFAULT 0,
constraint EMPPK
primary key(ssn),
constraint EMPSUPERVRFK
foreign key(superssn) references Employee(ssn)
ON DELETE SET NULL
);
drop table Department cascade constraints;
commit;
create table Department
(
dname varchar2(15),-- NOT NULL,
dnumber number,
mgrssn number,
mgrstartdate date,
constraint DEPTPK
primary key(dnumber),
constraint DEPTMGRFK
foreign key(mgrssn) references Employee(ssn)
ON DELETE SET NULL
);
alter table Employee add
constraint EMPDEPTFK foreign key(dno) references Department(dnumber)
ON DELETE SET NULL;
drop table DEPT_LOCATIONS;
create table DEPT_LOCATIONS
(
Dnumber number,
Dlocation varchar2(15),
constraint PK_DnoDloc primary key(Dnumber,Dlocation)
);
COMMIT;
drop table PROJECT;
create table PROJECT
(
Pname varchar2(15),
Ponumber number primary key,
Plocation varchar2 (15),
Dnum number,
foreign key (Dnum) references Department(dnumber)
);
Commit;
drop table DEPENDENT;
create table DEPENDENT
(
Essn number,
Dependent_name varchar2(15),
Sex Char,
Bdate Date,
Relationship varchar2(15),
foreign key(Essn) references Employee(ssn) --
ON DELETE SET NULL,
constraint PK_essn
primary key(Essn,Dependent_name)
);
COMMIT;
drop table WORKS_ON;
create table WORKS_ON
(
Essn number,
Pno number,
Hours number,
foreign key(Essn) references Employee(ssn)--
ON DELETE SET NULL,
foreign key(Pno) references PROJECT(Ponumber)
ON DELETE SET NULL,
constraint PK_SSN
primary key(Essn, Pno)
);
commit;
----------------------------------------------------------------
-- keep these two commands at the top of every sql file
set echo on
set linesize 120
-- test queries, not to be submitted
select count(*) from employee;
select count(*) as DEPT_COUNT from department;
-- comment out the above queries for your homework
-- a the first name, last name of employees who work in department 5.
select fname, lname from employee where dno = 5;
-- b the first name, last name of every employee and name of his/her department
select E.fname as FIRST_NAME, E.lname LAST_NAME, D.dname DEPARTMENT_NAME
from employee E, department D
where E.dno = D.dnumber;
--c The first name, last name of employees who works at the 'Research' department
select e.fname , e.lname , Dname
from employee e inner join department d on e.dno=d.dname
where d.name ='Research';
--d. The first name, last name of employee who is the manager of the 'Research' department
select e.fname , e.lname , Dname
from employee e inner join department d on e.dno=d.dname
where d.name ='Research' and e.super_ssn=d.mgr_ssn;
--e. The first name, last name of employees who works on the 'Computerization' project.
select e.fname,e.lname
from employee e inner join department d on e.dno=d.dnumber inner join project p on d.dnumber=p.dnum
where p.pname="Computerization";

this happens because you are inserting values to table that depends on other table that is still empty, you should insert on that table first before this one
for example, suppose you have employee table, and department table, in which every employee must be assigned to a department, so when you input employee Bob to department IT, it would result in error, since there is no IT yet in department table. so you need to input IT on department table, then you can input Bob to employee table
or, you can disable integrity check when importing sql, but this setting is different for each DB engine, so I can't give you an example

Related

How to generate a DDL and a DML in Oracle SQL (Scriptable)

I want to generate a .DDL that contains all the 'CREATE TABLES' and a .DML that contains all the 'INSERT'
I tried to use the answers of this question but didn't get to modify them to get the DDL and the DML
The question you referenced lets you get the DDL, to get the DML its easiest to use a tool. SQLcl is free and lets you do it easily, eg
SQL> select * from scott.emp;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
7369 SMITH CLERK 7902 17/DEC/80 800 20
7499 ALLEN SALESMAN 7698 20/FEB/81 1600 300 30
7521 WARD SALESMAN 7698 22/FEB/81 1250 500 30
7566 JONES MANAGER 7839 02/APR/81 2975 20
...
14 rows selected.
SQL> select /*insert*/ * from scott.emp;
REM INSERTING into SCOTT.EMP
SET DEFINE OFF;
Insert into SCOTT.EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO) values (7369,'SMITH','CLERK',7902,to_timestamp('17/DEC/80','DD/MON/RR HH12:MI:SSXFF AM'),800,null,20);
Insert into SCOTT.EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO) values (7499,'ALLEN','SALESMAN',7698,to_timestamp('20/FEB/81','DD/MON/RR HH12:MI:SSXFF AM'),1600,300,30);
Insert into SCOTT.EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO) values (7521,'WARD','SALESMAN',7698,to_timestamp('22/FEB/81','DD/MON/RR HH12:MI:SSXFF AM'),1250,500,30);
Insert into SCOTT.EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO) values (7566,'JONES','MANAGER',7839,to_timestamp('02/APR/81','DD/MON/RR HH12:MI:SSXFF AM'),2975,null,20);
Insert into SCOTT.EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO) values (7654,'MARTIN','SALESMAN',7698,to_timestamp('28/SEP/81','DD/MON/RR HH12:MI:SSXFF AM'),1250,1400,30);
Insert into SCOTT.EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO) values (7698,'BLAKE','MANAGER',7839,to_timestamp('01/MAY/81','DD/MON/RR HH12:MI:SSXFF AM'),2850,null,30);
...
...
Download SQLcl from Oracle
https://www.oracle.com/au/tools/downloads/sqlcl-downloads.html
Getting the DDL is easier now, it's a built-in command for SQL Developer and SQLcl.
For EMPLOYEES table, bonus: grabbing dependent objects on the table.
cd c:\users\jdsmith\desktop
set feedback off
set ddl segment_attributes off
set ddl storage off
set ddl tablespace off
spool employees_so.sql
ddl employees
set sqlformat insert
select * from employees;
spool off
Run this via F5 in SQL Developer (desktop) or SQLcl (cli at shell).
Out pops this file -
CREATE TABLE "HR"."EMPLOYEES"
( "EMPLOYEE_ID" NUMBER(6,0),
"FIRST_NAME" VARCHAR2(20) COLLATE "USING_NLS_COMP",
"LAST_NAME" VARCHAR2(25) COLLATE "USING_NLS_COMP" CONSTRAINT "EMP_LAST_NAME_NN" NOT NULL ENABLE,
"EMAIL" VARCHAR2(25) COLLATE "USING_NLS_COMP" CONSTRAINT "EMP_EMAIL_NN" NOT NULL ENABLE,
"PHONE_NUMBER" VARCHAR2(20) COLLATE "USING_NLS_COMP",
"HIRE_DATE" DATE CONSTRAINT "EMP_HIRE_DATE_NN" NOT NULL ENABLE,
"JOB_ID" VARCHAR2(10) COLLATE "USING_NLS_COMP" CONSTRAINT "EMP_JOB_NN" NOT NULL ENABLE,
"SALARY" NUMBER(8,2),
"COMMISSION_PCT" NUMBER(2,2),
"MANAGER_ID" NUMBER(6,0),
"DEPARTMENT_ID" NUMBER(4,0),
CONSTRAINT "EMP_SALARY_MIN" CHECK (salary > 0) ENABLE,
CONSTRAINT "EMP_EMAIL_UK" UNIQUE ("EMAIL")
USING INDEX ENABLE,
CONSTRAINT "EMP_DEPT_FK" FOREIGN KEY ("DEPARTMENT_ID")
REFERENCES "HR"."DEPARTMENTS" ("DEPARTMENT_ID") ENABLE,
CONSTRAINT "EMP_JOB_FK" FOREIGN KEY ("JOB_ID")
REFERENCES "HR"."JOBS" ("JOB_ID") ENABLE,
CONSTRAINT "EMP_MANAGER_FK" FOREIGN KEY ("MANAGER_ID")
REFERENCES "HR"."EMPLOYEES" ("EMPLOYEE_ID") ENABLE
) DEFAULT COLLATION "USING_NLS_COMP" ;
CREATE UNIQUE INDEX "HR"."EMP_EMP_ID_PK" ON "HR"."EMPLOYEES" ("EMPLOYEE_ID")
;
ALTER TABLE "HR"."EMPLOYEES" ADD CONSTRAINT "EMP_EMP_ID_PK" PRIMARY KEY ("EMPLOYEE_ID")
USING INDEX "HR"."EMP_EMP_ID_PK" ENABLE;
COMMENT ON COLUMN "HR"."EMPLOYEES"."EMPLOYEE_ID" IS 'Primary key of employees table.';
COMMENT ON COLUMN "HR"."EMPLOYEES"."FIRST_NAME" IS 'First name of the employee. A not null column.';
COMMENT ON COLUMN "HR"."EMPLOYEES"."LAST_NAME" IS 'Last name of the employee. A not null column.';
COMMENT ON COLUMN "HR"."EMPLOYEES"."EMAIL" IS 'Email id of the employee';
COMMENT ON COLUMN "HR"."EMPLOYEES"."PHONE_NUMBER" IS 'Phone number of the employee; includes country code and area code';
COMMENT ON COLUMN "HR"."EMPLOYEES"."HIRE_DATE" IS 'Date when the employee started on this job. A not null column.';
COMMENT ON COLUMN "HR"."EMPLOYEES"."JOB_ID" IS 'Current job of the employee; foreign key to job_id column of the
jobs table. A not null column.';
COMMENT ON COLUMN "HR"."EMPLOYEES"."SALARY" IS 'Monthly salary of the employee. Must be greater
than zero (enforced by constraint emp_salary_min)';
COMMENT ON COLUMN "HR"."EMPLOYEES"."COMMISSION_PCT" IS 'Commission percentage of the employee; Only employees in sales
department elgible for commission percentage';
COMMENT ON COLUMN "HR"."EMPLOYEES"."MANAGER_ID" IS 'Manager id of the employee; has same domain as manager_id in
departments table. Foreign key to employee_id column of employees table.
(useful for reflexive joins and CONNECT BY query)';
COMMENT ON COLUMN "HR"."EMPLOYEES"."DEPARTMENT_ID" IS 'Department id where employee works; foreign key to department_id
column of the departments table';
COMMENT ON TABLE "HR"."EMPLOYEES" IS 'employees table. Contains 107 rows. References with departments,
jobs, job_history tables. Contains a self reference.';
CREATE INDEX "HR"."EMP_DEPARTMENT_IX" ON "HR"."EMPLOYEES" ("DEPARTMENT_ID")
;
CREATE INDEX "HR"."EMP_JOB_IX" ON "HR"."EMPLOYEES" ("JOB_ID")
;
CREATE INDEX "HR"."EMP_MANAGER_IX" ON "HR"."EMPLOYEES" ("MANAGER_ID")
;
CREATE INDEX "HR"."EMP_NAME_IX" ON "HR"."EMPLOYEES" ("LAST_NAME", "FIRST_NAME")
;
CREATE OR REPLACE EDITIONABLE TRIGGER "HRREST"."TRIG_FOREIGN_TABLE"
BEFORE INSERT ON HR.EMPLOYEES
REFERENCING OLD AS OLD NEW AS NEW
BEGIN
NULL;
END;
/
ALTER TRIGGER "HRREST"."TRIG_FOREIGN_TABLE" ENABLE;
CREATE OR REPLACE EDITIONABLE TRIGGER "HR"."SECURE_EMPLOYEES"
BEFORE INSERT OR UPDATE OR DELETE ON employees
BEGIN
secure_dml;
END secure_employees;
/
ALTER TRIGGER "HR"."SECURE_EMPLOYEES" DISABLE;
CREATE OR REPLACE EDITIONABLE TRIGGER "HR"."UPDATE_JOB_HISTORY"
AFTER UPDATE OF job_id, department_id ON employees
FOR EACH ROW
BEGIN
add_job_history(:old.employee_id, :old.hire_date, sysdate,
:old.job_id, :old.department_id);
END;
/
ALTER TRIGGER "HR"."UPDATE_JOB_HISTORY" ENABLE;
CREATE OR REPLACE EDITIONABLE TRIGGER "HR"."EMPLOYEES_EMPLOYEE_ID_TRG"
before insert on employees
for each row
begin
if :new.employee_id is null then
select employees_seq.nextval into :new.employee_id from sys.dual;
end if;
end;
/
ALTER TRIGGER "HR"."EMPLOYEES_EMPLOYEE_ID_TRG" ENABLE;
REM INSERTING into EMPLOYEES
SET DEFINE OFF;
Insert into EMPLOYEES (EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,PHONE_NUMBER,HIRE_DATE,JOB_ID,SALARY,COMMISSION_PCT,MANAGER_ID,DEPARTMENT_ID) values (100,'Steven','King','SKING','515.123.4567',to_date('18-06-1987 06:00:00','DD-MM-YYYY HH24:MI:SS'),'AD_PRES',240000,null,null,90);
Insert into EMPLOYEES (EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,PHONE_NUMBER,HIRE_DATE,JOB_ID,SALARY,COMMISSION_PCT,MANAGER_ID,DEPARTMENT_ID) values (101,'Neena','Kochhar','NKOCHHAR','515.123.4568',to_date('22-09-1989 06:00:00','DD-MM-YYYY HH24:MI:SS'),'AD_VP',17000,null,100,90);
Insert into EMPLOYEES (EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,PHONE_NUMBER,HIRE_DATE,JOB_ID,SALARY,COMMISSION_PCT,MANAGER_ID,DEPARTMENT_ID) values (102,'Lex','De Haan','LDEHAAN','515.123.4569',to_date('14-01-1993 06:00:00','DD-MM-YYYY HH24:MI:SS'),'AD_VP',17000,null,100,90);
Insert into EMPLOYEES (EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,PHONE_NUMBER,HIRE_DATE,JOB_ID,SALARY,COMMISSION_PCT,MANAGER_ID,DEPARTMENT_ID) values (103,'Alexander','Hunold','AHUNOLD','590.423.4567',to_date('03-01-1990 00:00:00','DD-MM-YYYY HH24:MI:SS'),'IT_PROG',9000,null,102,60);
Insert into EMPLOYEES (EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,PHONE_NUMBER,HIRE_DATE,JOB_ID,SALARY,COMMISSION_PCT,MANAGER_ID,DEPARTMENT_ID) values (104,'Bruce','Ernst','BERNST','590.423.4568',to_date('20-05-1991 00:00:00','DD-MM-YYYY HH24:MI:SS'),'IT_PROG',6000,null,103,60);
Insert into EMPLOYEES (EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,PHONE_NUMBER,HIRE_DATE,JOB_ID,SALARY,COMMISSION_PCT,MANAGER_ID,DEPARTMENT_ID) values (105,'David','Austin','DAUSTIN','590.423.4569',to_date('25-06-1997 00:00:00','DD-MM-YYYY HH24:MI:SS'),'IT_PROG',4800,null,103,60);
Insert into EMPLOYEES (EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,PHONE_NUMBER,HIRE_DATE,JOB_ID,SALARY,COMMISSION_PCT,MANAGER_ID,DEPARTMENT_ID) values (106,'Valli','Pataballa','VPATABAL','590.423.4560',to_date('05-02-1998 00:00:00','DD-MM-YYYY HH24:MI:SS'),'IT_PROG',4800,null,103,60);
Insert into EMPLOYEES (EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,PHONE_NUMBER,HIRE_DATE,JOB_ID,SALARY,COMMISSION_PCT,MANAGER_ID,DEPARTMENT_ID) values (107,'Diana','Lorentz','DLORENTZ','590.423.5567',to_date('07-02-1999 00:00:00','DD-MM-YYYY HH24:MI:SS'),'IT_PROG',4200,null,103,60);
...
To adapt #ThatJeffSmith's answer
If you have three tables: employees, departments, jobs then you can use:
cd c:\users\jdsmith\desktop
set feedback off
set ddl segment_attributes off
set ddl storage off
set ddl tablespace off
spool myschema.ddl
ddl employees
ddl departments
ddl jobs
spool off
spool myschema.dml
set sqlformat insert
select * from employees;
select * from departments;
select * from jobs;
spool off

cannot insert data into the 4th table

I used the following script to create 4 test tables: dept1, dept2, dept3, and dept4. The code is exactly the same for each table. All tables are created successfully but the insert into statements only worked for the first three tables. After dropping all tables and purge the recyclebin, I moved Create Table dept4 and the following insert into statements to the top of the code. Then the insert into statement does not work for Dept3. Basically, I can only insert data into the first three tables in the script and not able to insert data into the 4th table on the script.
The error message is the following:
SQL Error: ORA-00604: error occurred at recursive SQL level 1
ORA-30667: cannot drop NOT NULL constraint on a DEFAULT ON NULL column
00604. 00000 - "error occurred at recursive SQL level %s"
This happened after some users created identity columns in Oracle 12.1 database. Some users used:
GENERATED ALWAYS AS IDENTITY
Other users used:
GENERATED BY DEFAULT ON NULL AS IDENTITY
Code used:
CREATE TABLE DEPT1 (
DEPT1NO NUMBER(2) NOT NULL,
DNAME VARCHAR2(14),
LOC VARCHAR2(13),
CONSTRAINT DEPT1_PRIMARY_KEY PRIMARY KEY (DEPT1NO));
INSERT INTO DEPT1 VALUES (10,'ACCOUNTING','NEW YORK');
INSERT INTO DEPT1 VALUES (20,'RESEARCH','DALLAS');
INSERT INTO DEPT1 VALUES (30,'SALES','CHICAGO');
INSERT INTO DEPT1 VALUES (40,'OPERATIONS','BOSTON');
CREATE TABLE DEPT2 (
DEPT2NO NUMBER(2) NOT NULL,
DNAME VARCHAR2(14),
LOC VARCHAR2(13),
CONSTRAINT DEPT2_PRIMARY_KEY PRIMARY KEY (DEPT2NO));
INSERT INTO DEPT2 VALUES (10,'ACCOUNTING','NEW YORK');
INSERT INTO DEPT2 VALUES (20,'RESEARCH','DALLAS');
INSERT INTO DEPT2 VALUES (30,'SALES','CHICAGO');
INSERT INTO DEPT2 VALUES (40,'OPERATIONS','BOSTON');
CREATE TABLE DEPT3 (
DEPT3NO NUMBER(2) NOT NULL,
DNAME VARCHAR2(14),
LOC VARCHAR2(13),
CONSTRAINT DEPT3_PRIMARY_KEY PRIMARY KEY (DEPT3NO));
INSERT INTO DEPT3 VALUES (10,'ACCOUNTING','NEW YORK');
INSERT INTO DEPT3 VALUES (20,'RESEARCH','DALLAS');
INSERT INTO DEPT3 VALUES (30,'SALES','CHICAGO');
INSERT INTO DEPT3 VALUES (40,'OPERATIONS','BOSTON');
CREATE TABLE DEPT4 (
DEPT4NO NUMBER(2) NOT NULL,
DNAME VARCHAR2(14),
LOC VARCHAR2(13),
CONSTRAINT DEPT4_PRIMARY_KEY PRIMARY KEY (DEPT4NO));
INSERT INTO DEPT4 VALUES (10,'ACCOUNTING','NEW YORK');
INSERT INTO DEPT4 VALUES (20,'RESEARCH','DALLAS');
INSERT INTO DEPT4 VALUES (30,'SALES','CHICAGO');
INSERT INTO DEPT4 VALUES (40,'OPERATIONS','BOSTON');

MERGING DATA OF TWO TABLES

I want to write a query which finds the difference between two tables and writes updates or new data into third table. My two tables have identical column names. Third table which captures changes have extra column called comment. I would like to insert the comment whether it is a new row or updated row based on the row modification.
**TABLE1 (BACKUP)**
KEY,FIRST_NAME,LAST_NAME,CITY
1,RAM,KUMAR,INDIA
2,TOM,MOODY,ENGLAND
3,MOHAMMAD,HAFEEZ,PAKISTAN
4,MONIKA,SAM,USA
5,MIKE,PALEDINO,USA
**TABLE2 (CURRENT)**
KEY,FIRST_NAME,LAST_NAME,CITY
1,RAM,KUMAR,USA
2,TOM,MOODY,ENGLAND
3,MOHAMMAD,HAFEEZ,PAKISTAN
4,MONIKA,SAM,INDIA
5,MIKE,PALEDINO,USA
6,MAHELA,JAYA,SL
**TABLE3 (DIFFERENCE FROM TABLE2 TO TABLE1)**
KEY,FIRST_NAME,LAST_NAME,CITY,COMMENT
1,RAM,KUMAR,USA,UPDATE
4,MONIKA,SAM,INDIA,UPDATE
6,MAHELA,JAYA,SL,INSERT
table scripts
DROP TABLE TABLE1;
DROP TABLE TABLE2;
DROP TABLE TABLE3;
CREATE TABLE TABLE1
(
KEY NUMBER,
FIRST_NAME VARCHAR2(100),
LAST_NAME VARCHAR2(100),
CITY VARCHAR2(50)
);
/
CREATE TABLE TABLE2
(
KEY NUMBER,
FIRST_NAME VARCHAR2(100),
LAST_NAME VARCHAR2(100),
CITY VARCHAR2(50)
);
/
CREATE TABLE TABLE3
(
KEY NUMBER,
FIRST_NAME VARCHAR2(100),
LAST_NAME VARCHAR2(100),
CITY VARCHAR2(50),
COMMENTS VARCHAR2(200)
);
/
INSERT ALL
INTO TABLE1
VALUES(1,'RAM','KUMAR','INDIA')
INTO TABLE1 VALUES(2,'TOM','MOODY','ENGLAND')
INTO TABLE1 VALUES(3,'MOHAMMAD','HAFEEZ','PAKISTAN')
INTO TABLE1 VALUES(4,'MONIKA','SAM','USA')
INTO TABLE1 VALUES(5,'MIKE','PALEDINO','USA')
SELECT 1 FROM DUAL;
/
INSERT ALL
INTO TABLE2
VALUES(1,'RAM','KUMAR','USA')
INTO TABLE2 VALUES(2,'TOM','MOODY','ENGLAND')
INTO TABLE2 VALUES(3,'MOHAMMAD','HAFEEZ','PAKISTAN')
INTO TABLE2 VALUES(4,'MONIKA','SAM','INDIA')
INTO TABLE2 VALUES(5,'MIKE','PALEDINO','USA')
INTO TABLE2 VALUES(6,'MAHELA','JAYA','SL')
SELECT 1 FROM DUAL;
I was using the merge statement to accomplish the same. but i have hit a roadblock in merge statement , it's rhrowing an error "SQL Error: ORA-00905: missing keyword
00905. 00000 - "missing keyword"" I dont understand where is the error. please help
INSERT INTO TABLE3
SELECT KEY,FIRST_NAME,LAST_NAME,CITY,NULL AS COMMENTS FROM TABLE2
MINUS
SELECT KEY,FIRST_NAME,LAST_NAME,CITY,NULL AS COMMENTS FROM TABLE1
;
MERGE INTO TABLE3 A
USING TABLE1 B
ON (A.KEY=B.KEY)
WHEN MATCHED THEN
UPDATE SET A.COMMENTS='UPDATED'
WHEN NOT MATCHED THEN
UPDATE SET A.COMMENTS='INSERTED';
There is no such WHEN NOT MATCHED THEN UPDATE clause, you should use WHEN NOT MATCHED THEN INSERT. Refer to MERGE for details.
A few assumptions made about the data:
An INSERT event will be a record identified by its key in table2 (current data) that does not have a matching key in the original back-up table: table1.
An UPDATE event is a field that exists in both table1 and table2 for the same KEY but is not the same.
Records which did not change between tables are not to be recorded in table3.
Example Query: Check for Updates
SELECT UPD_QUERY.NEW_CITY, 'UPDATED' as COMMENTS
FROM (SELECT CASE WHEN REPLACE(CURR.CITY, BKUP.CITY,'') IS NOT NULL THEN CURR.CITY
ELSE NULL END as NEW_CITY
FROM table1 BKUP, table2 CURR
WHERE BKUP.KEY = CURR.KEY) UPD_QUERY
WHERE UPD_QUERY.NEW_CITY is NOT NULL;
You can repeat this comparison method for the other fields:
SELECT UPD_QUERY.*
FROM (SELECT CURR.KEY,
CASE WHEN REPLACE(CURR.FIRST_NAME, BKUP.FIRST_NAME,'') IS NOT NULL
THEN CURR.FIRST_NAME
ELSE NULL END as FIRST_NAME,
CASE WHEN REPLACE(CURR.LAST_NAME, BKUP.LAST_NAME,'') IS NOT NULL
THEN CURR.LAST_NAME
ELSE NULL END as LAST_NAME,
CASE WHEN REPLACE(CURR.CITY, BKUP.CITY,'') IS NOT NULL
THEN CURR.CITY
ELSE NULL END as CITY
FROM table1 BKUP, table2 CURR
WHERE BKUP.KEY = CURR.KEY) UPD_QUERY
WHERE COALESCE(UPD_QUERY.FIRST_NAME, UPD_QUERY.LAST_NAME, UPD_QUERY.CITY)
is NOT NULL;
NOTE: This could get unwieldy very quickly if the number of columns compared are many. Since the target table design (table3) requires not only identification of a change, but the field and its new value are also recorded.
Example Query: Look for Newly Added Records
SELECT CURR.*, 'INSERTED' as COMMENTS
FROM table2 CURR, table1 BKUP
WHERE CURR.KEY = BKUP.KEY(+)
AND BKUP.KEY is NULL;
Basically MERGE forces the operation: MATCHED=UPDATE (or DELETE), NOT MATCHED = INSERT. It's in the docs.
You can do what you want but you need two insert statements with different set operators,
For UPDATED:
Insert into table3
table1 INTERSECT table2
For INSERTED:
Insert into table3
table2 MINUS table1

handling exception for insert into select from

SCHEMA 1
I have table transaction table
create table TXN_HEADER
(
txn_id NUMBER(10) not null,
txn_Date date
product_id NUMBER(10),
company_id NUMBER(10),
dealer_id NUMBER(10),
tran_amt number(10,2)
)
The above table having foreign key references to product.product_id and company.company_id.
This table having 5m rows
SCHEMA 2
create table TXN_HEADER_REPORTS
(
txn_id NUMBER(10) not null,
txn_Date date
product_id NUMBER(10),
company_id NUMBER(10),
dealer_id NUMBER(10),
tran_amt number(10,2)
)
here also we have the same constraints , having foreign key references to product.product_id and company.company_id.
in schema 2 we are trying to insert all the rows from schemea 1 to schema 2 in one shot, like this
begin
insert into TXN_HEADER_REPORTS (
txn_id, txn_Date ,product_id,company_id , dealer_id , tran_amt)
select
txn_id, txn_Date ,product_id,company_id , dealer_id , tran_amt
from schema1.TXN_HEADER;
commit;
exception
when others then
< ... procedure to log the errors >
end;
now we are trying to execute the above procedure , and it failed due to foreign key constraint of one rows. But entire my transaction rollback. Actually i dont want to use cursor to process the rows one by one , at it takes long time. So i used to "insert into .. SElect from " but due to constraints of 1 row all my transaction not moved to schema2.txn_Extract_hdr.
Is there any way to trap only that failed and to process the other rows without terminating
Please advice ..
You can create an error log table, and then use a single insert:
exec dbms_errlog.create_error_log(dml_table_name => 'TXN_HEADER_REPORTS');
insert into TXN_HEADER_REPORTS ( txn_id, txn_Date ,product_id,company_id ,
dealer_id , tran_amt)
select txn_id, txn_Date ,product_id,company_id , dealer_id , tran_amt
from schema1.TXN_HEADER
log errors into ERR$_TXN_HEADER_REPORTS reject limit unlimited;
Any rows that can't inserted will be recorded in the ERR table. Note that this is plain SQL, it doesn't need to be in a PL/SQL block.
Read more in the documentation.
I don't understand your constraint.
Does your insert fail because the product_id and company_id don't exists in schema2?
In that case, it may be better to insert the missing company and product records before you insert records into TXN_HEADER_REPORTS of schema2.
insert into company com_sch2
(col1, col2, col2,...)
select col1, col2, col3, ...
from schema1.company com_sch1
where not exists (select 'x'
from company com2
where com2.company_id = com_sch1.company_id);
And the seem for the product table.

Copy or show the primary key value into another table as foreign key APEX

I have two tables A and B .i want to copy or show the primary key column value from table A in the foreign key column in table B respectively .is there any method kindly help me.
Regards,
You can populate your primary key value while populating table B or by using a trigger when you are populating table A.
CREATE TABLE t1 (id1 NUMBER, dt DATE);
ALTER TABLE t1 ADD (
CONSTRAINT t1_pk
PRIMARY KEY
(id1));
CREATE TABLE t2 (id2 NUMBER, id1 NUMBER, dt2 DATE);
ALTER TABLE t2 ADD (
CONSTRAINT t2_pk
PRIMARY KEY
(id2));
ALTER TABLE t2
ADD CONSTRAINT t2_r01
FOREIGN KEY (id2)
REFERENCES t1 (id1);
First Approach, by this way you could populate second table when you are inserting values.
INSERT INTO t1
VALUES (1, SYSDATE
);
INSERT INTO t2
VALUES (1, 1, SYSDATE
);
With trigger, so when values are inserted into first table second tables values are populated using a trigger. So primary key value of first table is being inserted into foreign key of table 2.
CREATE OR REPLACE TRIGGER my_trigger
AFTER INSERT
ON t1
FOR EACH ROW
BEGIN
INSERT INTO t2
VALUES (1, :new.id1, SYSDATE
);
EXCEPTION
WHEN NO_DATA_FOUND
THEN
DBMS_OUTPUT.put_line (TO_CHAR (SQLERRM (-20299)));
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line (TO_CHAR (SQLERRM (-20298)));
END;

Resources