powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / помощь в проверке данных перед вставкой
13 сообщений из 13, страница 1 из 1
помощь в проверке данных перед вставкой
    #39452610
a.sonnova
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Необходима помощь в проверке данных перед вставкой. Никак не могу придумать, как осуществить ее.

Существуют таблицы Расписание(Schedule), Учитель(Teacher), Предмет(Subject) и таблица для сопоставления какой учитель ведет предмет(Subteacher(здесь всего три колонки:n_subteacher-первичный ключ, идентификатор и номера учителя и предмета)).
Есть связь между таблицами расписание-учитель и предмет, предмет и subteacher, учитель и subteacher. Нужно написать триггер перед вставкой в расписание на то, ведёт ли учитель данный предмет или нет

Попыталась написать, но он не срабатывает:

CREATE OR REPLACE TRIGGER subteach
BEFORE
INSERT OR UPDATE
ON schedule
FOR EACH ROW
DECLARE
one NUMBER;
two NUMBER;
BEGIN
SELECT a.n_subteacher INTO one FROM subteacher a
WHERE a.N_teacher=(select n_teacher from schedule)
AND
SELECT a.n_subteacher INTO two FROM subteacher a
WHERE a.N_subject=(select N_subject from schedule);
IF one!=two THEN
raise_application_error('Учитель не ведёт предмет');
END IF;
END;
...
Рейтинг: 0 / 0
помощь в проверке данных перед вставкой
    #39452632
a.sonnova,

Только триггером невозможно обеспечить промежцелкостность в конкурентной среде. Вместо учителя, в таблице расписаний используй ссыль на "сопоставления".
...
Рейтинг: 0 / 0
помощь в проверке данных перед вставкой
    #39452654
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a.sonnovaНужно написать триггерRTFM Data Integrity (FAQ)
...
Рейтинг: 0 / 0
помощь в проверке данных перед вставкой
    #39452704
vaneque
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a.sonnova,

Ох, мне бы такие простые задачки давали на работе... :)

1)Subteacher - плохое название для таблицы связей между учителями и предметами, я подумал сначала, что это какой-то помощник учителя. Лучше бы тогда было сделать что-то типа link_teachers_subjects или teachers_subjects_parity или хотя бы просто teachers_subjects.

2)a.sonnova Попыталась написать, но он не срабатывает:

Ну, логично, там мало того, что некорректный синтаксис, так и логика некорректная. Налицо фундаментальное непонимание принципов целостности БД и работы с триггерами :) Где ты обрабатываешь параметры инсерт запроса в теле триггера? Нигде. Получается, что триггер будет вызываться перед выполнением каждого инсерта или апдейта и при этом будет принимать решение о том, разрешать вставлять/обновлять запись или нет на основе данных, которые уже закоммичены в БД, а не на основе данных, которые присланы в качестве аргументов DML операции.
3)В триггере идет попытка получить первичные ключи, сохранить их в переменные one и two, потом проверка на равенство. Это очень странное решение. А если преподаватель ведет несколько предметов? Oracle будет ожидать скалярное значение, придет множество, будет ошибка.
4)Если преподаватель может вести несколько предметов, то надо сделать так:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
CREATE OR REPLACE TRIGGER trg_schedule
BEFORE INSERT OR UPDATE ON schedule
FOR EACH ROW
DECLARE
  flag NUMBER;
BEGIN
  select case 
    when exists
      (select null from teachers_subjects where teacher_id=:new.teacher_id and subject_id=:new.subject_id)
    then 1
    else 0
    end into flag from dual;
  if (flag=0) then
    raise_application_error('-20000','Teacher with id='||:new.teacher_id||' doesn''t teach the subject with id='||:new.subject_id);
  end if;
END;
/



Обрати внимание на :new - это ссылка на запись, которую ты пытаешься вставить/обновить.

То, что ты пыталась сделать можно переписать на корректный pl/sql, но я бы такую работу не принял точно, объяснил, почему в пункте 3.

Скрипты, которые я использовал для теста:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
--drop table teacher cascade constraints purge;
--drop table subject cascade constraints purge;
--drop table teachers_subjects cascade constraints purge;
--drop table schedule cascade constraints purge;

create table teacher(id number primary key, fullname varchar2(50) not null);
insert into teacher(id, fullname) values(1, 'Marivanna');
insert into teacher(id, fullname) values(2, 'Sansanych');
create table subject(id number primary key, discipline_name varchar2(30) not null);
insert into subject(id, discipline_name) values(1, 'Math');
insert into subject(id, discipline_name) values(2, 'Geography');
insert into subject(id, discipline_name) values(3, 'Chemistry');
create table teachers_subjects (id number primary key, teacher_id number references teacher(id) not null, subject_id number references subject(id) not null);
insert into teachers_subjects (id, teacher_id, subject_id) values (1,1,1);
insert into teachers_subjects (id, teacher_id, subject_id) values (2,2,2);
create table schedule(id number primary key, teacher_id number references teacher(id) not null, subject_id number references subject(id) not null, begin_datetime date not null, end_datetime date not null);

CREATE OR REPLACE TRIGGER trg_schedule
BEFORE INSERT OR UPDATE ON schedule
FOR EACH ROW
DECLARE
  flag NUMBER;
BEGIN
  select case 
    when exists
      (select null from teachers_subjects where teacher_id=:new.teacher_id and subject_id=:new.subject_id)
    then 1
    else 0
    end into flag from dual;
  if (flag=0) then
    raise_application_error('-20000','Teacher with id='||:new.teacher_id||' doesn''t teach the subject with id='||:new.subject_id);
  end if;
END;
/

delete from schedule;

insert into schedule (id, teacher_id, subject_id, begin_datetime, end_datetime) values (1,1,1,sysdate,sysdate+5/1440);
insert into schedule (id, teacher_id, subject_id, begin_datetime, end_datetime) values (2,2,2,sysdate,sysdate+5/1440);
insert into schedule (id, teacher_id, subject_id, begin_datetime, end_datetime) values (3,1,2,sysdate,sysdate+5/1440);
update schedule set subject_id = 3 where teacher_id=1;
...
Рейтинг: 0 / 0
помощь в проверке данных перед вставкой
    #39452728
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vanequeНалицо фундаментальное непонимание принципов целостности БД и работы с триггерами :)Твой триггер может создавать только иллюзию целостности.
...
Рейтинг: 0 / 0
помощь в проверке данных перед вставкой
    #39452764
vaneque
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dbms_photoshop,

Вот чем меня всегда "радовал" форум sql.ru, так это изобилием невсебешных экспертов, которые только и могут, что обосрать чужое решение и при этом ничего не предложить в качестве альтернативы. Действительно, зачем... Твое решение - говно. И точка. Я все сказал.
...
Рейтинг: 0 / 0
помощь в проверке данных перед вставкой
    #39452786
subhumans
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
vaneque,

Твою целкостность даже в одно рыло можно поломать - добавить запись в расписание, затем удалить из сопоставлений.
Чем FK не устраивает?
...
Рейтинг: 0 / 0
помощь в проверке данных перед вставкой
    #39452790
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vaneque,

Свои фантазии невсебешность, обосрать и говно лучше оставь при себе.
До твоего поста уже было дано два толковых ответа и я дал тебе намек, что не взлетит.
Если после всего непонятно почему - можно спросить прямо вместо того, чтоб сопли размазывать по форуму.
...
Рейтинг: 0 / 0
помощь в проверке данных перед вставкой
    #39452791
vaneque
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
subhumansvaneque,

Твою целкостность даже в одно рыло можно поломать - добавить запись в расписание, затем удалить из сопоставлений

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

subhumansЧем FK не устраивает?
Так а как FK решит ту же проблему, которую ты обозначил в твоем письме? Разве что если его сделать как enable novalidate
...
Рейтинг: 0 / 0
помощь в проверке данных перед вставкой
    #39452792
vaneque
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dbms_photoshop,

хорошо, извини за резкость. Поясни, пожалуйста, свою мысль.
...
Рейтинг: 0 / 0
помощь в проверке данных перед вставкой
    #39452794
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vaneque,

Выше уже ответили, если вставить в расписание, а потом удалить соответствующую строку из таблицы-развязки, то в расписании будет некорректная (не знаю как точнее перевести с английского - orphaned) запись.
Чтоб избежать делаешь развязку родительской таблицей с первичным ключом по двум полям, а расписание - дочерней.

PS. Отдельная тема - надо ли в таблице-развязке иметь суррогатный айдишник, это зависит от того как выполняется редактирование, ведется история и прочих деталей.
...
Рейтинг: 0 / 0
помощь в проверке данных перед вставкой
    #39452805
vaneque
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dbms_photoshopvaneque,

Выше уже ответили, если вставить в расписание, а потом удалить соответствующую строку из таблицы-развязки, то в расписании будет некорректная (не знаю как точнее перевести с английского - orphaned) запись.
Чтоб избежать делаешь развязку родительской таблицей с первичным ключом по двум полям, а расписание - дочерней.

PS. Отдельная тема - надо ли в таблице-развязке иметь суррогатный айдишник, это зависит от того как выполняется редактирование, ведется история и прочих деталей.

Понял теперь. Ну, это я проглядел, да, спасибо :) Просто сконцентрировался в первую очередь на триггере, а не на проектировании схемы.
...
Рейтинг: 0 / 0
помощь в проверке данных перед вставкой
    #39452812
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vanequeЕсли условитьсяВот так и выходит говнокод, базирующийся на условностях, ведомых только самому быдлокодеру.
...
Рейтинг: 0 / 0
13 сообщений из 13, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / помощь в проверке данных перед вставкой
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]