Postgresql: Changing Action For Foreign Key Constraint - sql

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.

Related

I have a problem with this query in Postgres

I have a problem with this table in Postgres, it give me this error:
ERROR: cannot use subquery in check constraint
LINE 66: check(Artista in(Select ID_Artista
create table DirigeF(
Artista int references Artista(ID_Artista) on delete cascade,
Film int references Film(ID_Contenuto) on delete cascade,
check(Artista in(Select ID_Artista
from Artista
where tipologia='REGISTA'or'AR')),
constraint DirigeF_PK primary key(Artista, Film)
);
I want to check that Artista in table DirigeF has tipologia='REGISTA' from another table.
As the error suggests, you cannot do this with a check constraint. One option is a trigger. Another is a foreign key constraint -- but that needs to be carefully arranged.
First you need a column that indicates whether the type in Artista is "REGISTA" or "AR". That would be:
alter table artista add is_regista_ar bool generated always as
(tipologia in ('REGISTA', 'AR'));
Then create a unique constraint or index:
alter table artista add unq_artista_tipologia_id
unique (is_regista_ar, id_artista)
Note: This requires Postgres 12+. But something similar can be done in earlier versions.
Then, add a boolean column to your table that is always true:
create table DirigeF (
Artista int references Artista(ID_Artista) on delete cascade,
Film int references Film(ID_Contenuto) on delete cascade,
is_regista_ar bool generated always as true,
constraint fk_artista_tipo_artista foreign key (is_regista_ar, Artista) references Artista(is_regista_ar, ID_Artista),
constraint DirigeF_PK primary key (Artista, Film)
);

Alter a table to add a foreign key constraint with a default value

How do I alter a table to have a column a foreign key constraint with a default value?
In T-SQL if you're using SQL-Server, just be careful to put a real key for default.
Edit: As said in the comments, be careful that you really need a default value for a foreign key, there could be a design problem.
ALTER TABLE [tablename]
ADD CONSTRAINT [CK_columnname_default]
DEFAULT [your_default_value] FOR [columnname];
GO
ALTER TABLE [tablename]
ADD CONSTRAINT [FK_nameForeignKey] FOREIGN KEY (columnname)
REFERENCES [dbo].[oTable] (oTableID)
ON UPDATE CASCADE;
GO
Well I did the following and it worked for me:
ALTER TABLE Employee
ADD RegionID varchar(3)
CONSTRAINT [Default_Value_Region] default ('US') NOT NULL,
CONSTRAINT [FK_EMPLOYEE_Region] FOREIGN KEY([RegionID])
REFERENCES [dbo].[Region] ([Code])
GO

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)
);

SQL Server : multi CASCADE Operation

I have two tables, and I want HEDE2 columns as FOREIGN KEY REFERENCES by HEDE table. FOR creating second table it will not allow because its having warning:
More than one key specified in column level FOREIGN KEY constraint, table 'HEDE2'.
But when I tried to ALTER TABLE HEDE2 for FOREIGN KEY it allows me to do that. Is anybody knows WHY this happens. Is this a bug?
CREATE TABLE cascde.HEDE
(
HedeID INT,
HedeID2 INT,
HedeID3 INT
CONSTRAINT PK_HEDE
PRIMARY KEY (HedeID, HedeID2, HedeID3)
)
GO
CREATE TABLE HEDE2
(
Hede2ID INT PRIMARY KEY IDENTITY(1,1) ,
HedeID INT,
HedeID2 INT,
HedeID3 INT
CONSTRAINT FK_HedeID
FOREIGN KEY (HedeID, Hede2ID, HedeID3)
REFERENCES cascde.HEDE (HedeID, HedeID2, HedeID3)
ON UPDATE NO ACTION
ON DELETE NO ACTION
)
Altering table HEDE 2 for foreign key. This allows me to do that:
ALTER TABLE cascde.HEDE2
ADD CONSTRAINT FK_HEDE
FOREIGN KEY(HedeID, HedeID2, HedeID3)
REFERENCES cascde.HEDE (HedeID, HedeID2, HedeID3)
ON UPDATE NO ACTION
ON DELETE NO ACTION
GO
You're missing a comma (,) after HedeID3 INT in the CREATE TABLE version.

SQL ALTER TABLE ON DELETE CASCADE

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