40

ORACLE で SQL クエリを実行する必要があり、一定の時間がかかります。だから私はこの関数を書きました:

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ですか?

4

11 に答える 11

53

へのアクセスを許可することを除いて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;
于 2010-04-01T16:05:36.847 に答える
22

ロックを行うだけのプロシージャを作成し、それを 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 */
于 2010-04-02T01:09:10.730 に答える
8

「sqlplus」内で実行すると、ホスト オペレーティング システム コマンド「sleep」を実行できます。

!sleep 1

また

host sleep 1
于 2013-07-08T09:24:22.557 に答える
5

プロシージャーでラップされた Java コードについてはどうですか? シンプルでうまく機能します。

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)';
于 2017-10-23T14:03:55.920 に答える
1

パイプには大きすぎるメッセージで使用できますDBMS_PIPE.SEND_MESSAGE。たとえば、5 秒の遅延の場合、次のように 5 秒のタイムアウトを使用して 1 バイトのみを受け入れることができるパイプに XXX を書き込みます。

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

しかし、それには助成金が必要なDBMS_PIPEので、おそらくそれ以上のことはありません.

于 2013-01-08T20:29:56.967 に答える
1

Java が 11G にインストールされている場合は、Java クラスで実行して PL/SQL から呼び出すことができますが、Java を呼び出すために特定の許可も必要としないかどうかはわかりません。

于 2010-04-01T15:53:19.527 に答える
1

Java プロシージャ/関数が機能するようです。しかし、アプリケーション スキーマのようなユーザーや、この許可を持つ管理者アカウントの下で関数をコンパイルして、開発者アカウントに実行を許可してみませんか。このようにして、定義者権限が使用されます。

于 2010-04-01T16:03:03.153 に答える