Running a stored procedure that populates a temporary table and then selecting from the temporary table

huangapple go评论71阅读模式
英文:

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

huangapple
  • 本文由 发表于 2023年7月20日 19:31:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/76729411.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定