Moin,
folgende Situation:
ich habe 2 Tabellen einen mit Standard Werten und eine mit Werten die ein User mit persönlichen Werten füllen kann. Wenn ein neuer Eintrag in eine andere Tabelle gemacht wird muss aus einer der beiden Tabellen ein Wert gewählt werden. Der andere Foreignkey ist dann null. Das klappt auch soweit. Ich habe eine entsprechende Constraint gebaut die eben erfordert das einer der beiden ForeignKeys nicht null sein darf und der andere es sein muss. Jetzt zu meinem Problem, wenn aus der User Tabelle nun ein Eintrag gelöscht wird, sollen alle bisherigen Datensätze unberührt bleiben also keine Cascade ausgelöst werden. Das bekomme ich aber leider nicht hin. Keine Ahnung ob man aus meiner Ausführung schlau werden kann als Fachmann? Ich stelle aber natürlich auch gerne die die SQL Statements zu Verfügung die ich so gebastelt habe wenn das hilft. Ich bräuchte also sowas wie ein softdelete. Alles alte bleibt wie es ist, aber für neue Datensätze steht der Eintrag nicht mehr zur Verfügung
Dann will ich das mal machen
CREATE TABLE IF NOT EXISTS public.user_fish_species (
id SERIAL PRIMARY KEY,
user_fish_species_name VARCHAR(30) UNIQUE NOT NULL,
user_id int,
created_at TIMESTAMP,
updated_at TIMESTAMP,
CONSTRAINT fish_species_users_fk FOREIGN KEY(user_id) REFERENCES users(id)
ON UPDATE CASCADE
ON DELETE CASCADE
);
CREATE TABLE IF NOT EXISTS public.user_fishing_baits (
id SERIAL PRIMARY KEY,
user_fishing_bait_name VARCHAR(30) NOT NULL,
user_id int,
created_at TIMESTAMP,
updated_at TIMESTAMP,
CONSTRAINT user_fishing_baits_users_fk FOREIGN KEY(user_id) REFERENCES users(id)
ON UPDATE CASCADE
);
CREATE TABLE IF NOT EXISTS public.catch_book (
id SERIAL PRIMARY KEY,
weight NUMERIC(7,2) NOT NULL,
length NUMERIC(7,2) NOT NULL,
temperature NUMERIC(7,2),
air_pressure NUMERIC(7,2),
catched_at TIMESTAMP without time zone NOT NULL,
user_id INT,
fish_species_id INT,
user_fish_species_id INT,
fishing_bait_id INT NULL,
user_fishing_bait_id INT NULL,
water_id INT,
user_water_id int,
weather_type_id INT,
created_at TIMESTAMP,
updated_at TIMESTAMP,
CONSTRAINT catch_book_waters_fk FOREIGN KEY(water_id) REFERENCES waters(id)
ON UPDATE CASCADE
ON DELETE CASCADE,
CONSTRAINT catch_book_user_waters_fk FOREIGN KEY(user_water_id) REFERENCES user_waters(id)
ON UPDATE CASCADE
ON DELETE CASCADE,
CONSTRAINT catch_book_weather_types_fk FOREIGN KEY(weather_type_id) REFERENCES weather_types(id)
ON UPDATE CASCADE
ON DELETE CASCADE,
CONSTRAINT catch_book_fish_species_fk FOREIGN KEY(fish_species_id) REFERENCES fish_species(id)
ON UPDATE CASCADE
ON DELETE CASCADE,
CONSTRAINT catch_book_user_fish_species_fk FOREIGN KEY(user_fish_species_id) REFERENCES user_fish_species(id)
ON UPDATE CASCADE
ON DELETE CASCADE,
CONSTRAINT catch_book_fishing_baits_fk FOREIGN KEY(fishing_bait_id) REFERENCES fishing_baits(id)
ON UPDATE CASCADE
ON DELETE CASCADE,
CONSTRAINT catch_book_user_fishing_baits_fk FOREIGN KEY(user_fishing_bait_id) REFERENCES user_fishing_baits(id)
ON UPDATE CASCADE
ON DELETE CASCADE,
CONSTRAINT catch_book_users_fk FOREIGN KEY(user_id) REFERENCES users(id)
ON UPDATE CASCADE
ON DELETE CASCADE,
CONSTRAINT catch_book_fishing_bait_all_user_ck CHECK (
CASE WHEN fishing_bait_id IS NULL THEN 0 ELSE 1 END +
CASE WHEN user_fishing_bait_id IS NULL THEN 0 ELSE 1 END = 1
),
CONSTRAINT catch_book_waters_all_user_ck CHECK (
CASE WHEN water_id IS NULL THEN 0 ELSE 1 END +
CASE WHEN user_water_id IS NULL THEN 0 ELSE 1 END = 1
),
CONSTRAINT catch_book_fish_species_all_user_ck CHECK (
CASE WHEN fish_species_id IS NULL THEN 0 ELSE 1 END +
CASE WHEN user_fish_species_id IS NULL THEN 0 ELSE 1 END = 1
),
CONSTRAINT weight_positiv_ck CHECK (weight > 0),
CONSTRAINT length_positiv_ck CHECK (length > 0)
);
vielleicht noch als Ergänzung. So läuft es bisher, da hatte ich das einfach noch nicht bedacht. Jetzt war mein Ansatz ein Trigger zu setzen, “wenn gelöscht wird, dann setze den anderen ForeignKey auf not null” und alle constraints sind erfüllt. Aber hier verließen Sie mich