SQL ALTER TABLE ON DELETE CASCADE - sql

I have the following tables:
CREATE TABLE BOOK_AUTHORS
(Book_id CHAR(20) NOT NULL,
AuthorName VARCHAR(30) NOT NULL,
PRIMARY KEY (Book_id, AuthorName),
FOREIGN KEY (Book_id) REFERENCES BOOK (Book_id));
CREATE TABLE BOOK_COPIES
(Book_id CHAR(20) NOT NULL,
Branch_id CHAR(20) NOT NULL,
No_of_copies NUMBER,
PRIMARY KEY (Book_id, Branch_id),
FOREIGN KEY (Book_id) REFERENCES BOOK (Book_id),
FOREIGN KEY (Branch_id) REFERENCES LIBRARY_BRANCH (Branch_id));
I want to add ON DELETE CASCADE constraints to the both of them:
The first time I tried it said it worked. That file looks like:
ALTER TABLE "BOOK_AUTHORS"
ADD CONSTRAINT "fk_test"
FOREIGN KEY ("Book_id")
REFERENCES "BOOK" ("Book_id")
ON DELETE CASCADE;
Then I went through and made two separate tables for the two foreign keys in the second table:
ALTER TABLE "BOOK_COPIES"
ADD CONSTRAINT "fk_test1"
FOREIGN KEY ("Book_id")
REFERENCES "BOOK" ("Book_id")
ON DELETE CASCADE;
ALTER TABLE "BOOK_COPIES"
ADD CONSTRAINT "fk_test2"
FOREIGN KEY ("Branch_id")
REFERENCES "LIBRARY_BRANCH" ("Branch_id")
ON DELETE CASCADE;
However, upon doing so I got the errors
"Book_id" invalid identifier
and then
"Branch_id" invalid identifier
I don't know what I did wrong. I then went back and did the first alter table again (the one that I originally thought worked) and it gave me the same error message ("Book_id" invalid identifier). Can someone help me add these constraints? I also have five other tables to add these constraints to.

If you put double quotes around your identifiers (like you did in
ALTER TABLE "BOOK_COPIES"
ADD CONSTRAINT "fk_test1"
FOREIGN KEY ("Book_id")
REFERENCES "BOOK" ("Book_id")
ON DELETE CASCADE;
) your identifiers (e.g. "Book_id" in this case) become case-sensitive.
So either you'll have to change your table definition and rename the column to "Book_id" or (much preferably IMHO) just get rid of the double quotes in your constraint definition:
ALTER TABLE BOOK_COPIES
ADD CONSTRAINT fk_test1
FOREIGN KEY (Book_id)
REFERENCES BOOK (Book_id)
ON DELETE CASCADE;

First of all let me clear one thing, You cant add on delete cascade to an already existing foreign key constraint, as shown in docs you can only change its state which means enable or disable, in case if you need to add then drop the constraint first. This question is asked twice and still repeating please moderators have a glance on this. Here are links that has already solved your problem. first , second and this third and who knows how many questioned asked on on delete cascade.

Put doublequotes (") around your table and column names.
I added table "BOOK" and table "LIBRARY_BRANCH":
CREATE TABLE "BOOK"
("Book_id" CHAR(20) NOT NULL,
"BookName" VARCHAR(30) NOT NULL,
PRIMARY KEY ("Book_id"));
CREATE TABLE "BOOK_AUTHORS"
("Book_id" CHAR(20) NOT NULL,
"AuthorName" VARCHAR(30) NOT NULL,
PRIMARY KEY ("Book_id", "AuthorName"));
CREATE TABLE "LIBRARY_BRANCH"
("Branch_id" CHAR(20) NOT NULL,
"Branch_name" VARCHAR(50),
"Address" VARCHAR(100),
PRIMARY KEY ("Branch_id"));
CREATE TABLE "BOOK_COPIES"
("Book_id" CHAR(20) NOT NULL,
"Branch_id" CHAR(20) NOT NULL,
"No_of_copies" NUMBER,
PRIMARY KEY ("Book_id", "Branch_id"));
ALTER TABLE "BOOK_AUTHORS"
ADD CONSTRAINT "fk_test"
FOREIGN KEY ("Book_id")
REFERENCES "BOOK" ("Book_id")
ON DELETE CASCADE;
ALTER TABLE "BOOK_COPIES"
ADD CONSTRAINT "fk_test1"
FOREIGN KEY ("Book_id")
REFERENCES "BOOK" ("Book_id")
ON DELETE CASCADE;
ALTER TABLE "BOOK_COPIES"
ADD CONSTRAINT "fk_test2"
FOREIGN KEY ("Branch_id")
REFERENCES "LIBRARY_BRANCH" ("Branch_id")
ON DELETE CASCADE;
sqlfiddle demo

Related

Postgresql foreign key as primary not unique?

So i have a table, that takes a nickname as foreign key and a id to form a primary key:
CREATE TABLE Character(
Nickname TEXT,
CONSTRAINT person_pk PRIMARY KEY(Nickname)
);
CREATE TABLE POSTING(
PostingID BIGINT UNIQUE,
Nickname TEXT,
CONSTRAINT posting_fk FOREIGN KEY(Nickname) REFERENCES Person(Nickname),
CONSTRAINT postings_pk PRIMARY KEY(PostingID, Nickname)
);
So far, so good. However, whenever i try to get now the primary key from posting, it tells me that: " there is no unique constraint matching given keys for referenced table "information"".
CREATE TABLE INFORMATION(
InformationID BIGINT,
PostingID BIGINT,
CONSTRAINT informations_fk FOREIGN KEY(PostingID) REFERENCES POSTING(PostingID),
CONSTRAINT informations_pk PRIMARY KEY(InformationID, PostingID)
);
CREATE TABLE DATA(
InformationID BIGINT,
Link TEXT NOT NULL,
CONSTRAINT data_fk FOREIGN KEY(InformationID) REFERENCES INFORMATION(InformationID),
CONSTRAINT datas_pk PRIMARY KEY(InformationID)
);
However, if i change in the table Information the InformationID to unique, the error disappears. Is that the correct way of doing things?
CREATE TABLE INFORMATION(
InformationID BIGINT UNIQUE,
PostingID BIGINT,
CONSTRAINT informations_fk FOREIGN KEY(PostingID) REFERENCES POSTING(PostingID),
CONSTRAINT informations_pk PRIMARY KEY(InformationID, PostingID)
);
Thanks in advance everyone!
Either the primary key for information should be only informationid, or data must include postingid and the foreign key to information is defined on both columns.
Hard to say without knowing your data, but I suspect the former solution to be the correct one.

Create table with foreign key to an other table created below in sql file

My problem is that i have two tables with each table having a foreign key to the other table.
Each time , i execute the SQL file containing the creation of the two tables, it gives me an error that he doesn't find the other table. I'm working with sqlplus to execute the sql file.
Here's an example of SQL file i tried with :
create table A(
Age number(3),
name number(3) constraint A_FK references B(name))
/
create table B(
Age number(3) constraint B_FK references A(Age),
name number(3))
And even if i reverse the order, it gives the same error.
Thanks for help.
This is a problem of cycles in foreign keys. One method is to add all foreign keys after table creation (as I think the other answers propose).
You can also just do that for the first table:
create table A (
Age number(3) primary key,
name number(3)
);
create table B (
name number(3) primary key,
Age number(3),
constraint B_FK foreign key (age) references A(Age)
);
alter table B add constraint A_FK foreign key (name) references B(name);
Here is a db<>fiddle.
Notes:
Foreign keys should reference primary keys, so I added that declaration as well.
I recommend making the primary key the first column in the table.
You can also define the constraint inline for one of the tables (i.e. age number(3) constraint b_fk references a(age)).
The table column(s) that is referred by a foreign key must exist at the time when the constraint is created. Since you have some kind of cyclic reference between the tables, you need to do this in three steps:
first create one table without the foreign key
create the second table (with its foreign key)
finally add the foreign key to the first table with an alter table statement
You also need the referred column to have a unique or primary key constraint set up, otherwise you would get error ORA-02270: no matching unique or primary key for this column-list.
create table A(
age number(3) primary key,
name number(3)
);
create table B(
age number(3) constraint B_FK references A(Age),
name number(3) primary key
);
alter table A add constraint A_FK foreign key (name) references B(name);
Demo on DB Fiddle
Side note: I am quite suspicious about your sample structure, but this could be because your oversimplified it in the question.
It fails because the reference table doesn't exist yet.
Create the tables without the key first. Then drop one and recreated it with the reference. Then drop the 2nd and recreate it with the reference.
Create table first and then ADD the CONSTRAINT
ALTER TABLE A
ADD FOREIGN KEY (name) REFERENCES B(name);
ALTER TABLE B
ADD FOREIGN KEY (age) REFERENCES A(age);

Postgresql: Changing Action For Foreign Key Constraint

I have a simple table like below.
create table chemlab.rule_header (
id serial PRIMARY KEY,
name varchar(50),
grade varchar(20),
class_tag varchar(20), --tag added to sammple if match
parent_id int REFERENCES chemlab.rule_header(id) DEFAULT NULL,
unique( grade, class_tag )
)
But afterwards, I found that I need to add ON DELETE action, the default is NO ACTION. I couldn't figure out how to change the action.
Now I have to DROP & ADD
ALTER table chemlab.rule_header
DROP CONSTRAINT rule_header_parent_id_fkey ;
ALTER TABLE rule_header
ADD CONSTRAINT rule_header_parent_id_fkey
FOREIGN KEY (parent_id) REFERENCES chemlab.rule_header(id) ON DELETE RESTRICT;
So what is the correct syntax to alter an action on foreign key constraint ?
Well, this not directly altering FOREIGN KEY constraint, and there are DROP and ADD still, though this is only one statement:
ALTER table chemlab.rule_header
DROP CONSTRAINT rule_header_parent_id_fkey,
ADD CONSTRAINT rule_header_parent_id_fkey
FOREIGN KEY (parent_id) REFERENCES chemlab.rule_header(id) ON DELETE RESTRICT;
Take a look at the documentation at https://www.postgresql.org/docs/current/sql-altertable.html. There are options to alter a few things about a constraint (like DEFERRABLE) but not for changing the action, as I understand you need.

How to add foreign key to an existing column in SQL Server 2012

I am trying to add foreign key to my existing column using below query
ALTER TABLE Sub_Category_Master
ADD FOREIGN KEY (Category_ID) REFERENCES Category_Master(Category_ID)
but I'm getting an error
The ALTER TABLE statement conflicted with the FOREIGN KEY constraint "FK__Sub_Categ__Categ__5812160E". The conflict occurred in database "shaadikarbefikar_new", table "shaadikarbefikar.Category_Master", column 'Category_ID'.
Well, the error clearly tells you that Category_ID in your Sub_Category_Master table contains some values that are not present in Category_Master (column Category_ID). But that's exactly the point of having a foreign key constraint - making sure your child table (Sub_Category_Master) only uses defined values from its parent table.
Therefore, you must fix those "voodoo" values first, before you're able to establish this foreign key relationship. I would also strongly recommend to explicitly name that constraint yourself, to avoid those system-generated, but not really very useful constraint names like FK__Sub_Categ__Categ__5812160E:
ALTER TABLE Sub_Category_Master
ADD CONSTRAINT FK_SubCategoryMaster_CategoryMaster
FOREIGN KEY (Category_ID) REFERENCES Category_Master(Category_ID)
ALTER TABLE Sub_Category_Master
ADD CONSTRAINT FKSub_Category_Master_Category_ID FOREIGN KEY (Category_ID)
REFERENCES Category_Master(Category_ID);
CREATE TABLE Orders
(
OrderID int NOT NULL,
OrderNumber int NOT NULL,
PersonID int,
PRIMARY KEY (OrderID),
CONSTRAINT FK_PersonOrder
FOREIGN KEY (PersonID) REFERENCES Persons(PersonID)
);

How do I make a Table's Attribute a Foreign Key within that Table?

I had to write the SQL to create the tables, attributes, and primary & foreign keys in this ERD:
http://imgur.com/VYZbwr6
In the table 'Financial_Transactions' in the ERD there is a attribute called 'previous_transaction_id' and another attribute called 'transaction_id'. In this table 'previous_transaction_id' is a Foreign Key for this table in addition to being an attribute. It references the last 'transaction_id' in the table.
Here is my SQL for the 'financial_transactions' table:
CREATE TABLE financial_transactions(
transaction_id int IDENTITY(1,1) NOT NULL,
account_id int NOT NULL,
item_rental_id int NOT NULL,
previous_transaction_id int,
transaction_type_code int NOT NULL,
transaction_date date NOT NULL,
transaction_amount money NOT NULL,
transaction_comment varchar(512) NOT NULL);
ALTER TABLE financial_transactions ADD CONSTRAINT pk_financial_transactions PRIMARY KEY (transaction_id);
ALTER TABLE financial_transactions ADD CONSTRAINT fk_financial_transactions_accounts FOREIGN KEY(account_id)
REFERENCES accounts (account_id);
ALTER TABLE financial_transactions ADD CONSTRAINT fk_financial_transactions_customer_rentals FOREIGN KEY(item_rental_id)
REFERENCES customer_rentals (item_rental_id);
ALTER TABLE financial_transactions ADD CONSTRAINT fk_financial_transactions_financial_transactions FOREIGN KEY(previous_transaction_id)
REFERENCES financial_transactions (previous_transaction_id);
ALTER TABLE financial_transactions ADD CONSTRAINT fk_financial_transactions_transaction_types FOREIGN KEY(transaction_type_code)
REFERENCES transaction_types (transaction_type_code);
When I run my SQL (includes statements for each table in the script) I get these errors:
"Msg 1776, Level 16, State 0, Line 87
There are no primary or candidate keys in the referenced table 'financial_transactions' that match the referencing column list in the foreign key 'fk_financial_transactions_financial_transactions'.
Msg 1750, Level 16, State 0, Line 87
Could not create constraint. See previous errors."
All other statements execute normally.
What am I doing wrong?
*I used this statement originally under CREATE TABLE: previous_transaction_id int NOT NULL,
However, it resulted in the same error and when searching I saw a similar question that was fixed by removing the NOT NULL.
Here
ALTER TABLE financial_transactions ADD CONSTRAINT
fk_financial_transactions_financial_transactions
FOREIGN KEY(previous_transaction_id)
REFERENCES financial_transactions (previous_transaction_id);
You have a column referencing itself. Was that your intent or did you want to reference the transaction_id?
There is nothing wrong with defining a foreign key to the same table but you have a column referencing itself.
Try replacing:
ALTER TABLE financial_transactions ADD CONSTRAINT fk_financial_transactions_financial_transactions FOREIGN KEY(previous_transaction_id)
REFERENCES financial_transactions (previous_transaction_id);
With:
ALTER TABLE financial_transactions ADD CONSTRAINT fk_financial_transactions_financial_transactions FOREIGN KEY(previous_transaction_id)
REFERENCES financial_transactions (transaction_id);