英文:
Running a stored procedure that populates a temporary table and then selecting from the temporary table
问题
I have a stored procedure that populates a global temporary table.
CREATE GLOBAL TEMPORARY TABLE temptable
(
...
)
ON COMMIT DELETE ROWS;
I want to run the stored procedure and then select the rows added to the temporary table.
$conn = oci_connect(...);
$sql = "BEGIN POPULATETEMPTABLE END;";
$stmt = oci_parse($conn, $sql);
oci_execute($stmt);
oci_free_statement($stmt);
$sql = "SELECT ... FROM temptable";
$stmt = oci_parse($conn, $sql);
oci_execute($stmt);
while ($row = oci_fetch_assoc($stmt))
{
...
}
oci_free_statement($stmt);
oci_close($conn);
That code fetches no rows. So I decided to put the select in the same round trip to the database:
$conn = oci_connect(...);
$sql = "
BEGIN POPULATETEMPTABLE END;
SELECT ... FROM temptable
";
$stmt = oci_parse($conn, $sql);
oci_execute($stmt);
while ($row = oci_fetch_assoc($stmt))
{
...
}
oci_free_statement($stmt);
oci_close($conn);
And that gives me an error:
PLS-00103: Encountered the symbol "SELECT"
If I put the SELECT inside the BEGIN ... END; then I get this error:
PLS-00428: an INTO clause is expected in this SELECT statement
How do I run a stored procedure that populates a temporary table and then select from it in PHP?
It works in SQL Developer, just not in PHP.
Using:
- PHP 8.1.4
- Oracle 19.0.0.0.0
英文:
I have a stored procedure that populates a global temporary table.
CREATE GLOBAL TEMPORARY TABLE temptable
(
...
)
ON COMMIT DELETE ROWS;
I want to run the stored procedure and then select the rows added to the temporary table.
$conn = oci_connect(...);
$sql = "BEGIN POPULATETEMPTABLE END;"
$stmt = oci_parse($conn, $sql);
oci_execute($stmt);
oci_free_statement($stmt);
$sql = "SELECT ... FROM temptable";
$stmt = oci_parse($conn, $sql);
oci_execute($stmt);
while ($row = oci_fetch_assoc($stmt))
{
...
}
oci_free_statement($stmt);
oci_close($conn);
That code fetches no rows. So I decided to put the select in the same round trip to the database:
$conn = oci_connect(...);
$sql = "
BEGIN POPULATETEMPTABLE END;
SELECT ... FROM temptable
"
$stmt = oci_parse($conn, $sql);
oci_execute($stmt);
while ($row = oci_fetch_assoc($stmt))
{
...
}
oci_free_statement($stmt);
oci_close($conn);
And that gives me error:
PLS-00103: Encountered the symbol "SELECT"
If I put the SELECT inside the BEGIN ... END; then I get this error:
PLS-00428: an INTO clause is expected in this SELECT statement
How do I run a stored procedure that populates a temporary table and then select from it in PHP?
It works in SQL Developer, just not in PHP.
Using:
PHP 8.1.4
Oracle 19.0.0.0.0
答案1
得分: 1
第一个问题是因为 oci_execute()
默认会提交事务,所以通过调用 POPULATETEMPTABLE
插入的任何行都会被 ON COMMIT DELETE ROWS;
定义清除。
修复这个问题,可以改成以下方式:
$sql = "BEGIN POPULATETEMPTABLE END;";
$stmt = oci_parse($conn, $sql);
oci_execute($stmt, OCI_NO_AUTO_COMMIT);
关于第二个问题,将 SELECT 放在 PL/SQL 块中是无效的 PL/SQL。可以使用 REF CURSOR 或 IMPLICIT RESULT SET。请参考 OCI8 文档或《The Underground PHP and Oracle Manual》。
英文:
The first issue is because oci_execute()
commits by default, so any rows inserted by the call to POPULATETEMPTABLE
are cleaned up by the ON COMMIT DELETE ROWS;
definition.
Fix this by changing to:
$sql = "BEGIN POPULATETEMPTABLE END;"
$stmt = oci_parse($conn, $sql);
oci_execute($stmt, OCI_NO_AUTO_COMMIT);
The secondary issue about putting the SELECT in the PL/SQL block is because this is invalid PL/SQL. Use a REF CURSOR or an IMPLICIT RESULT SET. See the OCI8 doc or The Underground PHP and Oracle Manual
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论