Oracle PLSQL Cascade Delete doesn't work? - sql

I have some tables with foreign keys which should be deleted. I Put the "on delete cascade" everywhere I needed it, but when I try to Drop the Table i get following error:
*Cause: An attempt was made to drop a table with unique or
primary keys referenced by foreign keys in another table.
This is the Table I want to drop:
DROP TABLE Author;
CREATE TABLE Author (
id NUMBER(4) NOT NULL,
first_name VARCHAR2(30) NOT NULL,
last_name VARCHAR2(30) NOT NULL,
date_of_birth DATE NOT NULL,
date_of_death DATE NULL,
CONSTRAINT Author_PK PRIMARY KEY (id)
);
And this is the Table that is in relation to the Author table:
CREATE TABLE Book (
id NUMBER(4) NOT NULL,
author NUMBER(4) NULL,
title VARCHAR2(30) NOT NULL,
ISBN VARCHAR2(13) NOT NULL,
book_language VARCHAR2(2) NOT NULL,
book_genre VARCHAR2(20) NOT NULL,
CONSTRAINT Book_PK PRIMARY KEY (id),
CONSTRAINT Book_Author FOREIGN KEY (author) REFERENCES Author(id) ON DELETE cascade
);

DROP is a DDL. It has nothing to do with DELETE (DML) (affected by the way you created the foreign key constraint).
Drop child table first; then drop its parent.

I resolved it now with help from #a_horse_with_no_name
If you have the same issue, just write
drop table table_name cascade constraints;

Related

I'm getting an error on Oracle Apex ORA-00907: missing right parenthesis

I'm trying to run this snipped of SQL in Oracle Apex and keep receiving errors about right parenthesis. I have tried to remove the constraints or alter the tables later, but I keep coming up with the same sort of errors. I cannot seem to figure out what it is that's wrong with the table structure, and I can't find anything online about it that makes sense. Any help would be much appreciated, thanks. Code below...
DROP TABLE Employee_T
CASCADE CONSTRAINTS;
DROP TABLE TaxDepartment_T
CASCADE CONSTRAINTS;
DROP TABLE Location_T
CASCADE CONSTRAINTS;
CREATE TABLE Employee_T
(
EmployeeID NUMBER(11) NOT NULL,
EmployeeName VARCHAR2(25) NOT NULL,
EmployeeAddress VARCHAR2(30) ,
EmployeeCity VARCHAR2(20) ,
EmployeeState CHAR(2) ,
EmployeePostalCode VARCHAR2(10) ,
CONSTRAINT Employee_PK PRIMARY KEY(EmployeeID),
CONSTRAINT Employee_FK1 FOREIGN KEY(DepartmentID) REFERENCES (TaxDepartment_T),
CONSTRAINT Employee_FK2 FOREIGN KEY(BranchID) REFERENCES (Location_T)
);
CREATE TABLE TaxDepartment_T
(
DepartmentID INTEGER(11) NOT NULL,
BranchID INTEGER(11) NOT NULL,
CPAID INTEGER(11) NOT NULL,
EmployeeID INTEGER(11) NOT NULL,
BranchName VARCHAR2(50) NOT NULL,
CONSTRAINT TaxDepartment_PK PRIMARY KEY(DepartmentID, BranchID, CPAID),
CONSTRAINT TaxDepartment_FK1 FOREIGN KEY(BranchID) REFERENCES (Location_T),
CONSTRAINT TaxDepartment_FK2 FOREIGN KEY(EmployeeID) REFERENCES (Employee_T)
);
CREATE TABLE Location_T
(
BranchID INTEGER(11) NOT NULL,
BranchName VARCHAR2(50) NOT NULL,
ManagerName VARCHAR2(50) NOT NULL,
EmployeeID INTEGER(11) NOT NULL,
CONSTRAINT Location_PK PRIMARY KEY(BranchID),
CONSTRAINT Location_FK1 FOREIGN KEY(EmployeeID) REFERENCES (Employee_T)
);
Your foreign key constraint syntax is off.
What it should look like:
REFERENCES SCHEMA.TABLE (COLUMN)
and you just have:
REFERENCES (COLUMN)
If you look at this code in SQL Developer, the parser catches your issue right away, and even gives you a simple click to get to the Docs with syntax diagram for defining FK constraints.
This is your FIRST problem.
The fun with bugs is killing one only exposes the next one. You can't create FK constraints for tables you haven't created yet. So either you need to create the base tables first, OR you need to remove the FK constraints from your CREATE TABLE calls, and add them back later as
alter table TABLE_NAME add constraint CONSTRAINT_NAME foreign key(COLUMN_NAME) references TABLE_NAME2(COLUMN_NAME)
Place all of these ALTER TABLE ADD CONSTRAINT calls at the end of your script, once all the tables have already been created.
Someone else has also noticed that you're using INTEGER.
Which I do, ALL THE TIME...because I'm too lazy to type 'NUMBER(38,0)'
That's fine. But what you can't do is say INTEGER(9). That makes no sense in Oracle.
You should use NUMBER instead of INTEGER in TaxDepartment_T and Location_T tables
There are a few syntax issues.
integer is OK but not integer(11). Use number(11). (Also, while char is a valid type, you should stick to the standard varchar2 for strings to avoid unexpected behaviour.)
Foreign key constraints are written constraint fk references tablename, or optionally you can specify the referenced column in brackets: constraint fk references tablename (columnname). (Also if you write them inline as part of the column definition, you can let the datatype inherit from the parent.)
Employee FK1 and FK2 refer to DepartmentID and BranchID columns that the table doesn't have.
You need to put the parent before the child if you want to run it as a script.
I would write it like this:
drop table employee_t cascade constraints;
drop table taxdepartment_t cascade constraints;
drop table location_t cascade constraints;
create table Location_T
( BranchID number(11) not null constraint Location_PK primary key
, BranchName varchar2(50) not null
, ManagerName varchar2(50) not null );
create table TaxDepartment_T
( DepartmentID number(11) not null
, BranchID constraint TaxDepartment_Location_FK references location_t not null
, CPAID number(11) not null
, BranchName varchar2(50) not null
, constraint TaxDepartment_PK primary key(DepartmentID, BranchID, CPAID) );
create table Employee_T
( EmployeeID number(11) not null constraint Employee_PK primary key
, EmployeeName varchar2(25) not null
, EmployeeAddress varchar2(30)
, EmployeeCity varchar2(20)
, EmployeeState varchar2(2)
, EmployeePostalCode varchar2(10)
, DepartmentID constraint Employee_Department_FK references location_t
, BranchID constraint Employee_Branch_FK references Location_T );
I don't think Location or Tax Department should have EmployeeId columns so I removed them - say if you think that's wrong.
Personally I wouldn't put _T on the end of my table names, and I would avoid camelCase naming because the data dictionary doesn't retain it, and so describing a table gives for example:
SQL> #desc location_t
Name Null? Type
----------------------------------------- -------- ----------------------------
BRANCHID NOT NULL NUMBER(11)
BRANCHNAME NOT NULL VARCHAR2(50)
MANAGERNAME NOT NULL VARCHAR2(50)

foreign or primary keys ORA-02270, i can not insert a table

I have the following code and it indicates the error ORA-02270
CREATE TABLE SEDE(
SEDE VARCHAR2(50) NOT NULL,
CAMPUS VARCHAR2(50),
CONSTRAINT PK_SEDE PRIMARY KEY(SEDE)
);
---------------------------------------------
CREATE TABLE DEPARTAMENTO(
NOMBRE VARCHAR2(50) NOT NULL,
SEDE VARCHAR2(50) NOT NULL,
TELEFONO VARCHAR2(10),
DIRECTOR INT,
CONSTRAINT PK_DEPARTAMENTO PRIMARY KEY(NOMBRE,SEDE)
);
---------------------------------------------
***HERE IS THE PROBLEM****
CREATE TABLE UBICACION(
NOMBRE_SEDE VARCHAR2(50) NOT NULL,
NOMBRE_DEPTO VARCHAR2(50) NOT NULL,
CONSTRAINT PK_UBICACION PRIMARY KEY(NOMBRE_SEDE,NOMBRE_DEPTO),
CONSTRAINT FK_UBICACION FOREIGN KEY(NOMBRE_SEDE) REFERENCES SEDE(SEDE) ON DELETE CASCADE,
CONSTRAINT FK_UBICACION2 FOREIGN KEY(NOMBRE_DEPTO) REFERENCES DEPARTAMENTO(NOMBRE) ON DELETE CASCADE
);
EDIT: More code to answer a question.
CREATE TABLE GRUPO(
NOMBRE VARCHAR2(50) NOT NULL,
AREA_CONOCIMIENTO VARCHAR2(50),
NOMBRE_DEPTO VARCHAR2(50),
LIDER INT,
CONSTRAINT PK_GRUPO PRIMARY KEY(NOMBRE,NOMBRE_DEPTO)
);
---------------------------------------------
CREATE TABLE PROFESOR(
DNI INT NOT NULL,
NOMBRE VARCHAR2(50),
TITULACION VARCHAR2(50),
ANIOS_EXP INT,
GRUPO_PARTICIPA VARCHAR2(50),
CONSTRAINT PK_PROFESOR PRIMARY KEY(DNI)
);
ALTER TABLE DEPARTAMENTO ADD CONSTRAINT FK_DEPARTAMENTO FOREIGN KEY(DIRECTOR) REFERENCES PROFESOR(DNI) ON DELETE CASCADE;
** HERE IS PROBLEM TOO***
ALTER TABLE GRUPO ADD CONSTRAINT FK_GRUPO FOREIGN KEY(NOMBRE_DEPTO) REFERENCES DEPARTAMENTO(NOMBRE) ON DELETE CASCADE;
ALTER TABLE GRUPO ADD CONSTRAINT FK_GRUPO2 FOREIGN KEY(LIDER) REFERENCES PROFESOR(DNI) ON DELETE CASCADE;
Informe de error -
ORA-02270: no matching unique or primary key for this column-list
02270. 00000 - "no matching unique or primary key for this column-list"
*Cause: A REFERENCES clause in a CREATE/ALTER TABLE statement
gives a column-list for which there is no matching unique or primary
key constraint in the referenced table.
*Action: Find the correct column names using the ALL_CONS_COLUMNS
catalog view
What do i have to do?
thanks in advance
THIS QUESTION ADDRESSES THE ORIGINAL QUESTION.
The primary key on departmento has two parts. If you want a foreign key relationship, you need to reference both of them:
CREATE TABLE UBICACION(
NOMBRE_SEDE VARCHAR2(50) NOT NULL,
NOMBRE_DEPTO VARCHAR2(50) NOT NULL,
CONSTRAINT PK_UBICACION PRIMARY KEY(NOMBRE_SEDE,NOMBRE_DEPTO),
CONSTRAINT FK_UBICACION FOREIGN KEY(NOMBRE_SEDE) REFERENCES SEDE(SEDE) ON DELETE CASCADE,
CONSTRAINT FK_UBICACION2 FOREIGN KEY(NOMBRE_DEPTO, NOMBRE_SEDE) REFERENCES DEPARTAMENTO(NOMBRE, SEDE) ON DELETE CASCADE
);
Here is a SQL Fiddle.
You have to take a second look at your design. If DEPARTMENTO has a Composite Primary Key (2 columns), a Foreign Key reference to it cannot be for a single column alone -- because the single column alone cannot guarantee uniqueness.

Oracle: Many to Many: Requires two Foreign Key Constraints?

Im very new to SQL and i tried to create a many to many relationship:
CREATE TABLE HOUSE_USER
(
USER_ID NUMBER(10) NOT NULL,
USER_EMAIL VARCHAR(255) NOT NULL,
USER_PASSWORD VARCHAR(255) NOT NULL,
CONSTRAINT USER_PK PRIMARY KEY(USER_ID),
CONSTRAINT PROFILE_FK FOREIGN KEY(PROFILE_ID) REFERENCES HOUSE_PROFILE(PROFILE_ID)
);
CREATE TABLE HOUSE_USER_GROUPE
(
USER_GROUPE_ID NUMBER(10) NOT NULL,
USER_GROUPE_NAME VARCHAR(255) NOT NULL,
CONSTRAINT USER_GROUPE_PK PRIMARY KEY(USER_GROUPE_ID)
);
CREATE TABLE HOUSE_USER_USER_GROUPE
(
USER_ID NUMBER(10) NOT NULL,
USER_GROUPE_ID NUMBER(10) NOT NULL,
CONSTRAINT USER_USER_GROUPE_PK PRIMARY KEY(USER_ID, USER_GROUPE_ID),
CONSTRAINT USER_FK FOREIGN KEY(USER_ID) REFERENCES HOUSE_USER(USER_ID),
CONSTRAINT USER_GROUPE_FK FOREIGN KEY(USER_GROUPE_ID) REFERENCES HOUSE_USER_GROUPE(USER_GROUPE_ID)
);
I need to ask now if these two constraints:
CONSTRAINT USER_FK FOREIGN KEY(USER_ID) REFERENCES HOUSE_USER(USER_ID),
CONSTRAINT USER_GROUPE_FK FOREIGN KEY(USER_GROUPE_ID) REFERENCES
are neccessary or not. I ask because i have another many to many relationship:
CREATE TABLE HOUSE_USER_GROUPE
(
USER_GROUPE_ID NUMBER(10) NOT NULL,
USER_GROUPE_NAME VARCHAR(255) NOT NULL,
CONSTRAINT USER_GROUPE_PK PRIMARY KEY(USER_GROUPE_ID)
);
CREATE TABLE HOUSE_ACCESSR
(
ACCESSR_ID NUMBER(10) NOT NULL,
ACCESSR_NAME VARCHAR(255) NOT NULL,
CONSTRAINT ACCESSR_PK PRIMARY KEY(ACCESSR_ID)
);
CREATE TABLE HOUSE_USER_GROUPE_ACCESR
(
USER_GROUPE_ID NUMBER(10) NOT NULL,
ACCESSR_ID NUMBER(10) NOT NULL,
CONSTRAINT USER_GROUPE_ACCESSR_PK PRIMARY KEY(USER_GROUPE_ID, ACCESSR_ID),
CONSTRAINT USER_GROUPE_FK FOREIGN KEY(USER_GROUPE_ID) REFERENCES HOUSE_USER_GROUPE(USER_GROUPE_ID),
CONSTRAINT ACCESSR_FK FOREIGN KEY(ACCESSR_ID) REFERENCES HOUSE_ACCESSR(ACCESSR_ID)
);
I cant create the second many to many table because i already used the constraint:
CONSTRAINT USER_GROUPE_FK FOREIGN KEY(USER_GROUPE_ID) REFERENCES HOUSE_USER_GROUPE(USER_GROUPE_ID),
I could just rename it but because of that error:
ORA-02264: name already used by an existing constraint
I just was wondering if these constraints are mandatory.
Yes, you should create the foreign key constrain on both tables.
The foreign key constraints are there to maintain referential integrity; ensuring that you can't insert values that don't exist in the parent table.
If you don't add the constraint to HOUSE_USER_GROUPE_ACCESR then you don't get that protection in that table. And you should want that protection everywhere.
Your only apparent mistake is that the constraint names are identical to each other. I traditionally either include No Name (letting Oracle decide on the name, because I never refer to the constraint by name) or use a format something like fk_<table>_<field>.
You need to do the constraints.. create the second constraints with another name.

foreign key Oracle

I'm working with Oracle Database and I have this script :
create table Guardians (
noCage number(3),
nomE varchar2(20),
CONSTRAINT nc_ne1 PRIMARY KEY(noCage, nomE)
);
create table Animals(
nomA varchar2(20) PRIMARY KEY,
type varchar2(15) NOT NULL,
country varchar2(20) NOT NULL,
noCage number(3),
CONSTRAINT fk_anim_cage0 FOREIGN KEY(noCage) REFERENCES Guardians(noCage)
);
Upon executing the script, the table guardians is created, an error is prompted and the table Animals is not created. I did some manipulations and i think that it's got to do with the
CONSTRAINT nc_ne1 PRIMARY KEY(noCage, nomE)
Since Guardians Table has composite primary key you need to include both the columns in foreign key.
CONSTRAINT fk_anim_cage0 FOREIGN KEY(noCage,nomA) REFERENCES Guardians(noCage, nomE)
Your Animals table would be like this
create table Animals(
nomA varchar2(20) PRIMARY KEY,
type varchar2(15) NOT NULL,
country varchar2(20) NOT NULL,
noCage number(3),
CONSTRAINT fk_anim_cage0 FOREIGN KEY(noCage,nomA)
REFERENCES Guardians(noCage, nomE)
);

how do i cascade updates and deletions in oracle?

I'm trying to follow the examples in my book to cascade updates and deletions but the problem is their syntax doesnt work in oracle DB..
I understand to cascade an update would mean an update to a parent would also update its child and same with deletions.. but i cant figure out the syntax for oracle.. the specific questions from my book are:
7.5 -- Write a CREATE TABLE statement for the EMPLOYEE table. Email is
required and is an alternate key, and the default value of Department is
Human Resources. Cascade updates but not deletions from DEPARTMENT to EMPLOYEE.
7.6 -- Write a CREATE TABLE statement for PROJECT table. The default value for
MaxHours is 100. Cascade updates but not deletions from DEPARTMENT to EMPLOYEE.
7.7 -- Write a CREATE TABLE statement for the ASSIGNMENT table. Cascade only
deletions from PROJECT to ASSIGNMENT; do not cascade either deletions or
updates from EMPLOYEE to ASSIGNMENT.
I finally managed to successfully created these tables in iSQL *Plus with this Query:
CREATE TABLE DEPARTMENT (
DepartmentName char(35) NOT NULL,
BudgetCode char(30) NOT NULL,
OfficeNumber char(15) NOT NULL,
Phone char(12) NOT NULL,
Constraint DepartmentPK PRIMARY KEY(DepartmentName)
);
INSERT INTO DEPARTMENT VALUES (
'Administration', 'BC-100-10', 'BLDG01-300', '360-285-8100');
CREATE TABLE EMPLOYEE (
EmployeeNumber int NOT NULL,
FirstName char(25) NOT NULL,
LastName char(25) NOT NULL,
Department char(35) DEFAULT 'Human Resources' NOT NULL,
Phone char(12) NULL,
Email char(30) NOT NULL,
DepartmentName_FK char(35) NOT NULL,
Constraint EmployeePK PRIMARY KEY(EmployeeNumber),
Constraint EmployeeAK1 UNIQUE(Email),
Constraint DepartmentFK FOREIGN KEY (DepartmentName_FK)
references DEPARTMENT(DepartmentName)
--ON UPDATE CASCADE
--ON DELETE no ACTION
);
CREATE TABLE PROJECT (
ProjectID int NOT NULL,
Name char(30) NOT NULL,
Department1 char(15) NOT NULL,
MaxHours int DEFAULT 100 NOT NULL,
StartDate DATE NULL,
EndDate DATE NULL,
DepartmentName_FK1 char(30) NULL,
Constraint datecheck check (StartDate < EndDate),
Constraint ProjectIDPK PRIMARY KEY(ProjectID),
Constraint DepartmentFK1 FOREIGN KEY (DepartmentName_FK1)
references DEPARTMENT(DepartmentName)
-- ON UPDATE CASCADE
-- ON DELETE no ACTION
);
CREATE TABLE Assignment(
ProjectID Number NOT NULL,
EmployeeNumber Number NOT NULL,
HoursWorked Number NULL,
Constraint ProjectIDEmpNumPK PRIMARY KEY(ProjectID, EmployeeNumber),
constraint ProjectIDFK FOREIGN KEY(ProjectID)
references Project(ProjectID),
constraint EmpNumFK FOREIGN KEY(EmployeeNumber)
references Employee(EmployeeNumber)
--CONSTRAINT UniqueEmployee UNIQUE (EmployeNumber)
--ON DELETE CASCADE
);
but how do I specify cascading delete and update and specify not to?
Did you try this?
CREATE TABLE Assignment(
ProjectID Number NOT NULL,
EmployeeNumber Number NOT NULL,
HoursWorked Number NULL,
Constraint ProjectIDEmpNumPK PRIMARY KEY(ProjectID, EmployeeNumber),
constraint ProjectIDFK FOREIGN KEY(ProjectID)
references Project(ProjectID)
ON DELETE CASCADE
ON UPDATE no ACTION ,
constraint EmpNumFK FOREIGN KEY(EmployeeNumber)
references Employee(EmployeeNumber)
ON DELETE no ACTION
ON UPDATE no ACTION
);