PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Ограничение за външен ключ с някои стойности на колони, намиращи се в други таблици

Пропуснали сте всички външни ключове в името на книгата.

Ето защо отговарям с пълен подобрен набор от дефиниции на таблици, става въпрос за външни ключове, нали? Разбира се, че дадохте съкратен пример.

Проблемът за решаване беше, че записите в reading_event_discussion трябва да е за теми, които съществуват в тази книга:

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

Така че решението е да напишете персонализирана функция за проверка. Това не е преносимо към други системи за бази данни.

Човек може да напише тази функция на няколко езика (plpgsql, pltcl, ...), но SQL функциите могат да бъдат вградени в заявка и може да са по-бързи.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Събирайте рекурсивни JSON ключове в Postgres

  2. Таблица като аргумент на функция на PostgreSQL

  3. Как да намерите елементи с *всички* съвпадащи категории

  4. Динамично транспониране за неизвестна стойност на ред в име на колона в postgres

  5. Съхранявайте резултата от заявката в променлива, използвана в PL/pgSQL