:: Не фоксом единым
Oracle Trigger
PaulWist
Автор

Сообщений: 14618
Дата регистрации: 01.04.2004
Спрошу, может кто сталкивался.

Как заставить в триггере работать dynamic-sql или если есть возможность использовать PRIVATE TEMPORARY TABLE без динамики?

На инструкции EXECUTE IMMEDIATE получаю ошибку - ORA-01031: привилегий недостаточно.

Какие права нужны и как их назначить?

create or replace TRIGGER MyTrigger
FOR INSERT OR UPDATE ON MyTable
COMPOUND TRIGGER
declare cSql varchar(200);
before statement
is
begin
cSql := 'CREATE PRIVATE TEMPORARY TABLE ora$ptt_my_temp_table (
ID NUMBER,
description VARCHAR2(20)
)
ON COMMIT DROP DEFINITION';
EXECUTE IMMEDIATE cSql;
end before statement;
...
END

Что в итоге пытаюсь получить, возможно есть другой способ.

В триггере необходимо получить записи затронутые командой DML.

-- Табличка
create table test (f1 NUMBER NOT NULL ENABLE);
-- Табличка лога
create table test1 (f1 NUMBER NOT NULL ENABLE, f2 NVARCHAR2);
-- Заполняем
insert into test (f1) values (1);
insert into test (f1) values (1);
insert into test (f1) values (2);
insert into test (f1) values (2);
-- Модифицируем
update test set f1 = f1

те в табличку лога записать при update по одной записи из таблички test (distinct, те что бы там было две записи f1 = 1, 2), как это можно сделать в триггере?


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)




Исправлено 1 раз(а). Последнее : PaulWist, 24.01.22 09:28
Ratings: 0 negative/0 positive
Re: Oracle Trigger
ВладимирС

Сообщений: 1693
Дата регистрации: 03.11.2005
Спрошу:
TRIGGER на какую таблицу test ?

А то таблицы MyTable не отражено...
Ratings: 0 negative/0 positive
Re: Oracle Trigger
PaulWist
Автор

Сообщений: 14618
Дата регистрации: 01.04.2004
ВладимирС
Спрошу:
TRIGGER на какую таблицу test ?

А то таблицы MyTable не отражено...

Да на табличку test/

В принципе пока выкрутился через Global Temporary Table, НО это надо создавать таблицу в БД, не по фенщую это.


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)
Ratings: 0 negative/0 positive
Re: Oracle Trigger
ВладимирС

Сообщений: 1693
Дата регистрации: 03.11.2005
В принципе мы в одном проекте и использовали Global Temporary Table с ON COMMIT DELETE ROWS...
Ratings: 0 negative/0 positive
Re: Oracle Trigger
PaulWist
Автор

Сообщений: 14618
Дата регистрации: 01.04.2004
ВладимирС
В принципе мы в одном проекте и использовали Global Temporary Table с ON COMMIT DELETE ROWS...

Если не сумею запустить Private Table, то придётся использовать Global.

Кстати, как в триггере из одной схемы обратиться к ф-ии другой схемы, какие нужны права??

Код в ТРИГГЕРЕ примерно такой:

Цитата:
update MySch.MyTable
set f1 = OtherSch.Func(MyTable.ID);


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)




Исправлено 2 раз(а). Последнее : PaulWist, 24.01.22 12:13
Ratings: 0 negative/0 positive
Re: Oracle Trigger
ВладимирС

Сообщений: 1693
Дата регистрации: 03.11.2005
>>какие нужны права ?
Права на EXECUTE FUNCTION
Ratings: 0 negative/0 positive
Re: Oracle Trigger
ВладимирС

Сообщений: 1693
Дата регистрации: 03.11.2005
Хм...
Не знаю, но я бы без Global Temporary Table пользовался:
CREATE TABLE TEST.MY_TEST
(
F1 NUMBER(38) NOT NULL
);
CREATE TABLE TEST.MY_TEST1
(
F1 NUMBER(38) NOT NULL,
F2 VARCHAR2(100 BYTE)
);
CREATE OR REPLACE TRIGGER TEST.TRG_MY_TEST_UPD
AFTER UPDATE ON TEST.MY_TEST
REFERENCING NEW AS New OLD AS Old
FOR EACH ROW
DECLARE
l_cnt NUMBER;
BEGIN
SELECT COUNT(*) INTO l_cnt FROM TEST.MY_TEST1 T1 WHERE T1.F1 = :Old.F1;
IF l_cnt = 0 THEN
INSERT INTO TEST.MY_TEST1 (F1) VALUES (:Old.F1);
END IF;
END TRG_MY_TEST_UPD;
/
insert into TEST.MY_TEST (f1) values (1);
insert into TEST.MY_TEST (f1) values (1);
insert into TEST.MY_TEST (f1) values (2);
insert into TEST.MY_TEST (f1) values (2);
update TEST.MY_TEST set f1 = f1;
И тоже 2 записи в MY_TEST1...
Но лучше в этом случае индексы на F1 повесить...
Ratings: 0 negative/0 positive
Re: Oracle Trigger
PaulWist
Автор

Сообщений: 14618
Дата регистрации: 01.04.2004
права на Execute есть, всё равно пишет нет привелегий.


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)
Ratings: 0 negative/0 positive
Re: Oracle Trigger
ВладимирС

Сообщений: 1693
Дата регистрации: 03.11.2005
Скрипт схемы можно увидеть ?
Ratings: 0 negative/0 positive
Re: Oracle Trigger
ВладимирС

Сообщений: 1693
Дата регистрации: 03.11.2005
В схеме OtherSch должно быть прописано что-то в этом роде:
GRANT EXECUTE ON OtherSch.Func TO MySch;
Ну и соответственно GRANT-ы на чтение таблиц, что в функции OtherSch.Func...



Исправлено 1 раз(а). Последнее : ВладимирС, 24.01.22 12:50
Ratings: 0 negative/0 positive
Re: Oracle Trigger
PaulWist
Автор

Сообщений: 14618
Дата регистрации: 01.04.2004
Те если я выполняю

select OtherSch.Func() from MySch.MyTAble

выборка происходит без проблем.

Но если OtherSch.Func() использовать в триггере, то прав не хватает.


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)
Ratings: 0 negative/0 positive
Re: Oracle Trigger
ВладимирС

Сообщений: 1693
Дата регистрации: 03.11.2005
Хм... может ИК подскажет...
Ratings: 0 negative/0 positive
Re: Oracle Trigger
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
По триггеру - аудиты/логи предпочтительнее делать через row-level триггера. При этом я не вижу надобности ни в каких временных таблицах вообще. Динамический SQL тоже не стоит без особой надобности использовать.

По правам - без кода ничего сказать нельзя. Не видно ни в каком режиме создана эта функция (invoker rights vs definer rights), ни какой там внутри код (к чему она обращается и как), ни как даны права на исполнение этой функции - напрямую или через роль, ни какую именно ошибку выдаёт сервер... В общем слишком мало информации.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Oracle Trigger
PaulWist
Автор

Сообщений: 14618
Дата регистрации: 01.04.2004
Всё, разобрался.

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


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)
Ratings: 0 negative/0 positive
Re: Oracle Trigger
ВладимирС

Сообщений: 1693
Дата регистрации: 03.11.2005
PaulWist
Всё, разобрался.
Что бы выполнить в триггере одной схемы ф-ию из другой схемы, надо дать прямые права EXECUTE владельцу схемы с триггером, если дать права EXECUTE роли в которую входит владелец схемы с триггеров, то не взлетает.
А конкретно скрипт можно показать ?
Ratings: 0 negative/0 positive
Re: Oracle Trigger
PaulWist
Автор

Сообщений: 14618
Дата регистрации: 01.04.2004
Тут и простой select не взлетает если нет "прямых" прав или я что-то неправильно приготовил.

-- Юзеры
CREATE USER "MYUSER" IDENTIFIED BY 123 ;
CREATE USER "OTHERUSER" IDENTIFIED BY 123 ;
-- Права на вход
GRANT "CONNECT" TO "MYUSER" ;
-- не обязательно
GRANT "CONNECT" TO "OTHERUSER" ;
-- Ф-ия
create or replace function OTHERUSER.testfunc(f1 varchar2)
RETURN VARCHAR2
IS
BEGIN
RETURN f1;
END;
-- Роль
create role MYROLE;
-- Права роли
grant execute on OTHERUSER.testfunc to MYROLE;
-- Добавляем в роль юзера
grant MYROLE to MYUSER;
ALTER USER MYUSER DEFAULT ROLE MYROLE, CONNECT;
-- Выполняем от имени MYUSER
select OTHERUSER.testfunc(1) as aa from dual;
-- Ошибка
-- ORA-00904: "OTHERUSER"."TESTFUNC": недопустимый идентификатор
-- 00904. 00000 - "%s: invalid identifier"
-- Убираем у роли EXECUTE
revoke execute on OTHERUSER.testfunc from MYROLE;
-- Разрешаем для MYUSER выполнять ф-ию в другой схеме
grant execute on OTHERUSER.testfunc to MYUSER;
-- Выполняем от имени MYUSER
select OTHERUSER.testfunc(1) as aa from dual;
-- Получаем '1'
-- revoke execute on OTHERUSER.testfunc from MYUSER;


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)




Исправлено 3 раз(а). Последнее : PaulWist, 26.01.22 16:42
Ratings: 0 negative/0 positive
Re: Oracle Trigger
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
PaulWist
Всё, разобрался.
Что бы выполнить в триггере одной схемы ф-ию из другой схемы, надо дать прямые права EXECUTE владельцу схемы с триггером, если дать права EXECUTE роли в которую входит владелец схемы с триггеров, то не взлетает.
Именно так - в контексте PL/SQL кода работающего в режиме definer rights роли явно отключены, и актуальны лишь права данные непосредственно пользователю (схеме). В варианте хранимого кода работающего в режиме invoker rights (а это так же включает "анонимные блоки pl/sql кода") - код "наследует" права доступа того кто его вызывает (т.е. текущего пользователя) - естественно это имеет свои отрицательные моменты.
Скажем дав права на ХП schemeA.Log() другой схеме, можно не беспокоиться о том что именно делает внутри себя эта ХП - она будет иметь доступ ко всем объектам схемы schemeA - т.к. авторизуется как schemeA. Если же определить её с опцией AUTHID CURRENT_USER, то она уже будет работать как будто создана и запускается в схеме того кто её вызывает. И права на объекты "якобы своей" схемы она не получит, и собственно не полностью квалифицированные имена объектов (имя таблицы без префикса схемы, к примеру) будут разрешаться относительно схемы того кто ХП вызвал - включая, к слову, динамический SQL.


------------------
WBR, Igor
Ratings: 0 negative/1 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 7 (Гостей: 7)

© 2000-2024 Fox Club 
Яндекс.Метрика