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_LOCK
do właściciela procedury.
Jak mogę przepisać tę funkcję bez użycia funkcji DBMS_LOCK.sleep
?
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;
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 */
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
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)';
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.
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;
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ę.
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.
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.
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;
/
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