Oracle数据库中执行完一个查询后如何执行第二个SQL查询?
在同一个Oracle连接中连续执行存储过程与SQL查询(PHP)
嘿,我看你已经搞定了调用Oracle存储过程的代码,现在想在同一个连接里紧接着跑一个SELECT查询对吧?其实核心就是不要在第一个操作后立刻断开数据库连接,保持连接打开,完成第二个查询后再关闭就行。我帮你把代码调整优化一下,看看怎么实现:
关键要点
- 复用同一个数据库连接:
OCILogoff要放在所有数据库操作完成之后,别执行完存储过程就立刻断开。 - 第二个查询用标准的
oci_parse/oci_execute流程:SELECT语句执行后需要读取返回的结果集。 - 用绑定变量替代硬编码:把发票编号抽成变量,既避免SQL注入风险,又方便后续维护。
修改后的完整代码
<?php $db = "(DESCRIPTION=(ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = 83.111.41.30)(PORT = 1536)))(CONNECT_DATA=(SID=TEST)))"; $invoiceNumber = '34499'; // 抽离硬编码的发票号,方便复用 // 建立数据库连接 if ($c = OCILogon("XXWEBSITE", "xxwebsite", $db)) { // 第一步:调用存储过程 $stidProc = oci_parse($c, "call apps.xx_ar_cust_os_bal_pkg.xx_ar_cust_os_bal_proc(:inv_num, :out_inv_num, :unit_no, :cust_name, :inv_date, :trans_type, :cust_no, :outstanding_amount, :err)"); // 绑定存储过程的变量(输入输出都用绑定,更规范) oci_bind_by_name($stidProc, ":inv_num", $invoiceNumber); oci_bind_by_name($stidProc, ":out_inv_num", $inv_num); oci_bind_by_name($stidProc, ":unit_no", $unit_no); oci_bind_by_name($stidProc, ":cust_name", $cust_name); oci_bind_by_name($stidProc, ":inv_date", $inv_date); oci_bind_by_name($stidProc, ":trans_type", $trans_type); oci_bind_by_name($stidProc, ":cust_no", $cust_no); oci_bind_by_name($stidProc, ":outstanding_amount", $outstanding_amount); oci_bind_by_name($stidProc, ":err", $err); $procCheck = oci_execute($stidProc); echo "存储过程执行状态:" . ($procCheck ? "成功" : "失败") . "<br>"; // 这里可以按需输出存储过程返回的变量,比如:echo "返回的发票编号:$inv_num<br>"; // 第二步:执行SELECT查询(复用同一个连接$c) $sqlSelect = " SELECT SUM(aps.amount_due_remaining) AS due_amount, ra.trx_number, ofc.office, hp.party_name, TO_CHAR(ra.trx_date) AS trx_date, rt.NAME AS trans_type_name, hc.account_number FROM ar.ra_customer_trx_all ra JOIN ar.ar_payment_schedules_all aps ON ra.customer_trx_id = aps.customer_trx_id AND ra.org_id = aps.org_id JOIN ar.ra_cust_trx_types_all rt ON ra.cust_trx_type_id = rt.cust_trx_type_id JOIN apps.hz_cust_accounts hc ON ra.bill_to_customer_id = hc.cust_account_id AND hc.cust_account_id = aps.customer_id JOIN apps.hz_parties hp ON hp.party_id = hc.party_id JOIN apps.pn_locations_v ofc ON TO_CHAR(ofc.location_id) = ra.attribute5 WHERE aps.amount_due_remaining <> 0 AND rt.NAME IN ('AC Bill ARA', 'ARA - Connection Fee', 'ARA Cooling Deposit', 'ARA - Demand Charges', 'AC Bill ARR') AND ra.trx_number = :inv_num GROUP BY ofc.suite, rt.NAME, ra.trx_number, ofc.office, hp.party_name, ra.trx_date, hc.account_number "; $stidSelect = oci_parse($c, $sqlSelect); // 绑定查询的发票号变量,和存储过程共用同一个变量 oci_bind_by_name($stidSelect, ":inv_num", $invoiceNumber); $selectCheck = oci_execute($stidSelect); if ($selectCheck) { echo "<br>查询结果:<br>"; // 循环读取结果集 while ($row = oci_fetch_array($stidSelect, OCI_ASSOC+OCI_RETURN_NULLS)) { echo "到期金额:" . $row['DUE_AMOUNT'] . "<br>"; echo "交易编号:" . $row['TRX_NUMBER'] . "<br>"; echo "办公室:" . $row['OFFICE'] . "<br>"; echo "客户名称:" . $row['PARTY_NAME'] . "<br>"; echo "交易日期:" . $row['TRX_DATE'] . "<br>"; echo "交易类型:" . $row['TRANS_TYPE_NAME'] . "<br>"; echo "客户账号:" . $row['ACCOUNT_NUMBER'] . "<br>"; echo "------------------------<br>"; } } else { $selectErr = OCIError($stidSelect); echo "查询执行失败:" . $selectErr['message'] . "<br>"; } // 所有操作完成后,关闭连接 OCILogoff($c); } else { $err = OCIError(); echo "数据库连接失败:" . $err['message']; } ?>
代码调整说明
- 复用连接:把
OCILogoff($c)移到了所有数据库操作的最后,确保连接在两个操作中都保持打开状态。 - 绑定变量优化:把硬编码的'34499'改成了变量
$invoiceNumber,并在存储过程和SELECT查询中都用绑定变量,既安全又易维护。 - 结果集处理:添加了循环读取SELECT结果的逻辑,用
oci_fetch_array获取每一行数据并展示,方便你查看查询输出。 - SQL语法优化:把原来的逗号分隔表改成了显式
JOIN,让SQL结构更清晰,可读性更强。
内容的提问来源于stack exchange,提问作者Rahul shukla
相关产品推荐
相关产品推荐

