PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Batasan kunci asing dengan beberapa nilai kolom berada di tabel lain

Anda telah menghilangkan semua kunci asing pada nama buku.

Itu sebabnya saya menjawab dengan satu set lengkap definisi tabel yang disempurnakan, ini tentang kunci asing, bukan? Tentu Anda memberikan contoh yang dipreteli.

Masalah yang harus dipecahkan adalah catatan di reading_event_discussion pasti tentang tema-tema yang ada di buku itu :

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

Jadi solusinya adalah menulis fungsi pemeriksaan khusus. Ini tidak portabel untuk sistem database lain.

Seseorang dapat menulis fungsi ini dalam beberapa bahasa (plpgsql, pltcl, ... ), tetapi fungsi SQL dapat dimasukkan ke dalam kueri dan mungkin lebih cepat.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Masalah SQLite3 dan Postgres/Heroku Ruby on Rails

  2. Mendapatkan semua Bangunan dalam jangkauan 5 mil dari koordinat yang ditentukan

  3. Keluarkan string ke angka, interpretasikan string nol atau kosong sebagai 0

  4. Apakah SELECT atau INSERT dalam suatu fungsi rentan terhadap kondisi balapan?

  5. Praktik Terbaik Pencatatan Audit PostgreSQL