sql >> Database >  >> RDS >> PostgreSQL

Externe sleutelbeperking met enkele kolomwaarden die zich in andere tabellen bevinden

U hebt alle externe sleutels op de boeknaam weggelaten.

Dat is waarom ik antwoord met een compleet verbeterde set tabeldefinities, dit gaat over buitenlandse sleutels, toch? Shure je gaf een uitgekleed voorbeeld.

Het op te lossen probleem was dat records in reading_event_discussion moet gaan over thema's die in dat boek voorkomen:

drop table book cascade;
drop table book_theme;
drop table reading_event cascade;
drop table reading_event_discussion;

create table book (
    name text primary key -- new, a must because it is FK in reading_event
);
insert into book (name) values ('game of thrones'),('Database design');

create table book_theme (
    bookname  text references book(name), -- new
    themename text
);
insert into book_theme (bookname, themename) values 
  ('game of thrones', 'ambition'), ('game of thrones', 'power');

create table reading_event (
  i        SERIAL primary key, 
  venue    text, 
  bookread text references book(name) -- FK is new
);
insert into reading_event (venue, bookRead) VALUES
  ('Municipal Library', 'game of thrones');  

-- this is the solution: extended reference check
create or replace function themecheck (i integer, th text) returns boolean as $$
    select 
     (th in (select themename from book_theme bt 
       join reading_event re on i=re.i and re.bookRead=bt.bookname))
$$ language sql;

create table reading_event_discussion (
    i integer references reading_event(i), 
    themeDiscussed text check (themecheck (i, themeDiscussed))
);

-- Test statements:
-- just check data
select * from reading_event;
-- this should be ok
insert into reading_event_discussion values (1,'ambition'),(1,'power');
-- this must be refused
insert into reading_event_discussion values (1,'databases');

De oplossing is dus om een ​​aangepaste controlefunctie te schrijven. Dit is niet overdraagbaar naar andere databasesystemen.

Men kan deze functie in verschillende talen schrijven (plpgsql, pltcl, ... ), maar SQL-functies kunnen in een query worden opgenomen en zijn mogelijk sneller.




  1. Resultaten uit twee afzonderlijke databases samenvoegen

  2. ONDERSCHEIDEN SELECTEREN *

  3. WSJDBCConnection verpakt geen objecten van het type Oracle jdbc Connection

  4. Hoe een primaire sleutel opnieuw ordenen?