Start · Sprachen · PHP · Referenz · oci_new_cursor

oci_new_cursor

Funktion

Legt einen neuen OCI8-Cursor (Statement-Handle) für eine bestehende Oracle-Verbindung an und gibt ihn zurück.

seit PHP 5.0.0 Kategorie: db

Signatur

oci_new_cursor(resource $connection): resource|false

Beschreibung

oci_new_cursor() erstellt einen neuen, leeren Cursor (auch als REF CURSOR bekannt) für eine vorhandene Oracle-Datenbankverbindung. Cursors werden hauptsächlich benötigt, wenn gespeicherte Prozeduren oder anonyme PL/SQL-Blöcke einen SYS_REFCURSOR-Ausgabeparameter zurückgeben sollen.

Der typische Einsatz besteht darin, den zurückgegebenen Cursor-Handle mit oci_bind_by_name() als SQLT_RSET-Parameter an eine PL/SQL-Prozedur zu binden. Nachdem das Statement ausgeführt wurde, kann der Cursor mit den normalen OCI-Fetch-Funktionen wie oci_fetch_array() durchlaufen werden.

Am Ende sollte der Cursor explizit mit oci_free_statement() freigegeben werden, um Ressourcen auf der Oracle-Seite nicht unnötig zu belegen. Das übergeordnete Statement und die Verbindung sollten ebenfalls sauber geschlossen werden.

Diese Funktion ist besonders nützlich, wenn komplexe Geschäftslogik in der Datenbank gekapselt ist und PHP nur die Ergebnismenge aus einer gespeicherten Prozedur abrufen soll.

Parameter

Name Typ Default Beschreibung
$connection Pflicht resource Eine gültige OCI8-Verbindungsressource, die zuvor mit oci_connect(), oci_pconnect() oder oci_new_connect() erstellt wurde.

Rückgabewert

Typ
resource|false
Beschreibung
Gibt im Erfolgsfall eine neue Cursor-Ressource zurück, die als REF-CURSOR-Parameter oder direkt für Abfragen verwendet werden kann. Bei einem Fehler wird false zurückgegeben.

Beispiele

REF CURSOR aus einer gespeicherten PL/SQL-Prozedur abrufen

<?php
// Verbindung zur Oracle-Datenbank herstellen
$conn = oci_connect('benutzer', 'passwort', 'localhost/ORCL');
if (!$conn) {
    $e = oci_error();
    trigger_error(htmlentities($e['message']), E_USER_ERROR);
}

// Neuen Cursor anlegen
$cursor = oci_new_cursor($conn);

// PL/SQL-Block, der einen REF CURSOR zurückgibt
$sql = 'BEGIN mitarbeiter_pkg.get_alle(:rc); END;';
$stmt = oci_parse($conn, $sql);

// Cursor als OUT-Parameter binden (SQLT_RSET = REF CURSOR)
oci_bind_by_name($stmt, ':rc', $cursor, -1, OCI_B_CURSOR);

// Statement ausführen
oci_execute($stmt);

// Den zurückgegebenen Cursor selbst ausführen
oci_execute($cursor);

// Ergebnisse des Cursors abrufen
while ($row = oci_fetch_array($cursor, OCI_ASSOC + OCI_RETURN_NULLS)) {
    echo $row['VORNAME'] . ' ' . $row['NACHNAME'] . PHP_EOL;
}

// Ressourcen freigeben
oci_free_statement($cursor);
oci_free_statement($stmt);
oci_close($conn);
?>
Max Mustermann Erika Musterfrau ...

Cursor in einem anonymen PL/SQL-Block verwenden

<?php
$conn = oci_connect('benutzer', 'passwort', 'localhost/ORCL');
if (!$conn) {
    $e = oci_error();
    trigger_error(htmlentities($e['message']), E_USER_ERROR);
}

// Neuen Cursor anlegen
$cursor = oci_new_cursor($conn);

// Anonymer PL/SQL-Block, der einen offenen Cursor zurückgibt
$sql = '
    BEGIN
        OPEN :cur FOR
            SELECT abteilung_id, bezeichnung
            FROM abteilungen
            ORDER BY bezeichnung;
    END;
';
$stmt = oci_parse($conn, $sql);
oci_bind_by_name($stmt, ':cur', $cursor, -1, OCI_B_CURSOR);
oci_execute($stmt);

// Cursor ausführen und Daten lesen
oci_execute($cursor);
while ($row = oci_fetch_array($cursor, OCI_ASSOC)) {
    printf("ID: %d, Bezeichnung: %s\n", $row['ABTEILUNG_ID'], $row['BEZEICHNUNG']);
}

oci_free_statement($cursor);
oci_free_statement($stmt);
oci_close($conn);
?>
ID: 3, Bezeichnung: Buchhaltung ID: 1, Bezeichnung: Entwicklung ID: 2, Bezeichnung: Vertrieb

// Wichtig · Fallstricke

Ressourcen-Management: Jeder mit oci_new_cursor() angelegte Cursor belegt eine Session-Ressource auf der Oracle-Seite (begrenzt durch den Parameter OPEN_CURSORS). Vergisst man oci_free_statement() aufzurufen, können alle verfügbaren Cursor aufgebraucht werden, was zu Oracle-Fehler ORA-01000: maximum open cursors exceeded führt.

Ausführung: Ein mit oci_new_cursor() erzeugter Cursor muss nach dem Binden und der Ausführung des übergeordneten Statements noch separat mit oci_execute($cursor) geöffnet werden, bevor Zeilen abgerufen werden können.

PHP 8: Ab PHP 8.0 wurde die OCI8-Erweiterung überarbeitet; Verbindungen und Statements werden nun als OCIConnection- bzw. OCIStatement-Objekte repräsentiert, das Verhalten von oci_new_cursor() bleibt jedoch identisch.