• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

SQL, relacja na kilka tabeli

Object Storage Arubacloud
0 głosów
106 wizyt
pytanie zadane 30 marca 2023 w SQL, bazy danych przez JaaO Początkujący (490 p.)

Witam, mam problem z tym kodem:

CREATE table logs (
 id BIGINT UNSIGNED PRIMARY KEY,
  log_date DATETIME NOT NULL,
  log_action VARCHAR(255) NOT NULL,
  log_user_id BIGINT UNSIGNED NOT NULL,
  object_id BIGINT UNSIGNED NOT NULL,
  object_type ENUM('users', 'usergroups', 'permissions') NOT NULL,
  FOREIGN KEY (log_user_id) REFERENCES users(id) ON DELETE CASCADE,
  FOREIGN KEY (object_id) REFERENCES  
    CASE
      WHEN object_type = 'users' THEN users(id)
      WHEN object_type = 'usergroups' THEN usergroups(id)
      WHEN object_type = 'permissions' THEN permissions(id)
    END
);

 

PMA wyrzuca problemy z nawiasami
 

2 errors were found during analysis.

 

  1. An opening bracket was expected. (near ")" at position 568)
  2. A closing bracket was expected. (near ")" at position 568)

1 odpowiedź

+1 głos
odpowiedź 30 marca 2023 przez Wiciorny Ekspert (269,710 p.)
edycja 30 marca 2023 przez Wiciorny

W SQL nie możesz użyć CASE expression kiedy używasz do określania kluczy z słówkiem kluczowym REFERENCES dla tworzenia  FOREIGN KEY.
Poprawnie zapisać możesz to tylko tak. 
 

CREATE TABLE logs (
 id BIGINT UNSIGNED PRIMARY KEY,
 log_date DATETIME NOT NULL,
 log_action VARCHAR(255) NOT NULL,
 log_user_id BIGINT UNSIGNED NOT NULL,
 object_id BIGINT UNSIGNED NOT NULL,
 object_type ENUM('users', 'usergroups', 'permissions') NOT NULL,
 FOREIGN KEY (log_user_id) REFERENCES users(id) ON DELETE CASCADE,
 FOREIGN KEY (object_id) REFERENCES users(id) ON DELETE CASCADE,
 FOREIGN KEY (object_id) REFERENCES usergroups(id) ON DELETE CASCADE,
 FOREIGN KEY (object_id) REFERENCES permissions(id) ON DELETE CASCADE
);


Ty tworzysz tabele, a tworzenie definicji tabeli jest jedno - więc twój ENUM jest workiem na dane, ale twój foreign key nie może dotyczyć się rekordu który zostanie wpisany, bo na tym poziomie (definicji), jest to niemożliwe. 

Możesz jedynie to zrobić dynamicznie z poziomu kodu, np  skorzystać z połączenia dynamicznego SQL i prepared statements.

DELIMITER //

CREATE PROCEDURE add_object_fk(IN type ENUM('users', 'usergroups', 'permissions'))
BEGIN
    SET @sql = CONCAT('ALTER TABLE logs ADD FOREIGN KEY (object_id) REFERENCES ', type, '(id) ON DELETE CASCADE');
    PREPARE stmt FROM @sql;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
END//

DELIMITER ;

i uruchomić to z poziomu jakiegoś skryptu 

CALL add_object_fk('users');

Jeśli nie potrafisz korzystać z procedur składowych MSQL to możesz ostatecznie dodać skrypt z alterami po definicji tabeli

ALTER TABLE logs ADD CONSTRAINT fk_logs_users FOREIGN KEY (object_id) REFERENCES users(id) ON DELETE CASCADE WHERE object_type = 'users';
ALTER TABLE logs ADD CONSTRAINT fk_logs_usergroups FOREIGN KEY (object_id) REFERENCES usergroups(id) ON DELETE CASCADE WHERE object_type = 'usergroups';
ALTER TABLE logs ADD CONSTRAINT fk_logs_permissions FOREIGN KEY (object_id) REFERENCES permissions(id) ON DELETE CASCADE WHERE object_type = 'permissions';

Chociaż isntrukcji CALL możesz wykonać z poziomu SQL. 

Podobne pytania

0 głosów
0 odpowiedzi 154 wizyt
0 głosów
1 odpowiedź 521 wizyt
pytanie zadane 30 października 2018 w SQL, bazy danych przez GhostZoombie Użytkownik (640 p.)
0 głosów
1 odpowiedź 219 wizyt

92,550 zapytań

141,394 odpowiedzi

319,522 komentarzy

61,935 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...