Funkcja Sleep W ORACLE

Muszę wykonać zapytanie SQL w ORACLE, zajmuje to pewną ilość czasu. Więc napisałem tę funkcję:

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;

I wołam w ten sposób

SELECT TEST_SLEEP(10.5) FROM DUAL
Ale do pracy potrzebuję set grant of DBMS_LOCKdo właściciela procedury.

Jak mogę przepisać tę funkcję bez użycia funkcji DBMS_LOCK.sleep?

Author: Lukasz Szozda, 2010-04-01

10 answers

Poza przyznaniem dostępu do DBMS_LOCK.sleep, to zadziała, ale to straszny hack:

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;
 37
Author: OMG Ponies,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-04 21:59:06

Utwórz procedurę, która po prostu wykonuje blokadę i zainstaluj ją u innego użytkownika, który jest" zaufany " z dbms_lock( USERA), przyznaj użytkownikowi dostęp do dbms_lock.

Następnie po prostu przyznaj USERB dostęp do tej funkcji. Następnie nie będą musieli mieć dostępu do DBMS_LOCK

(Upewnij się, że nie masz usera i userb w systemie przed uruchomieniem tego)

Połącz się jako użytkownik z Grantem privs dla dbms_lock i możesz tworzyć użytkowników

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 */
 20
Author: Matthew Watson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-02 01:09:10

Jeśli zostanie wykonana w "sqlplus" , możesz wykonać polecenie systemu operacyjnego hosta "sleep":

!sleep 1

Lub

host sleep 1
 5
Author: metatechbe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-08 09:24:22

Co jest z kodem Javy owiniętym procedurą? Proste i działa dobrze.

CREATE OR REPLACE AND COMPILE JAVA SOURCE NAMED SNOOZE AS
public final class Snooze {
  private Snooze() {
  }
  public static void snooze(Long milliseconds) throws InterruptedException {
      Thread.sleep(milliseconds);
  }
}

CREATE OR REPLACE PROCEDURE SNOOZE(p_Milliseconds IN NUMBER) AS
    LANGUAGE JAVA NAME 'Snooze.snooze(java.lang.Long)';
 4
Author: MacTouch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-23 14:03:55

Lepiej zaimplementować mechanizm synchronizacji. Najłatwiej jest napisać plik po zakończeniu pierwszego pliku. Więc masz akta Sentinela.

Więc zewnętrzne programy szukają pliku sentinel, aby istniał. Kiedy to robi, wie, że może bezpiecznie korzystać z danych w prawdziwym pliku.

Innym sposobem, który jest podobny do tego, jak robią to niektóre przeglądarki podczas pobierania plików, jest posiadanie pliku o nazwie base-name_part, dopóki plik nie zostanie całkowicie pobrany i następnie na końcu Zmień nazwę pliku na base-name. W ten sposób zewnętrzny program nie może "zobaczyć" pliku, dopóki nie zostanie ukończony. Ten sposób nie wymagałby przepisania zewnętrznego programu. Co może pomóc w tej sytuacji.

 3
Author: Bozon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-25 22:00:23

Z Oracle 18c można użyć DBMS_SESSION.SEN procedura:

Procedura ta zawiesza sesję na określony czas.

DBMS_SESSION.SLEEP (seconds  IN NUMBER)

DBMS_SESSION.sleep jest dostępny dla wszystkich sesji bez dodatkowych dotacji. Należy pamiętać, że {[3] } jest przestarzały.

Jeśli potrzebujesz prostego snu zapytań, możesz użyć WITH FUNCTION:

WITH FUNCTION my_sleep(i NUMBER)
RETURN NUMBER
BEGIN
    DBMS_SESSION.sleep(i);
    RETURN i;
END;
SELECT my_sleep(3) FROM dual;
 3
Author: Lukasz Szozda,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-02 21:18:35

Jeśli Java jest zainstalowana na Twoim 11G, możesz to zrobić w klasie java i wywołać ją z twojego PL / SQL, ale nie jestem pewien, czy nie wymaga to również specjalnego grantu, aby wywołać Javę.

 1
Author: Matthieu BROUILLARD,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-01 15:53:19

Wygląda na to, że procedura/funkcja Javy może działać. Ale dlaczego nie skompilujesz swojej funkcji pod użytkownikiem takim jak schemat aplikacji lub konto administratora, które ma tę dotację i po prostu przyznaj swoje konto programisty na nim wykonaj. W ten sposób używane są prawa definera.

 1
Author: Kuberchaun,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-01 16:03:03

Możesz użyć DBMS_PIPE.SEND_MESSAGE z wiadomością, która jest zbyt duża dla potoku, na przykład dla 5-sekundowego opóźnienia napisz XXX do potoku, który może zaakceptować tylko jeden bajt, używając 5-sekundowego limitu czasu, jak poniżej

dbms_pipe.pack_message('XXX');<br>
dummy:=dbms_pipe.send_message('TEST_PIPE', 5, 1);

Ale to wymaga dotacji dla {[2] } więc może nie lepiej.

 1
Author: The love dada,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-08 20:52:09

Jest dobry artykuł na ten temat: PL / SQL: Sleep without using DBMS_LOCK który mi pomógł. Użyłem opcji 2 zapakowanej w niestandardowe opakowanie. Proponowane rozwiązania to:

Opcja 1: APEX_UTIL.sleep

Jeśli Apex jest zainstalowany, możesz użyć procedury "PAUSE" z publicznie dostępnego pakietu APEX_UTIL.

Przykład - "poczekaj 5 sekund":

SET SERVEROUTPUT ON ;
BEGIN
    DBMS_OUTPUT.PUT_LINE('Start ' || to_char(SYSDATE, 'YYYY-MM-DD HH24:MI:SS'));
    APEX_UTIL.PAUSE(5);
    DBMS_OUTPUT.PUT_LINE('End   ' || to_char(SYSDATE, 'YYYY-MM-DD HH24:MI:SS'));
END;
/

Opcja 2: java.lang.Nić.sleep

Inną opcją jest użycie metody" sleep "z klasy Java "Thread" , którą można łatwo wykorzystać poprzez dostarczenie prostej procedury owijania PL / SQL:

Uwaga: proszę pamiętać, że " wątek.sen " używa milisekund!

--- create ---
CREATE OR REPLACE PROCEDURE SLEEP (P_MILLI_SECONDS IN NUMBER) 
AS LANGUAGE JAVA NAME 'java.lang.Thread.sleep(long)';

--- use ---
SET SERVEROUTPUT ON ;
BEGIN
    DBMS_OUTPUT.PUT_LINE('Start ' || to_char(SYSDATE, 'YYYY-MM-DD HH24:MI:SS'));
    SLEEP(5 * 1000);
    DBMS_OUTPUT.PUT_LINE('End   ' || to_char(SYSDATE, 'YYYY-MM-DD HH24:MI:SS'));
END;
/
 1
Author: dominik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-05 15:22:17