我有一个存储过程,我使用以下命令从PHP运行:
//Request does not change
$sql = 'BEGIN SP_GET_MY_DATA(:POP, :SEG, :DUR, :VIEW, :PAGE, :OUTPUT_CUR); END;';
//Statement does not change
$stmt = oci_parse($conn,$sql);
oci_bind_by_name($stmt,':POP',$pop);
oci_bind_by_name($stmt,':SEG',$seg);
oci_bind_by_name($stmt,':DUR',$dur);
oci_bind_by_name($stmt,':VIEW',$view);
oci_bind_by_name($stmt,':PAGE',$page);
//But BEFORE statement, Create your cursor
$cursor = oci_new_cursor($conn)
// On your code add the latest parameter to bind the cursor resource to the Oracle argument
oci_bind_by_name($stmt,":OUTPUT_CUR", $cursor,-1,OCI_B_CURSOR);
// Execute the statement as in your first try
oci_execute($stmt);
// and now, execute the cursor
oci_execute($cursor);
// Use OCIFetchinto in the same way as you would with SELECT
while ($data = oci_fetch_assoc($cursor, OCI_RETURN_LOBS )) {
print_r($data}
}
问题是我在存储过程中有数百万行和复杂的逻辑。当我通过SQL开发人员执行SP_GET_MY_DATA时,完成它需要大约2个小时。
当我这样做时,PHP会超时。我也不能在PHP中增加max_execution_time。
如何在Oracle上运行此程序或在没有超时的情况下使用PHP?请帮忙。
答案 0 :(得分:3)
我回答了如何使用Oracle Scheduler在DBA堆栈交换的这个答案中异步地异步运行一个长时间运行的过程。见https://dba.stackexchange.com/a/67913/38772
TL; DR
-- submit this as a background job
BEGIN
dbms_scheduler.create_job (
job_name => 'MY_BACKGROUND_JOB'
, job_type => 'STORED_PROCEDURE'
, job_action => 'SP_GET_MY_DATA'
, enabled => TRUE
, auto_drop => TRUE
);
END;
如果要将参数传递给过程,则必须再做一些工作。您可能会发现此答案有用https://dba.stackexchange.com/q/42119/38772/
有关所有血腥详细信息的其他参考,Oracle文档中的相关章节位于https://docs.oracle.com/database/121/ADMIN/scheduse.htm
答案 1 :(得分:-2)
不要增加max_execution_time,将其设置为0,允许它无限期运行。如果要返回大量行,请确保增加内存(ini_set)或允许立即缓冲区刷新,以便它可以直接输出到客户端。
后者还会阻止客户过早断开连接,因为他们没有获得任何数据。 (ob_implicit_flush(true);
)