Обновление триггера для обеспечения совпадения значений в другой таблице Oracle SQL Developer - PullRequest
0 голосов
/ 10 октября 2019

Я пытаюсь найти способ убедиться, что при обновлении таблицы выполняется определенное условие. Можно ли это сделать в триггере? Я создал следующие две таблицы: storeTable и employeeTable.

Мне нужно убедиться, что при обновлении storeManager в storeTable у сотрудника есть storeID, соответствующий магазину, в котором я пытаюсь обновитьstoreManager. (сотрудник не может быть менеджером магазина, в котором он не работает)

Кроме того, мне нужно убедиться, что сотрудник существует в таблице employee. Я думал, что какой-то оператор CASE будет лучше, но я не знаю, как это может быть выполнено с помощью триггера.

Я думал о том, чтобы изменить пример триггера «Внешний ключ триггера для дочерней таблицы» из https://docs.oracle.com/cd/B12037_01/appdev.101/b10795/adfns_tr.htm#1007172 но я не мог понять, как изменить это, чтобы соответствовать моим конкретным потребностям. Любая помощь очень ценится.

Для контекста текущие ключи:

storeTable:

storeID ПЕРВИЧНЫЙ КЛЮЧ

employeeTable:

empID ПЕРВИЧНЫЙ КЛЮЧ

storeID ИНОСТРАННЫЙ КЛЮЧ ОТНОСИТСЯ К storeTable.storeID

enter image description here

enter image description here

1 Ответ

2 голосов
/ 10 октября 2019

Мне кажется, что ограничения могут сделать работу. Вам не нужны триггеры.

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

SQL> create table employee
  2    (empid        number,
  3     fname        varchar2(10),
  4     storeid      number
  5    );

Table created.

SQL> create table store
  2    (storeid      number,
  3     storename    varchar2(20),
  4     storemanager number
  5    );

Table created.

SQL>
SQL> alter table employee add constraint pk_employee  primary key (empid, storeid);

Table altered.

SQL> alter table store    add constraint pk_store     primary key (storeid);

Table altered.

SQL>
SQL> alter table store    add constraint fk_store_emp foreign key (storemanager, storeid)
  2    references employee (empid, storeid)
  3    deferrable initially deferred;

Table altered.

SQL> alter table employee add constraint fk_emp_store foreign key (storeid)
  2    references store (storeid)
  3    deferrable initially deferred;

Table altered.

SQL>

Теперь давайте добавимнекоторые данные: начальная вставка в employee будет в порядке, пока я не выполню фиксацию, а затем произойдет сбой, поскольку ее хранилище еще не существует:

SQL> insert into employee values (1, 'John' , 1);

1 row created.

SQL> commit;
commit
*
ERROR at line 1:
ORA-02091: transaction rolled back
ORA-02291: integrity constraint (SCOTT.FK_EMP_STORE) violated - parent key not
found


SQL>

Но, если я не сделаю фиксацию и обратите вниманиек тому, что я ввожу (то есть, что ссылочная целостность поддерживается), все будет в порядке:

SQL> insert into employee values (1, 'John' , 1);

1 row created.

SQL> insert into employee values (2, 'Matt' , 2);

1 row created.

SQL> insert into store values (1, 'Santa Clara', 1);

1 row created.

SQL> insert into store values (2, 'San Francisco', 2);   --> note 2 as STOREID

1 row created.

SQL> commit;

Commit complete.

SQL> select * From employee;

     EMPID FNAME         STOREID
---------- ---------- ----------
         1 John                1
         2 Matt                2

SQL> select * From store;

   STOREID STORENAME            STOREMANAGER
---------- -------------------- ------------
         1 Santa Clara                     1
         2 San Francisco                   2

SQL>

Видите? Все идет нормально.

Теперь я попытаюсь изменить таблицу STORE и установить для ее менеджера значение John, которое работает в storeid = 1, что означает, что оно должно завершиться с ошибкой:

SQL> update store set storemanager = 1
  2  where storeid = 2;

1 row updated.

SQL> commit;
commit
*
ERROR at line 1:
ORA-02091: transaction rolled back
ORA-02291: integrity constraint (SCOTT.FK_STORE_EMP) violated - parent key not
found


SQL>

Как и ожидалось.

Давайте теперь добавим emplyoee ID = 6, Jimmy, который работает в storeid = 2 и назначим его менеджером в Сан-Франциско (storeid = 2):

SQL> insert into employee values (6, 'Jimmy', 2);

1 row created.

SQL> update store set storemanager = 6
  2  where storeid = 2;

1 row updated.

SQL> commit;

Commit complete.

SQL>

Yey! Это работает!


Как видите, триггеры не нужны.

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

SQL> drop table store;
drop table store
           *
ERROR at line 1:
ORA-02449: unique/primary keys in table referenced by foreign keys


SQL> drop table employee;
drop table employee
           *
ERROR at line 1:
ORA-02449: unique/primary keys in table referenced by foreign keys


SQL>

Это означает, что сначала нужно удалить ограничения внешнего ключа, а затем таблицы:

SQL> alter table employee drop constraint fk_emp_store;

Table altered.

SQL> alter table store    drop constraint fk_store_emp;

Table altered.

SQL> drop table store;

Table dropped.

SQL> drop table employee;

Table dropped.

SQL>

Вот и все, я думаю.

...