On DELETE CASCADE not working in snowflake - ddl

I have two tables:
CREATE TABLE category(
id INTEGER NOT NULL DEFAULT CATEGORY_SEQUENCE.NEXTVAL,
name VARCHAR(50),
PRIMARY KEY(id)
);
CREATE TABLE product(
id INTEGER NOT NULL DEFAULT PRODUCT_SEQUENCE.NEXTVAL,
name VARCHAR(50),
id_category INTEGER REFERENCES category(id) ON DELETE CASCADE ON UPDATE CASCADE,
PRIMARY KEY(id)
);
When I DELETE FROM category, the products do not get deleted.
What am I doing wrong?

Thing is Snowflake doesn't really service constraints other than not null. It will have them (as in store somewhere) but not really enforce - which means your cascade won't work.
reference:
https://docs.snowflake.com/en/sql-reference/constraints-overview.html

Related

drop foreign key constraint on DB2 table through alter table

I have a DB2 (for IBMi) table created as below. I would like to drop the forign key constraint while running in an SQLRPGLE program. Is this possible?
create table grid_action_details(id integer not null
generated always as identity
(start with 1 increment by 1)
PRIMARY KEY,grid_details_id integer,foreign key(grid_details_id)
references grid_details(id),action_code_details_id integer,
foreign key(action_code_details_id)
references action_code_details(id),action_code_status varchar(2),
created_date date default
current_date,created_by varchar(30),
last_updated_date date default current_date,updated_by
varchar(30),required_parameter clob);
I tried the below syntax but it just doesn't seem to work for me:
ALTER TABLE table-name
DROP FOREIGN KEY foreign_key_name
alter table iesqafile.grid_action_details
drop foreign key action_code_details_id
ACTION_CODE_DETAILS_ID in IESQAFILE type *N not found.
You drop the FK constraint via name, not via column.
Since you didn't specify one during create, you'll need to look to see what name the system generated.
Always a best practice to name things yourself.
CONSTAINT <name> FOREIGN KEY (<columns>)
create table grid_action_details (
id integer not null generated always as identity (
start with 1 increment by 1
)
,constraint grid_action_details_pk
primary key
,grid_details_id integer
,constraint grid_details_fk
foreign key (grid_details_id)
references grid_details (id)
,action_code_details_id integer
,constraint action_code_details_fk
foreign key (action_code_details_id)
references action_code_details (id)
,action_code_status varchar(2)
,created_date date default current_date
,created_by varchar(30)
,last_updated_date date default current_date
,updated_by varchar(30)
,required_parameter clob
);
Now you can drop by the known name
alter table iesqafile.grid_action_details
drop foreign key action_code_details_fk
EDIT
To find the generated name use:
the ACS Schema component
DSPFD
SQL against one of the catalog views (QSYS2.SYSCST, SYSIBM.SQLFOREIGNKEYS, SYSIBM.REFERENTIAL_CONSTRAINTS )

want to link crew Assignment to above tables given I'm getting an error How to solve this error?

CREATE TABLE Route(
RouteNo VARCHAR(10),
Origin VARCHAR(30),
Destination VARCHAR(30),
DepartureTime VARCHAR(15),
SerialNo VARCHAR(5),
ArrivalTime VARCHAR(15),
PRIMARY KEY(RouteNo) );
CREATE TABLE Employee(
EmployeeID VARCHAR(5) NOT NULL,
Name VARCHAR(30),
Phone NUMBER,
JobTitle VARCHAR(30),
PRIMARY KEY(EmployeeID) );
CREATE TABLE Flight(
SerialNo VARCHAR(5),
RouteNo VARCHAR(5),
FlightDate DATE,
ActualTD VARCHAR(10),
ActualTA VARCHAR(10),
PRIMARY KEY(SerialNo, RouteNo, FlightDate),
FOREIGN KEY(RouteNo) REFERENCES Route(RouteNo),
FOREIGN KEY(SerialNo) REFERENCES Airplane(SerialNo) ); -- does Airplane table exists ?
CREATE TABLE CrewAssigment(
EmployeeID VARCHAR(5),
RouteNo VARCHAR(5),
FlightDate DATE,
Role VARCHAR(45),
Hours INT,
PRIMARY KEY(EmployeeID, RouteNo, FlightDate),
FOREIGN KEY(EmployeeID) REFERENCES Employee(EmployeeID),
FOREIGN KEY(RouteNo) REFERENCES Route(RouteNo),
FOREIGN KEY(FlightDate) REFERENCES Flight(FlightDate) );
Select * from CrewAssignment
This is my code where I'm getting an error in the CrewAssignment table and above are the tables where the foreign key is referenced from.
Error report -
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
A few objections.
This is clearly an Oracle question, not MySQL. How do I know? ORA-02270 is an Oracle database error code; pay attention to tags you use.
You should use VARCHAR2 datatype instead of VARCHAR. Why? Oracle recommends so.
create table flight fails first as it references the airplane table, and it doesn't exist yet (at least, not in code you posted)
error you're complaining about is due to create table crewassignment. One of its foreign keys references the flight table:
FOREIGN KEY(flightdate) REFERENCES flight(flightdate)
but flight's primary key is composite, made up of 3 columns:
PRIMARY KEY(serialno,
routeno,
flightdate)
which means that you can't create that foreign key.
So, what to do? No idea, I don't know rules responsible for such a data model. Either modify primary key of the flight table, or modify foreign key constraint of the crewassingment table.
Perhaps you could add a new column to flight table (made up of a sequence (or identity column, if your database version supports it) and then let the crewassignment table reference that primary key. Columns you currently use as a primary key (serialno, routeno, flightdate) would then switch to unique key.

Do I need to drop a foreign key on one table to delete a row on another using oracle?

I have two tables
Parent table
(account_number varchar(15) not null,
branch_name varchar(50) not null,
balance number not null,
primary key(account_number));
Child table
account_number varchar(15) not null,
foreign key(account_number) references parent table(account_number));
I am trying this:
DELETE FROM parent table
WHERE balances > 1000;
I am deleting accounts by balances on the parent but I get an error message about the child relationship.
My assumption is a DELETE CASCADE has to be added to the foreign key in the child table. All the documentation shows how to alter the table when the constraint is named. I do not have that situation. Is there a way to do it, or do I have to specify the cascade in the delete statement I am writing?
Every constraint in Oracle has a name. If a name isn't specified when the constraint is created, Oracle will autogenerate a name for the constraint. If you don't know what the name of a constraint is, try running a SQL statement that violates the constraint and reading the constraint name from the error message:
SQL> delete from parent where account_number = 1234;
delete from parent where account_number = 1234
*
ERROR at line 1:
ORA-02292: integrity constraint (LUKE.SYS_C007357) violated - child record
found
In this case the name of the constraint is SYS_C007357.
If that doesn't work, you can query the data dictionary view user_constraints:
SQL> select constraint_name from user_constraints where table_name = 'CHILD' and constraint_type = 'R';
CONSTRAINT_NAME
------------------------------
SYS_C007357
As far as I can tell, you can't modify a foreign key constraint to enable ON DELETE CASCADE. Instead you must drop the constraint and recreate it.
I don't believe you can apply the CASCADE option to a DELETE statement either, but you can delete the child rows before deleting from the parent:
DELETE FROM child
WHERE account_number IN (SELECT account_number FROM parent WHERE balance > 1000);
DELETE FROM parent
WHERE balance > 1000;
However, I don't know how many other tables you have with foreign key constraints referencing your parent table, nor in how many places you are deleting from the parent table, so I can't say how much work it would be to use this approach.
yes you can set DELETE CASCADE
see more info here FOREIGN KEYS WITH CASCADE DELETE
CREATE TABLE table_name
(
column1 datatype null/not null,
column2 datatype null/not null,
...
CONSTRAINT fk_column
FOREIGN KEY (column1, column2, ... column_n)
REFERENCES parent_table (column1, column2, ... column_n)
ON DELETE CASCADE
);
for example
CREATE TABLE supplier
( supplier_id numeric(10) not null,
supplier_name varchar2(50) not null,
contact_name varchar2(50),
CONSTRAINT supplier_pk PRIMARY KEY (supplier_id)
);
CREATE TABLE products
( product_id numeric(10) not null,
supplier_id numeric(10) not null,
CONSTRAINT fk_supplier
FOREIGN KEY (supplier_id)
REFERENCES supplier(supplier_id)
ON DELETE CASCADE
);

Can two or more tables which share same foreign keys share a constraint on that foreign key?

What is the problem with this code??
It gives error "name already used by another constraint". Also if I can't define same constraint in different tables then is there any way I can reuse the previously defined constraint?
Any insight??
CREATE TABLE tbl_formats
(
format_id NUMBER(5),
format_name VARCHAR2(50),
format_desc VARCHAR2(100),
valid_from DATE,
valid_to DATE,
format_type VARCHAR2(50),
CONSTRAINT pk_format_id PRIMARY KEY(format_id)
);
CREATE TABLE tbl_format_detail
(
id NUMBER(10),
format_id NUMBER(5),
src_field VARCHAR2(200),
target_field VARCHAR2(100),
business_rule VARCHAR2(4000),
expression VARCHAR2(4000),
target_segment VARCHAR2(4),
CONSTRAINT pk_id PRIMARY KEY(id),
CONSTRAINT fk_format_id FOREIGN KEY(format_id) REFERENCES tbl_formats(format_id)
);
CREATE TABLE tbl_client_formats
(
client_format_id NUMBER(10),
format_id NUMBER(5),
client_id NUMBER(5),
CONSTRAINT pk_client_format_id PRIMARY KEY(client_format_id),
CONSTRAINT fk_format_id FOREIGN KEY(format_id) REFERENCES tbl_formats(format_id),
CONSTRAINT fk_client_id FOREIGN KEY(client_id) REFERENCES tbl_clients(client_id)
);
It seem like the foreign key constraint 'fk_format_id' defined in the table 'tbl_client_formats' conflicts with the same constraint already defined in the table 'tbl_format_detail'.
I am new to oracle so explain even the obvious things please.
The problem is that you're trying to use the same constraint name twice.
Just use a different name for your second constraint (e.g. fk_client_formats_format_id), and you should be fine.
Generally, I'd recommend using the table name as part of the constraint name, to avoid name clashes (if the constraint name gets too long, you'll have to use some kind of abbreviation scheme).
Foreign key are stored in a database range, not a table range. You cannot have two FK with the same name on the same database, even if they are not in the same table. You could name your FK that way:
FK_PARENT_CHILD_FIELD
ex:
FK_FORMATDETAILS_FORMATS_ID,
FK_CLIENTFORMATS_FORMATS_ID,
FK_CLIENTFORMATS_CLIENT_ID

Oracle foreign key relation

I have a composite primary key in my Candidate table
CREATE TABLE CANDIDATE(
CANDIDATE_ID VARCHAR(5),
NAME VARCHAR(30),
TELEPHONE NUMBER,
PRIMARY KEY(CANDIDATE_ID, NAME));
When I create a child table, I get an error saying the number of referencing columns must match referenced columns when I create a foreign key for the CANDIDATE_ID
CREATE TABLE JOB(
POSITION_ID VARCHAR(5) PRIMARY KEY,
CANDIDATE_ID VARCHAR(5),
DATE2 DATE,
FOREIGN KEY(CANDIDATE_ID) REFERENCES CANDIDATE);
A table can only have one primary key-- you have a composite primary key. If you have a composite primary key, you have to reference the entire key in your child table. That would mean that the child table would need to have a CANDIDATE_ID column and a NAME column.
CREATE TABLE job (
position_id VARCHAR2(5) PRIMARY KEY,
candidate_id VARCHAR2(5),
name VARCHAR2(30),
date2 DATE,
FOREIGN KEY( candidate_id, name ) REFERENCES candidate( candidate_id, name )
);
Of course, you probably don't want to store the name in both tables. You probably want the candidate_id to be the prmiary key of candidate and you may want to create a separate unique constraint on name.
CREATE TABLE CANDIDATE(
CANDIDATE_ID VARCHAR(5) primary key,
NAME VARCHAR(30) unique,
TELEPHONE NUMBER);
CREATE TABLE JOB(
POSITION_ID VARCHAR(5) PRIMARY KEY,
CANDIDATE_ID VARCHAR(5),
DATE2 DATE,
FOREIGN KEY(CANDIDATE_ID) REFERENCES CANDIDATE(candidate_id));
Assuming that the combination of CANDIDATE_ID and NAME is required for the key to be unique, then you will need to add a reference to the NAME column in your referencing table.
I suspect that CANDIDATE_ID is enough to uniquely identify the candidates in your primary table. If that is the case then it should be your primary key and your relationship will work. If you want to index the NAME separately then do so, but leave it out of the primary key.
Last line should be like this;
CONSTRAINT FK_CANDIDATE_ID FOREIGN KEY (CANDIDATE_ID)REFERENCES CANDIDATE(CANDIDATE_ID);
CREATE TABLE dept
( did char(3) not null,
dname varchar2(20) not null,
CONSTRAINT dept_pk PRIMARY KEY (did)
);
strong text
create table emp
(
eid char(3) unique,
ename varchar2(10) not null,
sal number check (sal between 20000 AND 50000),
city varchar2(10) default 'texus',
did char(3) not null,
constraint fk_did_dept
FOREIGN KEY (did) references
dept(did)
);

Resources