Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Oracle [игнор отключен] [закрыт для гостей] / помощь в проверке данных перед вставкой / 13 сообщений из 13, страница 1 из 1
13.05.2017, 19:33
    #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
13.05.2017, 22:44
    #39452632
помощь в проверке данных перед вставкой
a.sonnova,

Только триггером невозможно обеспечить промежцелкостность в конкурентной среде. Вместо учителя, в таблице расписаний используй ссыль на "сопоставления".
...
Рейтинг: 0 / 0
14.05.2017, 07:07
    #39452654
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помощь в проверке данных перед вставкой
a.sonnovaНужно написать триггерRTFM Data Integrity (FAQ)
...
Рейтинг: 0 / 0
14.05.2017, 12:58
    #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
14.05.2017, 14:37
    #39452728
dbms_photoshop
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помощь в проверке данных перед вставкой
vanequeНалицо фундаментальное непонимание принципов целостности БД и работы с триггерами :)Твой триггер может создавать только иллюзию целостности.
...
Рейтинг: 0 / 0
14.05.2017, 17:28
    #39452764
vaneque
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помощь в проверке данных перед вставкой
dbms_photoshop,

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

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

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

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

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

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

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

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

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

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

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

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


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