В MySQL, как мне дублировать существующую запись в таблице и вспомогательной таблице, которая опирается на идентификатор родительской таблицы? - PullRequest
0 голосов
/ 11 июня 2019

Допустим, у меня есть таблица core и 2 вспомогательные таблицы, которые мы назовем activity и steps.

Core может содержать следующее:

coreID(int) | coreLabel(varchar)
--------------------------------
1           | Wash Car
12          | Wash Dog
15          | Vacuum the carpet

Активность может содержать следующее:

aID(int auto) | coreID(int fk) | menuID(int fk)
-----------------------------------------------
1             | 1              | 268
2             | 1              | 269
3             | 12             | 269
4             | 12             | 239
5             | 12             | 230
6             | 15             | 237
7             | 15             | 269
8             | 15             | 244
9             | 15             | 242

Шаги могут содержать следующее:

stepID(int auto) | coreID(int fk) | aID(int fk)
-----------------------------------------------
1                | 1              | 1
2                | 1              | 2
3                | 12             | 5
4                | 12             | 6
5                | 12             | 9
6                | 15             | 10
7                | 15             | 11
8                | 15             | 26

На сайте будут отображаться основные элементы. Пользователь должен иметь возможность нажимать кнопку для дублирования элемента (например, дубликата стиральной машины, coreID = 2), чтобы Core теперь имел значения

coreID(int) | coreLabel(varchar)
--------------------------------
1           | Wash Car
12          | Wash Dog
15          | Vacuum the carpet
16           | Wash Dog (copy)

... и данные в Activity должны выглядеть следующим образом:

aID(int auto) | coreID(int fk) | menuID(int fk)
-----------------------------------------------
1             | 1              | 268
2             | 1              | 269
3             | 12             | 269
4             | 12             | 239
5             | 12             | 230
6             | 15             | 237
7             | 15             | 269
8             | 15             | 244
9             | 15             | 242
10            | 16             | 268
11            | 16             | 269

... а затем Шаги должны выглядеть следующим образом:

stepID(int auto) | coreID(int fk) | aID(int fk)
-----------------------------------------------
1                | 1              | 1
2                | 1              | 2
3                | 12             | 5
4                | 12             | 6
5                | 12             | 9
6                | 15             | 10
7                | 15             | 11
8                | 15             | 26
9                | 16             | 10
10               | 16             | 11

Дублирование записей в Core и Activity прямолинейно, у меня нет проблем там. То, что я не знаю, как сделать, это дублировать вспомогательные записи в Шаги , потому что, когда запись вставляется в Деятельность , вставленное значение для aID требуется для вставки в Шаги и именно в этом и заключается моя дилемма ... Может ли MySQL справиться с этим с помощью триггера, такого как я нашел здесь: https://dba.stackexchange.com/questions/37470/cascading-inserts-in-mysql и если да, то как мне пройти в значения по умолчанию?

Update Триггер на столе не сработает. Мне нужно иметь возможность добавлять данные в таблицу Activity без БД, также добавляя строку в таблицу step. Обычно я думаю, что решение сработало бы, но не по этому сценарию.

Обновление № 2 Я создал базу данных скрипку . Это составлено из выборочных данных, полученных из моих истинных исходных данных, но было упрощено, так что, надеюсь, данных выборок достаточно.

CREATE TABLE `core` (
    `coreID` INT(11) NOT NULL AUTO_INCREMENT,
    `coreLabel` VARCHAR(150) NOT NULL DEFAULT 'Untitled',
    PRIMARY KEY (`coreID`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=1
;

CREATE TABLE `activity` (
    `aID` INT(11) NOT NULL AUTO_INCREMENT,
    `coreID` INT(11) NULL DEFAULT NULL,
    `menuID` INT(11) NULL DEFAULT NULL,
    PRIMARY KEY (`aID`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=1
;

CREATE TABLE `steps` (
    `stepID` INT(11) NOT NULL AUTO_INCREMENT,
    `coreID` INT(11) NULL DEFAULT NULL,
    `aID` INT(11) NOT NULL,
  PRIMARY KEY (`stepID`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=1
;

insert into core (corelabel) values ('Wash Car');
insert into core (corelabel) values ('Wash Dog');
insert into core (corelabel) values ('Vacuum Rug');

insert into activity (coreID, menuID) values (1,268);
insert into activity (coreID, menuID) values (1,269);
insert into activity (coreID, menuID) values (12,268);
insert into activity (coreID, menuID) values (12,239);
insert into activity (coreID, menuID) values (12,230);
insert into activity (coreID, menuID) values (15,237);
insert into activity (coreID, menuID) values (15,269);
insert into activity (coreID, menuID) values (15,244);
insert into activity (coreID, menuID) values (15,242);
insert into activity (coreID, menuID) values (4,268);


insert into steps (coreID, aID) values (1,1);
insert into steps (coreID, aID) values (1,2);
insert into steps (coreID, aID) values (12,5);
insert into steps (coreID, aID) values (12,6);
insert into steps (coreID, aID) values (12,9);
insert into steps (coreID, aID) values (15,10);
insert into steps (coreID, aID) values (15,11);
insert into steps (coreID, aID) values (15,26);

select * from core;
select * from activity;
select * from steps;
Select
    c.coreID,
    c.coreLabel,
    a.aID,
    a.menuID,
    s.stepID
From
    core c Left Join
    activity a On a.coreID = c.coreID Left Join
    steps s On s.aID = a.aID;

- Если мы притворимся, что кнопка была нажата для дублирования "Мойка машины", мы ожидаем, что произойдут следующие вставки;
- проблема заключается в том, чтобы получить эти значения программно;

insert into core (corelabel) values ('Wash Car (copy)');
insert into activity (coreID, menuID) values (4,269);   
insert into steps (coreID, aID) values (4,10);
insert into steps (coreID, aID) values (4,11);

Select
    c.coreID,
    c.coreLabel,
    a.aID,
    a.menuID,
    s.stepID
From
    core c Left Join
    activity a On a.coreID = c.coreID Left Join
    steps s On s.aID = a.aID;

Последний запрос на выборку (см. Выше) возвращает 4 записи. Это должно быть правильно, так как «Wash Car» имеет два шага. Сценарий таков, что пользователь хочет использовать «Мойку машины» в качестве шаблона для другой процедуры. После нажатия на кнопку-дубликат рядом с «Мойка автомобиля» на веб-сайте мы должны увидеть 6 возвращенных записей и запись «Мойка автомобиля (копия)»

Ответы [ 2 ]

0 голосов
/ 11 июня 2019

Дублировать записи в Core и Activity просто

И, вероятно, будет выглядеть примерно так:

set @sourceCoreID = 12;

insert into core (coreLabel)
  select coreLabel
  from core
  where coreID = @sourceCoreID;

set @newCoreID = last_insert_id();

insert into activity (coreID, menuID)
  select @newCoreID, menuID
  from activity
  where coreID = @sourceCoreID;

Все, что вам сейчас нужно, это скопировать некоторые данные из новых строк activity в steps (по крайней мере, это выглядит так в вашем примере результата). И не нужно много магии:

insert into steps(coreID, aID)
  select coreID, aID
  from activity
  where coreID = @newCoreID;

дб-скрипка

0 голосов
/ 11 июня 2019
CREATE TRIGGER steps_ti 
AFTER INSERT ON `Activity` 
FOR EACH ROW 
INSERT INTO Steps (aID,coreID) VALUES (NEW.aID,NEW.coreID);  
...