Другой способ сделать это - забыть о триггерах, но использовать VIEW...WITH CHECK OPTION
, чтобы контролировать, что никто не вставляет данные, которые они не должны.
Предположим, ваша таблица конфигурации выглядит следующим образом:
CREATE TABLE my_config
( owner VARCHAR2(30) NOT NULL,
table_name VARCHAR2(30) NOT NULL,
other_stuff VARCHAR2(500),
CONSTRAINT my_config_pk PRIMARY KEY ( owner, table_name ) );
Создание представления для обработки вставок
Условия представления ограничивают его только таблицами, для которых у текущего пользователя есть права DELETE
.
WITH CHECK OPTION
гарантирует, что никто не может использовать представление для вставки или обновления данных, которые не удовлетворяют представлению.
CREATE VIEW my_config_ins_v
AS
SELECT * FROM my_config c
WHERE EXISTS ( SELECT 'user has delete privs'
FROM user_tab_privs p
WHERE p.owner = c.owner
AND p.grantee = user
AND p.table_name = c.table_name
AND p.privilege = 'DELETE' )
WITH CHECK OPTION;
Попробуйте это
INSERT INTO my_config_ins_v VALUES ('USER_1','TABLE_I_HAVE_ACCESS_TO', 'STUFF');
-- 1 row inserted.
INSERT INTO my_config_ins_v VALUES ('SYS','OBJ$', 'STUFF');
-- ORA-01402: view WITH CHECK OPTION where-clause violation
Естественно, чтобы это было эффективным, вы не можете
GRANT INSERT ON my_config TO anyone; -- don't do this
Вместо того, чтобы:
GRANT INSERT ON my_config_ins_v TO anyone;