вставить внешние ключи с триггером

  • Автор темы Mironovtlt
  • Обновлено
  • 13, May 2024
  • #1
Привет.

У меня получились следующие таблицы:

СОЗДАТЬ ТАБЛИЦУ А (

id_a INT AUTO_INCREMENT ПЕРВИЧНЫЙ КЛЮЧ,

имя_a VARCHAR(50),

фамилия_a VARCHAR(50));

СОЗДАТЬ ТАБЛИЦУ Б(

id_b INT AUTO_INCREMENT ПЕРВИЧНЫЙ КЛЮЧ,

имя_b VARCHAR(50),

фамилия_b ВАРЧАР(50),

уникальный bbb(имя_b,фамилия_b));

СОЗДАТЬ ТАБЛИЦУ C(

id_c INT AUTO_INCREMENT ПЕРВИЧНЫЙ КЛЮЧ,

кабина ВАРЧАР(40) УНИКАЛЬНАЯ);

СОЗДАТЬ ТАБЛИЦУ D(

id_as INT,

id_bs ИНТ,

id_cs ИНТ,

дт ДАТАВРЕМЯ,

ВНЕШНИЙ КЛЮЧ(id_as) ССЫЛКИ A(id_a),

ВНЕШНИЙ КЛЮЧ(id_bs) ССЫЛКИ B(id_b),

ВНЕШНИЙ КЛЮЧ(id_cs) ССЫЛКИ C(id_c));

СОЗДАТЬ ТАБЛИЦУ E(

дата ДАТА,

или ВРЕМЯ,

имя_b VARCHAR(50),

фамилия_b ВАРЧАР(50),

имя_a VARCHAR(50),

фамилия_а ВАРЧАР(50),

такси ВАРЧАР(40));

Таблица A и таблица E заполняются процессом загрузки файла.

Я использую триггер для таблицы E для заполнения таблиц B, C и D. Триггер имеет обработчик продолжения для повторяющихся записей.

До сих пор мне удавалось заполнить таблицы B и C, но у меня РЕАЛЬНЫЕ проблемы с тем, чтобы сделать то же самое с таблицей D. Я не могу найти способ поместить первичные ключи в эту таблицу.

Я попытался поместить их в переменную, используя флаг дублирования обработчика, но это не сработало.

Есть идеи ? Любая помощь будет высоко оценен.

Спасибо.

Mironovtlt


Рег
23 Jul, 2013

Тем
78

Постов
192

Баллов
582
  • 19, May 2024
  • #2
Я наконец получил это. Не знаю, интересно ли вам, но вот оно:
 DELIMITER &&

CREATE trigger mytrigger before insert on E for each row

begin

declare x,y,z,double int;
declare dou_reg condition for 1062;

declare continue handler for dou_reg
 begin
set double = 0;
 end;

set double = 1;

 set foreign_key_checks = 0;

insert into A(name_a, surname_a) values(new.name_a, new.surname_a);

set x= last_insert_id();

 if double = 0 then
 select distinct id_a from A where name_a=new.name_a and surname_a=new.surname_a into x;
 set double = 1;
 end if;

insert into B(name_b, surname_b) values (new.name_b, new.surname_b);

set y= last_insert_id();

 if double = 0 then
 select distinct id_b from B where name_b=new.name_b and surname_b=new.surname_b into y;
 set double = 1;
 end if;

insert into C (cab) values (new.cab);

set z= last_insert_id();

 if double = 0 then
 select distinct id_c from C where cab=new.cab into z;
 set double = 1;
 end if;

insert into D (id_as, id_bs, id_cs, dt) values (x,y,z,(concat(dat,' ',ora)));

SET FOREIGN_KEY_CHECKS=1;

end&&
Код (разметка):
 

Coldrex


Рег
01 Feb, 2014

Тем
66

Постов
209

Баллов
549
  • 01, Jun 2024
  • #3
Спасибо за ваше сообщение.

Я работаю над этим проектом, поэтому все эти таблицы необходимы.

Это не точная структура таблиц (имена и длина столбцов), потому что это уже длинный пост, и я не хотел делать его еще длиннее, а если быть точным: таблица A содержит список врачей, таблица B — список врачей.

Таблица пациентов C список кабинетов Таблица D список с днями и часами посещения, а также внешний ключ и таблица E содержит врачей, пациентов, кабинеты и информацию о посещениях.

Я уже два дня ломаю голову, пытаясь решить эту проблему с внешним ключом, но просто не могу этого сделать.
 

Lesnik59


Рег
07 Nov, 2011

Тем
79

Постов
202

Баллов
607
  • 03, Jun 2024
  • #4
Ну, этот триггер не завершен. Вам также придется вставить фактические значения, которые вам нужны, в таблицу D? И вам нужно будет извлечь последний идентификатор вставки - в настоящее время, я думаю, все, что вы делаете, это извлекаете все идентификаторы из разных таблиц, в которые вы вставили По сути, после обеих этих вставок, когда у вас есть значения как для x, так и для y, просто выполните новую вставку в последнюю таблицу? Разве это не должно сработать?
 

Sereda_V_V


Рег
20 Mar, 2011

Тем
48

Постов
215

Баллов
455
  • 04, Jun 2024
  • #5
Как выглядит триггер, который у вас сейчас есть? Проблема, вероятно, в том, что у вас нет прямого доступа к идентификаторам, необходимым для заполнения полей внешнего ключа из таблицы E (где находится триггер, если я не ошибаюсь) - вам нужен многослойный триггер, который вводит данные в другие таблицы, затем извлекает эти NEW.id_X и помещает их в столбцы внешних ключей.
 

Liolikavna


Рег
01 Jan, 2011

Тем
58

Постов
208

Баллов
538
  • 09, Jun 2024
  • #6
Что ж, этот триггер не очень хорош, потому что я не могу вставить набор результатов в переменную(y). Но я думаю, что это часть решения, используя переменную обработчика (x).

Когда x = 1, это означает, что существует повторяющаяся запись, и единственный способ получить идентификатор - это выбрать, когда x = 0 это означает, что повторяющейся записи нет, и я должен иметь возможность получить идентификатор с помощью Last_insert_id() . Я не знаю, как это написать.

На данный момент для меня это слишком много. Я знаю, что триггер не завершен, но не знаю, как его завершить.
 

Mega182


Рег
02 Jan, 2014

Тем
79

Постов
187

Баллов
602
  • 10, Jun 2024
  • #7
Я немного запутался, а нужны ли все эти таблицы? Мне просто интересно, какова цель таблиц.

Кажется, вы сохраняете одни и те же значения в нескольких местах (если я не ошибаюсь и есть одна таблица для загруженных файлов, а другая для загруженных или что-то в этом роде?), что никогда не является хорошей идеей.

Кроме того, сохранение имен (имени и фамилии) в формате varchar(50) кажется мне возможной ловушкой.

Да, не так уж много людей используют свое полное имя, если оно содержит более 100 символов, но иногда у людей, например, есть несколько имен, и это может быстро преодолеть 50 символов.

Не большая проблема, просто потенциальная проблема.
 

ИГPOK


Рег
01 Jan, 2011

Тем
80

Постов
204

Баллов
624
  • 12, Jun 2024
  • #8
Итак, по сути, это база данных «многие ко многим».

Однако, если структура такая, как вы сказали, ее, вероятно, можно было бы немного минимизировать.

Таблица А:

Информация о докторе

идентификатор, имя, фамилия

Таблица Б:

Информация о пациенте

идентификатор, имя, фамилия (почему здесь полное имя?)

Таблица С:

Информация о кабинете

удостоверение личности, такси

Таблица Д:

Таблица посещений.

Я не понимаю, почему вы все так усложняете?

идентификатор, врач, пациент, кабинет и дата-время

заполняется автоматически увеличивающимся первичным ключом, Doctor_id, Patient_id, Cabinet_id и DateTime

Таблица Е:

идентификатор, дата и время, врач, пациент, кабинет

заполняется автоматически увеличивающимся первичным ключом, датой и временем из таблицы d, Doctor_id, Patient_id и Cabinet_id

(однако эту последнюю таблицу можно полностью пропустить и просто получить информацию на основе объединений при извлечении данных)

Я думаю, что это было бы и быстрее, и проще, поскольку вы просто используете идентификаторы из других таблиц и не сохраняете данные несколько раз - вам, конечно, при извлечении из таблицы E придется выполнить соединение.

в других таблицах, чтобы получить из них необходимую информацию и получить фактически имена, а не просто идентификатор.

Объединения являются более дорогостоящими, но если вы не планируете извлекать тысячи записей, это не должно быть такой уж большой проблемой? И какова необходимость ограничений внешнего ключа в таблице D?
 

Uakilller


Рег
01 Jan, 2011

Тем
74

Постов
192

Баллов
592
Тем
403,760
Комментарии
400,028
Опыт
2,418,908

Интересно