SQL запрос для удаления из соединительной таблицы и ассоциированной таблицы - PullRequest
1 голос
/ 20 апреля 2020

У меня есть много-много связей для событий и сроков. В моей программе можно удалить событие, а затем мне также нужно удалить все строки this.eventID + timelineID из соединительной таблицы.

Вот моя структура таблицы для этих 3 таблиц:

CREATE TABLE `events` (
  `EventID` int NOT NULL AUTO_INCREMENT,
  `EventType` tinyint NOT NULL,
  `EventName` nvarchar(100) DEFAULT NULL,
  `EventDescription` nvarchar(5000) DEFAULT NULL,
  `StartYear` bigint NOT NULL,
  `StartMonth` tinyint unsigned NOT NULL,
  `StartDay` tinyint unsigned NOT NULL,
  `StartHour` tinyint unsigned  NULL,
  `StartMinute` tinyint unsigned  NULL,
  `StartSecond` tinyint unsigned  NULL,
  `StartMillisecond` smallint unsigned  NULL,
  `EndYear` bigint DEFAULT NULL,
  `EndMonth` tinyint unsigned DEFAULT NULL,
  `EndDay` tinyint unsigned DEFAULT NULL,
  `EndHour` tinyint unsigned DEFAULT NULL,
  `EndMinute` tinyint unsigned DEFAULT NULL,
  `EndSecond` tinyint unsigned DEFAULT NULL,
  `EndMillisecond` smallint unsigned DEFAULT NULL,
  `CreatedYear` bigint DEFAULT NULL,
  `CreatedMonth` tinyint unsigned DEFAULT NULL,
  `CreatedDay` tinyint unsigned DEFAULT NULL,
  `CreatedHour` tinyint unsigned DEFAULT NULL,
  `CreatedMinute` tinyint unsigned DEFAULT NULL,
  `CreatedSecond` tinyint unsigned DEFAULT NULL,
  `CreatedMillisecond` smallint unsigned DEFAULT NULL,
  PRIMARY KEY (`EventID`),
  UNIQUE KEY `EventID_UNIQUE` (`EventID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

CREATE TABLE `timelines`
(
    `TimelineID`          int               NOT NULL AUTO_INCREMENT,
    `Scale`               nvarchar(100)     DEFAULT NULL,
    `TimelineName`        nvarchar(100)     DEFAULT NULL,
    `TimelineDescription` nvarchar(5000)    DEFAULT NULL,
    `Theme`               nvarchar(100)     DEFAULT NULL,
    `StartYear`           bigint            NOT NULL,
    `StartMonth`          tinyint unsigned  NOT NULL,
    `StartDay`            tinyint unsigned  NOT NULL,
    `StartHour`           tinyint unsigned  NOT NULL,
    `StartMinute`         tinyint unsigned  NOT NULL,
    `StartSecond`         tinyint unsigned  NOT NULL,
    `StartMillisecond`    smallint unsigned NOT NULL,
    `EndYear`             bigint            DEFAULT NULL,
    `EndMonth`            tinyint unsigned  DEFAULT NULL,
    `EndDay`              tinyint unsigned  DEFAULT NULL,
    `EndHour`             tinyint unsigned  DEFAULT NULL,
    `EndMinute`           tinyint unsigned  DEFAULT NULL,
    `EndSecond`           tinyint unsigned  DEFAULT NULL,
    `EndMillisecond`      smallint unsigned DEFAULT NULL,
    `CreatedYear`         bigint            DEFAULT NULL,
    `CreatedMonth`        tinyint unsigned  DEFAULT NULL,
    `CreatedDay`          tinyint unsigned  DEFAULT NULL,
    `CreatedHour`         tinyint unsigned  DEFAULT NULL,
    `CreatedMinute`       tinyint unsigned  DEFAULT NULL,
    `CreatedSecond`       tinyint unsigned  DEFAULT NULL,
    `CreatedMillisecond`  smallint unsigned DEFAULT NULL,
    `Private`             boolean           DEFAULT true,
    `TimelineOwner`       int,
    PRIMARY KEY (`TimelineID`),
    UNIQUE KEY `TimelineID_UNIQUE` (`TimelineID`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8mb4
  COLLATE = utf8mb4_general_ci;

 CREATE TABLE `timelineevents`
  (
      `TimelineID` int NOT NULL,
      `EventID` int NOT NULL,
      CONSTRAINT `pK_timelinesevent` PRIMARY KEY (eventID,timelineID),
      CONSTRAINT `fk_timelineevents_events1` FOREIGN KEY (`EventID`) REFERENCES `events` (`EventID`),
      CONSTRAINT `fk_timelineevents_timelines` FOREIGN KEY (`TimelineID`) REFERENCES `timelines` (`TimelineID`)
  ) ENGINE = InnoDB
    DEFAULT CHARSET = utf8mb4
    COLLATE = utf8mb4_general_ci;

и это утверждение, которое я пытаюсь построить, чтобы удалить как событие из таблицы событий, так и все связанные с ним соединения в таблице соединений "timelineevents"

 public PreparedStatement getDeleteQuery() throws SQLException {
        PreparedStatement out = DBM.conn.prepareStatement("DELETE FROM `events` WHERE (`EventID` = ?); DELETE FROM `timelineevents` WHERE (`fk_timelineevents_events1` = ?)");
        out.setInt(1, eventID);
        out.setInt(2, eventID);
        return out;
    }

Правильно ли это способ сделать это?

Ответы [ 2 ]

0 голосов
/ 20 апреля 2020

Просто добавьте параметр ON DELETE CASCADE к определению внешнего ключа (или обоих внешних ключей):

CREATE TABLE `timelineevents` (
    `TimelineID` int NOT NULL,
    `EventID` int NOT NULL,
    CONSTRAINT `pK_timelinesevent` PRIMARY KEY (eventID,timelineID),
    CONSTRAINT `fk_timelineevents_events1` 
        FOREIGN KEY (`EventID`) 
        REFERENCES `events` (`EventID`)
        ON DELETE CASCADE,                    --> here
    CONSTRAINT `fk_timelineevents_timelines` 
        FOREIGN KEY (`TimelineID`) 
        REFERENCES `timelines` (`TimelineID`)
        ON DELETE CASCADE                     --> and here
)

Затем, когда вы удаляете из events (или из timelines), база данных автоматически удаляет ссылочные строки в соединительной таблице. Таким образом, вы можете просто сделать:

DELETE FROM `events` WHERE `EventID` = ?

... И будьте уверены, что соответствующие строки в соединительной таблице также были удалены.

0 голосов
/ 20 апреля 2020

Нет,

, в вашем случае вы должны использовать два PreparedStatement и выполнять их в одной транзакции.

Или вы можете заключить свои запросы в процедуру хранения или блок кода и выполнить с помощью CallableStatement .

...