SQL Delete trigger for multiple table - sql

So I have two table with id_pastille and I want to create a trigger that each time that one id_pastille is deleted every table that has the id_pastille is deleted as well.
CREATE TABLE tp1_trajet
(
id_trajet int NOT NULL,
longitude double precision NOT NULL,
latitude double precision NOT NULL,
"date" timestamp NOT NULL,
id_pastille int NOT NULL,
CONSTRAINT PK_zone_geographique PRIMARY KEY ( id_trajet ),
CONSTRAINT FK_ FOREIGN KEY ( id_pastille ) REFERENCES tp1_pastille ( id_pastille )
and let say this table
CREATE TABLE tp1_compte
(
id_compte int NOT NULL,
date_achat date NOT NULL,
id_pastille int NOT NULL,
id_usager int NOT NULL,
probabilite_malade double precision NULL,
CONSTRAINT PK_compte PRIMARY KEY ( id_compte ),
CONSTRAINT UQ_compte_id_pastille UNIQUE ( id_pastille ),
CONSTRAINT UQ_compte_id_usager UNIQUE ( id_usager ),
CONSTRAINT FK_compte_id_pastille FOREIGN KEY ( id_pastille ) REFERENCES tp1_pastille ( id_pastille ),
CONSTRAINT FK_compte_id_usager FOREIGN KEY ( id_usager ) REFERENCES tp1_usager ( id_usager )
);
I came up with this so far :
CREATE FUNCTION Delete_pastille() RETURNS trigger
AS $DeleteCustomerWithOrders$
BEGIN
DELETE FROM tp1_bulle,
tp1_compte,
tp1_pastille,
tp1_signes_vitaux,
tp1_usager,
tp1_transaction,
tp1_trajet
WHERE id_pastille = OLD."Id";
RETURN OLD;
END;
$DeleteCustomerWithOrders$
LANGUAGE plpgsql;

You can only delete from a single table in a DELETE statement. Try using several statements.
The best solution might be to define foreign key constraints on all but one of these columns that point to the table that contains the original copy (pastille?). If the foreign key is defined with ON DELETE CASCADE, deleting the original will automatically delete all the dependent rows.

alter table tp1_trajet
drop constraint fK_,
add constraint fK_
foreign key (ID_pastille)
references tp1_pastille (ID_pastille)
on delete cascade;
alter table tp1_compte
drop constraint FK_compte_id_pastille,
add constraint FK_compte_id_pastille
foreign key (ID_pastille)
references tp1_pastille (ID_pastille)
on delete cascade;

Related

How to fix error "there is no unique constraint matching given keys for referenced table"

I am trying to create some tables in pgadmim.
Although in both tables tb_discipline and tb_round the discipline_id is the primary key I get the error:
there is no unique constraint matching given keys for the referenced table
"tb_round"
Adding the full code:
CREATE TABLE tb_discipline (
discipline_id INT NOT NULL,
name CHARACTER VARYING(50) NOT NULL,
inventor CHARACTER VARYING(50) NOT NULL,
type CHARACTER VARYING(10) NOT NULL,
object_type CHARACTER(20) DEFAULT NULL,
CONSTRAINT PK_tb_discipline PRIMARY KEY(discipline_id)
);
------------------------------------------------------------------------------------------------
--
-- Create table tb_athlete
--
------------------------------------------------------------------------------------------------
CREATE TABLE tb_athlete (
athlete_id CHARACTER(7) NOT NULL,
name CHARACTER VARYING(50) NOT NULL,
country CHARACTER(3) NOT NULL,
substitute_id CHARACTER (7),
CONSTRAINT PK_tb_athlete PRIMARY KEY(athlete_id),
CONSTRAINT FK_athlete_substitute FOREIGN KEY (substitute_id) REFERENCES tb_athlete(athlete_id)
);
------------------------------------------------------------------------------------------------
--
-- Create table tb_play
--
------------------------------------------------------------------------------------------------
CREATE TABLE tb_play (
athlete_id CHARACTER(7) NOT NULL,
discipline_id INT NOT NULL,
CONSTRAINT FK_play_athlete FOREIGN KEY (athlete_id) REFERENCES tb_athlete(athlete_id),
CONSTRAINT FK_play_discipline FOREIGN KEY (discipline_id) REFERENCES tb_discipline(discipline_id)
);
------------------------------------------------------------------------------------------------
--
-- Create table tb_round
--
------------------------------------------------------------------------------------------------
CREATE TABLE tb_round (
round_number INT NOT NULL,
discipline_id INT NOT NULL,
CONSTRAINT PK_tb_round PRIMARY KEY(round_number, discipline_id),
CONSTRAINT FK_round_discipline FOREIGN KEY (discipline_id) REFERENCES tb_discipline(discipline_id)
);
------------------------------------------------------------------------------------------------
--
-- Create table tb_register
--
------------------------------------------------------------------------------------------------
CREATE TABLE tb_register (
athlete_id CHARACTER(7) NOT NULL,
round_number INT NOT NULL,
discipline_id INT NOT NULL UNIQUE,
register_date DATE NOT NULL DEFAULT CURRENT_DATE,
register_position INT,
register_time TIME,
register_measure REAL,
CONSTRAINT PK_tb_register PRIMARY KEY(athlete_id,round_number,discipline_id),
CONSTRAINT FK_register_athlete FOREIGN KEY (athlete_id) REFERENCES tb_athlete(athlete_id),
CONSTRAINT FK_register_round_discipline FOREIGN KEY (discipline_id) REFERENCES tb_round(discipline_id),
CONSTRAINT FK_register_round_number FOREIGN KEY (round_number) REFERENCES tb_round(round_number)
);
Any idea how can I solve this?
You have two foreign keys in tb_register referencing round but only part of its key. Make that one referencing the complete key.
CREATE TABLE tb_register
(...
CONSTRAINT fk_register_round_number_discipline_id
FOREIGN KEY (round_number,
discipline_id)
REFERENCES tb_round
(round_number,
discipline_id)
...);

Database constraint over multiple tables

Say I have the following tables:
CREATE TABLE [Weeks]
(
[Id] INT NOT NULL IDENTITY,
CONSTRAINT [PK_Weeks] PRIMARY KEY ([Id])
);
CREATE TABLE [Days]
(
[Id] INT NOT NULL IDENTITY,
[WeekId] INT NULL,
CONSTRAINT [PK_Days] PRIMARY KEY ([Id]),
CONSTRAINT [FK_Days_Weeks_WeekId]
FOREIGN KEY ([WeekId]) REFERENCES [Weeks] ([Id])
);
CREATE TABLE [ReplacedDayInWeek]
(
[Id] INT NOT NULL IDENTITY,
[WeekId] INT NOT NULL,
[DayId] INT NOT NULL,
[ReplacedDayId] INT NOT NULL,
CONSTRAINT [PK_ReplacedDayInWeek] PRIMARY KEY ([Id]),
CONSTRAINT [FK_ReplacedDayInWeek_Days_DayId]
FOREIGN KEY ([DayId]) REFERENCES [Days] ([Id]),
CONSTRAINT [FK_ReplacedDayInWeek_Weeks_WeekId]
FOREIGN KEY ([WeekId]) REFERENCES [Weeks] ([Id]),
CONSTRAINT [FK_ReplacedDayInWeek_Weeks_ReplacedWeekId]
FOREIGN KEY ([ReplacedWeekId]) REFERENCES [Weeks] ([Id])
);
The table ReplacedDayInWeek contains a day in a specific week that's replaced by another day.
How can I create a SQL constraint (or perhaps another SQL based solution) that makes sure I can only insert rows into DayInWeek with a DayId that's part of the same week as WeekId?
I'm looking for a solution with the least amount of changes to the source database. I'd prefer an additional table or table changes above stored procedures.
This data structure makes no sense to me. You have the mapping between days and weeks in two tables.
You should really only be storing the week in one table and looking it up in the other.
That said, you can do what you want using an additional constraint on day/week between the two tables:
CREATE TABLE [Days]
(
[Id] INT NOT NULL IDENTITY,
[WeekId] INT NULL,
CONSTRAINT [PK_Days] PRIMARY KEY ([Id]),
CONSTRAINT [FK_Days_Weeks_WeekId]
FOREIGN KEY ([WeekId]) REFERENCES [Weeks] ([Id]),
CONSTRAINT UNQ_Days_WeekId_Id UNIQUE (WeekId, Id)
);
CREATE TABLE [DaysInWeek]
(
[Id] INT NOT NULL IDENTITY,
[WeekId] INT NOT NULL,
[DayId] INT NOT NULL,
CONSTRAINT [PK_DaysInWeek] PRIMARY KEY([Id]),
CONSTRAINT [FK_DaysInWeek_Days_WeekId_DayId]
FOREIGN KEY (WeekId, DayId) REFERENCES Days(WeekId, Id),
CONSTRAINT [FK_DaysInWeek_Weeks_WeekId]
FOREIGN KEY ([WeekId]) REFERENCES [Weeks] ([Id])
);

ERROR: No unique constraint matching when having FK

I have three tables that are linked together
My script:
-- Ticket --
CREATE TABLE public.ticket (
id bigint NOT NULL,
libelle character varying(255) NOT NULL,
description character varying(255) NOT NULL,
status character varying(255) NOT NULL,
date_creation timestamp NOT NULL,
date_modification timestamp NOT NULL,
user_createur_id bigint,
referent_realisateur_id bigint,
CONSTRAINT pk_ticket PRIMARY KEY (id)
);
-- Ticket_Avance TABLE --
CREATE TABLE public.ticket_avance (
id bigint NOT NULL,
date_livraison_souhaite timestamp NOT NULL,
date_engagement_livraison timestamp NOT NULL,
referent_demandeur_id bigint
);
ALTER TABLE public.ticket_avance ADD CONSTRAINT "fk_ticket_ticketAvance" FOREIGN KEY (id)
REFERENCES public.ticket (id) MATCH SIMPLE
ON DELETE NO ACTION ON UPDATE NO ACTION;
-- Demande_Travaux TABLE --
DROP TABLE IF EXISTS public.demande_travaux CASCADE;
CREATE TABLE public.demande_travaux (
id bigint NOT NULL,
contrat_id bigint
);
ALTER TABLE public.demande_travaux ADD CONSTRAINT "fk_ticketAvance_DDT" FOREIGN KEY (id)
REFERENCES public.ticket_avance (id) MATCH FULL
ON DELETE NO ACTION ON UPDATE NO ACTION;
I have this error on the demand_travaux creation
SQL Error [42830]: ERROR: there is no unique constraint matching given keys for referenced table "ticket_avance"
ERROR: there is no unique constraint matching given keys for referenced table "ticket_avance"
ERROR: there is no unique constraint matching given keys for referenced table "ticket_avance"
You have forgotten to declare column ID in table ticket_avance as primary key.
Please use the following SQL:
-- Ticket_Avance TABLE --
CREATE TABLE public.ticket_avance (
id bigint NOT NULL,
date_livraison_souhaite timestamp NOT NULL,
date_engagement_livraison timestamp NOT NULL,
referent_demandeur_id bigint,
CONSTRAINT pk_avance PRIMARY KEY (id) --- add this
);
you need add constraint in Ticket_Avance table because you provide reference this id to demande_travaux
-- Ticket_Avance TABLE --
CREATE TABLE ticket_avance (
id bigint NOT NULL,
date_livraison_souhaite timestamp NOT NULL,
date_engagement_livraison timestamp NOT NULL,
referent_demandeur_id bigint,
CONSTRAINT pk_ticket_avance PRIMARY KEY (id) //constraint that you need
);
ALTER TABLE demande_travaux ADD CONSTRAINT "fk_ticketAvance_DDT" FOREIGN KEY (id)
REFERENCES ticket_avance (id) MATCH FULL
ON DELETE NO ACTION ON UPDATE NO ACTION;
here is the demo link of your full query
A foreign key constraint has to target a primary key or unique constraint. The database has to be able to identify a single row in the "parent" table.
You could add primary key constraints:
ALTER TABLE public.ticket_avance ADD PRIMARY KEY (id);
In addition, you should have an index on the column on which the foreign key is defined, particularly if you plan to delete parent rows. With the primary key above, you have such an index on id, but you also should have one on demande_travaux.
The simplest way is to define id as primary key there too:
ALTER TABLE public.demande_travaux ADD PRIMARY KEY (id);

Oracle: Constraints of keys

I have an entity within Oracle's SQL:
and I'm wondering, what does "UF" represent? I've written the SQL code but I do not know how to represent the "UF" attribute as a constraint.
CREATE TABLE entry (
entryno NUMBER(4) NOT NULL,
carndate DATE NOT NULL,
entrystarttime DATE NOT NULL,
entryfinishtime DATE NOT NULL,
entryplace NUMBER(4) NOT NULL,
charname VARCHAR2(30) NOT NULL,
compno NUMBER(4) NOT NULL,
eventypecode CHAR(3) NOT NULL,
teamname VARCHAR2(30) NOT NULL
);
ALTER TABLE entry ADD CONSTRAINT entry_pk PRIMARY KEY ( entryno,
carndate );
ALTER TABLE entry
ADD CONSTRAINT entry_charity_fk FOREIGN KEY ( charname )
REFERENCES charity ( charname );
ALTER TABLE entry
ADD CONSTRAINT entry_carnival_fk FOREIGN KEY ( carndate )
REFERENCES carnival ( carndate );
ALTER TABLE entry #
ADD CONSTRAINT entry_competitor_fk FOREIGN KEY ( compno )
REFERENCES competitor ( compno );
ALTER TABLE entry #
ADD CONSTRAINT entry_event_fk FOREIGN KEY ( carndate, eventypecode )
REFERENCES evenet ( carndate, eventypecode );
ALTER TABLE entry
ADD CONSTRAINT entry_team_fk FOREIGN KEY ( teamname, carndate )
REFERENCES team ( teamname,carndate );
ALTER TABLE entry
ADD CONSTRAINT ... ("UF")
The UF is actually two flags.
As you've recognised the F means the column is a foreign key. The U stands for Unique. Those columns form part of the compound unique key:
ALTER TABLE entry ADD CONSTRAINT entry_carnival_un UNIQUE
( carndate, compno, eventypecode );
carndate is also part of the compound primary key so really it should be flagged PFU but I guess the modelling tool didn't allow for three flags.

Invalid Column Name when Create trigger using SQL server

I encountered several errors when I tried to create a simple trigger using SQL server. Tables are created using:
CREATE TABLE person
(
person_id INT NOT NULL PRIMARY KEY,
name VARCHAR NOT NULL,
phone INT,
birth_date DATE,
address VARCHAR
);
CREATE TABLE volunteers
(
person_id INT NOT NULL PRIMARY KEY,
skill VARCHAR,
FOREIGN KEY (person_id) REFERENCES person(person_id)
ON DELETE CASCADE
ON UPDATE CASCADE
);
CREATE TABLE physicians
(
person_id INT NOT NULL PRIMARY KEY,
speciality VARCHAR,
phone_number INT,
FOREIGN KEY (person_id) REFERENCES person(person_id)
ON DELETE CASCADE
ON UPDATE CASCADE
);
CREATE TABLE patients
(
person_id INT NOT NULL PRIMARY KEY,
contact_date DATE,
physician_id INT, -- TODO determine whether NULL able
-- TODO determine ON DELETE ACTION
CHECK (person_id <> physician_id),
FOREIGN KEY (person_id) REFERENCES person(person_id)
ON DELETE CASCADE
ON UPDATE CASCADE,
FOREIGN KEY (physician_id) REFERENCES physicians(person_id)
ON DELETE NO ACTION
ON UPDATE NO ACTION
);
CREATE TABLE outpatients
(
person_id INT NOT NULL PRIMARY KEY,
FOREIGN KEY (person_id) REFERENCES patients(person_id)
ON DELETE CASCADE
ON UPDATE CASCADE
);
CREATE TABLE visits
(
person_id INT NOT NULL,
date DATE NOT NULL,
comments VARCHAR,
PRIMARY KEY (person_id, date),
FOREIGN KEY (person_id) REFERENCES outpatients(person_id)
ON DELETE CASCADE
ON UPDATE CASCADE
);
CREATE TABLE employees
(
person_id INT NOT NULL PRIMARY KEY,
date_hire DATE,
FOREIGN KEY (person_id) REFERENCES person(person_id)
ON DELETE CASCADE
ON UPDATE CASCADE
);
CREATE TABLE nurses
(
person_id INT NOT NULL PRIMARY KEY,
certificate VARCHAR,
care_center_name VARCHAR,
FOREIGN KEY (person_id) REFERENCES employees(person_id)
ON DELETE CASCADE
ON UPDATE CASCADE,
-- FOREIGN KEY (care_center_name) REFERENCES care_centers(name)
-- ON DELETE CASCADE
-- ON UPDATE CASCADE
);
CREATE TABLE care_centers
(
name VARCHAR PRIMARY KEY NOT NULL,
nurses_in_charge INT NOT NULL,
location VARCHAR,
type VARCHAR
-- FOREIGN KEY (nurses_in_charge) REFERENCES registered_nurse(person_id)
);
CREATE TABLE registered_nurse
(
person_id INT NOT NULL PRIMARY KEY,
care_center_name VARCHAR,
FOREIGN KEY (person_id) REFERENCES nurses(person_id),
-- ON DELETE CASCADE
-- ON UPDATE CASCADE,
FOREIGN KEY (care_center_name) REFERENCES care_centers(name)
-- ON DELETE CASCADE
-- ON UPDATE CASCADE
);
ALTER TABLE nurses
ADD constraint nurses__care_centers_FK
FOREIGN KEY (care_center_name) REFERENCES care_centers(name)
ON DELETE CASCADE
ON UPDATE CASCADE;
ALTER TABLE care_centers
ADD constraint care_centers__registered_nurse_FK
FOREIGN KEY (nurses_in_charge) REFERENCES registered_nurse(person_id);
CREATE TABLE beds
(
bed_number INT NOT NULL,
room_number INT NOT NULL,
care_center_name VARCHAR,
PRIMARY KEY (bed_number,room_number),
FOREIGN KEY (care_center_name) REFERENCES care_centers(name)
ON DELETE CASCADE
ON UPDATE CASCADE
);
CREATE TABLE residents
(
person_id INT NOT NULL PRIMARY KEY,
date_admitted DATE,
bed_number INT,
room_number INT,
FOREIGN KEY (person_id) REFERENCES patients(person_id)
ON DELETE CASCADE
ON UPDATE CASCADE,
FOREIGN KEY (bed_number, room_number) REFERENCES beds(bed_number, room_number)
ON DELETE CASCADE
ON UPDATE CASCADE
);
CREATE TABLE staffs
(
person_id INT NOT NULL PRIMARY KEY,
job_class DATE,
FOREIGN KEY (person_id) REFERENCES employees(person_id)
ON DELETE CASCADE
ON UPDATE CASCADE
);
CREATE TABLE technicians
(
person_id INT NOT NULL PRIMARY KEY,
skill VARCHAR,
FOREIGN KEY (person_id) REFERENCES employees(person_id)
ON DELETE CASCADE
ON UPDATE CASCADE
);
CREATE TABLE laboratories
(
name VARCHAR NOT NULL PRIMARY KEY,
location VARCHAR
);
CREATE TABLE assignTechnicianToLab
(
person_id INT NOT NULL,
laboratories_name VARCHAR NOT NULL,
PRIMARY KEY(person_id, laboratories_name),
FOREIGN KEY (person_id) REFERENCES employees(person_id)
ON DELETE CASCADE
ON UPDATE CASCADE,
FOREIGN KEY (laboratories_name) REFERENCES laboratories(name)
ON DELETE CASCADE
ON UPDATE CASCADE
)
And the trigger I am trying to create:
-- Trigger
/* if nurse has certificate "RN", add to registered_nurse */
CREATE TRIGGER registered_nurse_trigger
ON nurses
FOR INSERT, UPDATE
AS
BEGIN
IF EXISTS (SELECT * FROM inserted where certificate = "RN")
BEGIN
INSERT INTO registered_nurse
VALUES(inserted.person_id, nurses.care_center_name);
END
END;
And I keep getting errors saying that:
Msg 207, Level 16, State 1, Procedure registered_nurse_trigger, Line 6
Invalid column name 'RN'.
Msg 4104, Level 16, State 1, Procedure registered_nurse_trigger, Line 8
The multi-part identifier "inserted.person_id" could not be bound.
Msg 4104, Level 16, State 1, Procedure registered_nurse_trigger, Line 8
The multi-part identifier "nurses.care_center_name" could not be bound.
I've been hanging over here for several hours and I really appreciate anyone can help me with it. Thank you very much!
You can't use VALUES() like that. Use INSERT..SELECT instead:
-- Trigger
/* if nurse has certificate "RN", add to registered_nurse */
CREATE TRIGGER registered_nurse_trigger ON nurses
For INSERT, UPDATE
AS BEGIN
INSERT INTO registered_nurse (person_id, care_center_name)
SELECT person_id, care_center_name
FROM inserted
WHERE certificate = 'RN'
END;
I don't think you need to reference nurses or have that EXISTS() either, but maybe I'm overlooking something.
You are using double quote instead of single quotes in your Create Trigger statement try this and see if it works:
-- Trigger
/* if nurse has certificate "RN", add to registered_nurse */
CREATE TRIGGER registered_nurse_trigger ON nurses
FOR INSERT, UPDATE
AS
BEGIN
IF EXISTS (SELECT * FROM inserted where certificate = 'RN')
BEGIN
INSERT INTO registered_nurse
SELECT person_id, care_center_name FROM Inserted;
END
END;