我需要创建一个函数,它将值插入表中,直到我打破它。 所以我用循环实现了这个功能。 但是我需要在每次插入后暂停循环一秒钟,否则数据库会在一段时间后内存不足。
我已经尝试过系统暂停,但这会停止整个实例。
如果任何人有想法解决这个问题,那将是非常好的。
问候
答案 0 :(得分:4)
我需要创建一个函数,将值插入表中直到i 打破它。
正如您所说,如果您需要随意中断长时间运行的循环,请使用dbms_alert
包,特别是其register()
,waitone()
和signal()
程序。
以下是一个例子:
会话#1 :长时间循环播放。
declare
l_message varchar2(1000);
l_astatus number;
l_index number := 0;
l_maxindex number := 10e3;
begin
dbms_alert.register('waiting_to_be_broken');
loop
l_index := l_index + 1;
dbms_alert.waitone('waiting_to_be_broken', l_message, l_astatus, 0);
exit when (l_astatus = 0) or (l_index = l_maxindex);
insert into t1
values(l_index);
dbms_lock.sleep(1); -- NOTE! We call dbms_lock.sleep(1) here to just
end loop; -- delay(simulation of time consuming operations)
if (l_index < 10e3) -- the loop execution, nothing more.
then
dbms_output.put_line('Interrupted!');
else
dbms_output.put_line('Done!');
end if;
commit;
end;
/
会话#2 :您已经等待了很长时间并决定中断循环;
begin
dbms_alert.signal('waiting_to_be_broken', '');
commit;
end;
/
会话#1 :流程中断。
Interrupted!
PL/SQL procedure successfully completed.
注意!此示例仅用于演示。通常在循环中执行DML操作不是一个好主意。基于这样的事实,正如您所说,您的内存不足,您需要认真重新思考解决手头问题的方式。
答案 1 :(得分:3)
您需要在循环的每次迭代后添加DBMS_LOCK.SLEEP (seconds => 1);
。
SQL> l
1 begin
2 dbms_output.put_line(to_char(sysdate, 'hh24:mi:ss'));
3 DBMS_LOCK.sleep(seconds => 1);
4 dbms_output.put_line(to_char(sysdate, 'hh24:mi:ss'));
5* end;
SQL> /
09:55:42
09:55:43
有关详细信息,请参阅docs
答案 2 :(得分:2)
请参阅DBMS_LOCK.SLEEP程序。例如,我希望执行停止10秒:
SQL> set serveroutput on;
SQL> DECLARE
2 START_TM NUMBER;
3 BEGIN
4 START_TM := DBMS_UTILITY.GET_TIME;
5 DBMS_LOCK.SLEEP(10);
6 DBMS_OUTPUT.PUT_LINE('time taken : ' || (DBMS_UTILITY.get_time - START_TM));
7 END;
8 /
time taken : 1000
PL/SQL procedure successfully completed.
SQL>
因此,所需时间 1000/100 ,即10秒,因为SLEEP procedure
暂停了10秒。
注意:
我刚刚在问题中意识到你的第一个陈述,它说:
我需要创建一个将值插入表
的函数
为什么用于DML的函数?它是流水线表函数还是普通函数?如果你的想法是在你的普通UDF中插入语句,那么这是不好的做法。如果您愿意,我们可以详细讨论。