Функция сна в Oracle

Я должен выполнить SQL-запрос в Oracle, она берет определенное количество времени. Таким образом, я записал эту функцию:

CREATE OR REPLACE FUNCTION MYSCHEMA.TEST_SLEEP
(
TIME_  IN  NUMBER
)
RETURN INTEGER IS
 BEGIN
   DBMS_LOCK.sleep(seconds => TIME_);
RETURN 1;
 EXCEPTION
   WHEN OTHERS THEN
   RAISE;
   RETURN 1;
END TEST_SLEEP;

и я звоню таким образом

SELECT TEST_SLEEP(10.5) FROM DUAL

но работать я должен установить предоставление DBMS_LOCK владельцу процедуры.

Как я могу переписать эту функцию, не используя DBMS_LOCK.sleep функция?

30
задан Lukasz Szozda 2 March 2018 в 21:21
поделиться

4 ответа

За исключением предоставления доступа к DBMS_LOCK.sleep , это будет работать, но это ужасный взлом:

IN_TIME INT; --num seconds
v_now DATE;

-- 1) Get the date & time 
SELECT SYSDATE 
  INTO v_now
  FROM DUAL;

-- 2) Loop until the original timestamp plus the amount of seconds <= current date
LOOP
  EXIT WHEN v_now + (IN_TIME * (1/86400)) <= SYSDATE;
END LOOP;
41
ответ дан 27 November 2019 в 23:09
поделиться

Если Java установлена на вашем 11G, то вы можете сделать это в классе java и вызвать его из вашего PL/SQL, но я не уверен, что это не требует также специального гранта для вызова java.

1
ответ дан 27 November 2019 в 23:09
поделиться

Кажется, что java процедура/функция может работать. Но почему бы вам не скомпилировать вашу функцию под пользователем, например, под схемой приложения или учетной записью администратора, которая имеет этот грант, и просто дать вашей учетной записи разработчика право на выполнение. Таким образом, используются права разработчика.

1
ответ дан 27 November 2019 в 23:09
поделиться

Создайте процедуру, которая просто делает вашу блокировку и установите ее другому пользователю, которому "доверяют" dbms_lock ( USERA ), предоставьте USERA доступ к dbms_lock.

Затем просто предоставьте USERB доступ к этой функции. Затем им не нужно будет иметь доступ к DBMS_LOCK

(убедитесь, что в вашей системе нет usera и userb, прежде чем выполнять это)

Подключитесь как пользователь с правами на dbms_lock и можете создавать пользователей

drop user usera cascade;
drop user userb cascade;
create user usera default tablespace users identified by abc123;
grant create session to usera;
grant resource to usera;
grant execute on dbms_lock to usera;

create user userb default tablespace users identified by abc123;
grant create session to userb;
grant resource to useb

connect usera/abc123;

create or replace function usera.f_sleep( in_time number ) return number is
begin
 dbms_lock.sleep(in_time);
 return 1;
end;
/

grant execute on usera.f_sleep to userb;

connect userb/abc123;

/* About to sleep as userb */
select usera.f_sleep(5) from dual;
/* Finished sleeping as userb */

/* Attempt to access dbms_lock as userb.. Should fail */

begin
  dbms_lock.sleep(5);
end;
/

/* Finished */
22
ответ дан 27 November 2019 в 23:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: