PL / SQL中是否存在异步调用的功能? 假设我在一个代码块中想多次调用一个过程,并且不会打扰何时以及该过程返回什么内容?
BEGIN
myProc(1,100);
myProc(101,200);
myProc(201,300);
...
...
END;
在上面的例子中,我不希望我的代码在执行(101,200)之前等待myProc(1,100)完成处理 感谢。
答案 0 :(得分:24)
为DBMS_SCHEDULER和DBMS_JOB方法+1,但也要考虑是否应该使用不同的方法。
如果你有一个以逐行方式执行的过程,并且发现它很慢,那么答案可能不是同时多次运行该过程,而是确保使用基于集合的aproach代替。在极端情况下,您甚至可以使用并行查询和并行DML来减少进程的挂钟时间。
我之所以提到这一点,只是因为这是一个非常常见的错误。
答案 1 :(得分:17)
在DBMS_JOB中提交,如下所示:
declare
ln_dummy number;
begin
DBMS_JOB.SUBMIT(ln_dummy, 'begin myProc(1,100); end;');
DBMS_JOB.SUBMIT(ln_dummy, 'begin myProc(101,200); end;');
DBMS_JOB.SUBMIT(ln_dummy, 'begin myProc(201,300); end;');
COMMIT;
end;
您需要将job_queue_processes参数设置为> 0以生成线程来处理作业。您可以通过检查视图user_jobs来查询作业。
请注意,这适用于Oracle 9i,不确定10g支持的内容。查看更多信息here。
编辑:添加了错过的COMMIT
答案 2 :(得分:11)
您可能需要查看DBMS_SCHEDULER。
编辑完整性:
Oracle 10g上提供了DMBS_SCHEDULER。对于此之前的版本,DBMS_JOB执行大致相同的工作。
有关详细信息,请参阅:http://download.oracle.com/docs/cd/B12037_01/server.101/b10739/jobtosched.htm
答案 3 :(得分:10)
对于PL / SQL并行处理,您有以下选择:
这些将允许您在PL / SQL中“模拟”分叉和线程。当然,使用这些,您可能意识到需要在并行执行的过程之间进行通信。为此,请查看:
我个人使用DBMS_Scheduler实现了并行处理系统,并使用DBMS_Pipe在“线程”之间进行通信。我对两者的结合非常满意,我的主要目标(通过特定的重量程序减少主要处理时间)已经实现!
答案 4 :(得分:5)
此处显示了执行并行(多线程)PL / SQL的另一种方法:
http://www.williamrobertson.net/documents/parallel-plsql-launcher.html
使用dbms_job或dbms_schedular的缺点是您不知道任务何时完成。我读到你不打扰但也许你将来会改变主意。
编辑:
本文http://www.devx.com/dbzone/10MinuteSolution/20902/0/page/1描述了另一种方式。它使用dbms_job
和dbms_alert
。警报用于表示作业已完成(回叫信号)。
答案 5 :(得分:5)
你还有另一种选择,从11g开始。 Oracle推出了一个类似于你想要做的事情的软件包,命名为DBMS_PARALLEL_EXECUTE
据他们说,“DBMS_PARALLEL_EXECUTE包允许用户并行地逐步更新表数据”。关于如何使用它的一个相当好的总结是here
基本上,您定义了Oracle应该使用的方式将您的工作分解成碎片(在您的情况下,您似乎传递了一些键值),然后它将单独启动每个碎片。为了使用它,肯定会有一些计划和一些额外的编码,但是你不应该做任何事情。
使用诸如此类的认可方法的优点是Oracle甚至提供了可用于监视每个独立线程的数据库视图。
答案 6 :(得分:1)
这里解释了将数据卸载到平面文件的不同方法。其中一种方法展示了如何使用PL / SQL进行并行执行以加快速度。
答案 7 :(得分:1)
askTom在此列出的并行流水线方法提供了一种更复杂的方法,但实际上您将暂停工作,直到工作完成,这与DBMS Job技术不同。也就是说, 要求“异步”技术,DBMS_JOB非常适合。
答案 8 :(得分:-1)
您是否考虑过使用Oracle Advanced Queuing?