简体   繁体   English

oracle pl/sql DBMS_LOCK 错误

[英]oracle pl/sql DBMS_LOCK error

In the Oracle PL/SQL, I want to test the sleep function. I am using hr schema.在 Oracle PL/SQL 中,我想测试睡眠 function。我使用的是 hr 模式。 but it gives me error:但它给了我错误:

PLS-00201: identifier 'DBMS_LOCK' must be declared

code:代码:

begin
 DBMS_LOCK.Sleep( 60 );
end;
/

You should grant execute on that package to your schema您应该将该包上的执行权限授予您的架构

grant execute on <object> to <user>;

eg例如

connect as sys
grant execute on SYS.DBMS_LOCK to someuser;

If you you don't have access to sys or your dba is unwilling to do如果您无权访问 sys 或者您的 dba 不愿意这样做

   GRANT EXECUTE on SYS.DBMS_LOCK to you;

You can create a Java procedure in the database:您可以在数据库中创建 Java 过程:

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

And create a function, which calls the java stored procedure并创建一个函数,调用java存储过程

 CREATE OR REPLACE FUNCTION sleep (
    seconds IN NUMBER
   ) RETURN NUMBER
   AS
   BEGIN
     SLEEPIMPL( seconds );
     RETURN seconds;
   END;

which after a之后

GRANT EXECUTE ON sleep TO public;

you can call from a select您可以从选择中调用

select sleep(6000) from dual

I came across this problem and my user did not get access on DBMS_LOCK package and as I am currently on 12c so cannot use DBMS_SESSION.SLEEP package.我遇到了这个问题,我的用户无法访问 DBMS_LOCK 包,因为我目前在 12c 上,所以不能使用DBMS_SESSION.SLEEP包。 So created the following procedure to accommodate wait time of 30 minutes.因此创建了以下过程以适应 30 分钟的等待时间。

Parameter V_START_DATE saves' current datetime.参数V_START_DATE保存当前日期时间。

Parameter V_END_DATE saves' current datetime and adds the number of minutes you want your job to wait (in this case 30/1440 adds 30 minutes).参数V_END_DATE保存“当前日期时间”并添加您希望您的作业等待的分钟数(在本例中,30/1440 增加了 30 分钟)。

WHILE loop will iterate till the end datetime, and will break if the flag is 1 or the execution exceeds the wait time specified (ie V_END_DATE > V_START_DATE) and flag value <> 1. WHILE循环将迭代到结束日期时间,如果标志为 1 或执行超过指定的等待时间(即 V_END_DATE > V_START_DATE)且标志值 <> 1,则将中断。

create or replace procedure SP_SLEEP_ALTERNATE is
  V_FLAG       INT := 0;
  V_START_DATE DATE;
  V_END_DATE   DATE;
begin

  SELECT SYSDATE INTO V_START_DATE FROM DUAL;

  SELECT SYSDATE + 30 / 1440 INTO V_END_DATE FROM DUAL;

  while V_START_DATE <= V_END_DATE LOOP
  
    BEGIN
      /* get flag from a table */
    EXCEPTION
      WHEN NO_DATA_FOUND THEN
        V_FLAG := 0;
    END;
    IF V_FLAG <> 1 THEN
    
      V_FLAG := 0;
    ELSIF V_FLAG = 1 THEN
      DBMS_OUTPUT.PUT_LINE('Execution Started');
      EXIT;
    ELSIF V_FLAG <> 1 AND V_START_DATE > V_END_DATE THEN
      EXIT;
    END IF;
  
    SELECT SYSDATE INTO V_START_DATE FROM DUAL;
  
  END LOOP;

end SP_SLEEP_ALTERNATE;

I hope it helps someone, facing the same issue.我希望它可以帮助面临同样问题的人。

DBMS_SESSION.SLEEP Replaces DBMS_LOCK.SLEEP in Oracle Database 18c DBMS_SESSION.SLEEP 替换 Oracle Database 18c 中的 DBMS_LOCK.SLEEP

The SLEEP procedure is added to the DBMS_SESSION package and deprecated from the DBMS_LOCK package in Oracle Database 18c. SLEEP 过程已添加到 DBMS_SESSION 包中,并已从 Oracle Database 18c 中的 DBMS_LOCK 包中弃用。

The SLEEP procedure is added to the DBMS_SESSION package, so it is available to all sessions with no additional grants needed and no dependency on the DBMS_LOCK package. SLEEP 过程被添加到 DBMS_SESSION 包中,因此它可用于所有会话,无需额外授权,也不依赖于 DBMS_LOCK 包。


Fails: dbms_lock.sleep(...)失败: dbms_lock.sleep(...)

with function slow_function(p_id  in number) return number
    deterministic as
begin
    dbms_lock.sleep(0.02);  --look here
    return p_id;
end;

select 
    slow_function(level)
from 
    dual
connect by level <= 20000

Error:错误:

ORA-00904: "SYS"."DBMS_LOCK": invalid identifier

Succeeds: sys.dbms_session.sleep(...)成功: sys.dbms_session.sleep(...)

with function slow_function(p_id  in number) return number
    deterministic as
begin
    --dbms_lock.sleep(0.02);
    sys.dbms_session.sleep(0.02);  --look here
    return p_id;
end;

select 
    slow_function(level)
from 
    dual
connect by level <= 20000

Result:结果:

SLOW_FUNCTION(LEVEL)
--------------------
                   1
                   1
                   1
                   1
                   1
                   1
                   1
                   1
                   1
                   1
…
10 rows of 20000

db<>fiddle db<>小提琴

Related: Why does DETERMINISTIC function return unexpected numbers in CONNECT BY LEVEL query?相关: 为什么 DETERMINISTIC 函数在 CONNECT BY LEVEL 查询中返回意外数字?


I'm not an expert, so feel free to correct me if I'm wrong.我不是专家,如果我错了,请随时纠正我。

Self made procedure.自制程序。 If you dont have the right to set the grant如果您无权设置补助金

CREATE OR REPLACE procedure new_sleep(p_nSekunden  number)

is

  dDate  date := sysdate;
begin

  if p_nSekunden < 1 then
    return;
  end if;
 
  dDate := dDate + ( (1/24/3600) * p_nSekunden );

  loop
    exit when sysdate > dDate;       
  end loop;
end;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM