Start · Sprachen · PHP · Referenz · oci_cancel

oci_cancel

Funktion

Bricht das Lesen von Zeilen aus einem OCI-Statement-Cursor ab und gibt die damit verbundenen Server-Ressourcen frei.

seit PHP 5.0.0 Kategorie: db

Signatur

oci_cancel(resource $statement): bool

Beschreibung

oci_cancel wird verwendet, um das Lesen von Zeilen aus einem Oracle-Datenbank-Cursor (Statement-Handle) abzubrechen. Die Funktion gibt serverseitig belegte Ressourcen frei, die durch einen laufenden oci_fetch- oder oci_fetch_array-Vorgang entstanden sind, ohne dass alle Zeilen abgerufen werden müssen.

Dies ist besonders nützlich, wenn eine Abfrage eine große Ergebnismenge liefert und man nach dem Abrufen der ersten paar Zeilen feststellt, dass keine weiteren Daten benötigt werden. Ohne oci_cancel würden die Server-Ressourcen erst beim Schließen des Cursors oder beim nächsten Ausführen des Statements freigegeben.

Nach dem Aufruf von oci_cancel kann das Statement-Handle erneut mit oci_execute ausgeführt werden. Das Statement selbst wird nicht geschlossen — dafür ist oci_free_statement zuständig.

Die Funktion wirkt sich nur auf Statements aus, bei denen ein Cursor aktiv ist (also nach einem oci_execute-Aufruf). Bei nicht ausgeführten Statements hat sie keine Auswirkung.

Parameter

Name Typ Default Beschreibung
$statement Pflicht resource Ein gültiges OCI-Statement-Handle, das zuvor mit oci_parse erstellt und mit oci_execute ausgeführt wurde.

Rückgabewert

Typ
bool
Beschreibung
Gibt true bei Erfolg zurück, false bei einem Fehler (z. B. wenn das übergebene Handle ungültig ist).

Beispiele

Cursor-Lesen vorzeitig abbrechen

<?php
$conn = oci_connect('hr', 'welcome', 'localhost/XE');
if (!$conn) {
    $e = oci_error();
    trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR);
}

$sql = 'SELECT employee_id, last_name FROM employees ORDER BY employee_id';
$stmt = oci_parse($conn, $sql);
oci_execute($stmt);

$count = 0;
while (($row = oci_fetch_array($stmt, OCI_ASSOC)) !== false) {
    echo $row['EMPLOYEE_ID'] . ': ' . $row['LAST_NAME'] . PHP_EOL;
    $count++;
    if ($count >= 5) {
        // Nur die ersten 5 Zeilen werden benötigt
        oci_cancel($stmt);
        break;
    }
}

oci_free_statement($stmt);
oci_close($conn);
?>
100: King 101: Kochhar 102: De Haan 103: Hunold 104: Ernst

Statement nach oci_cancel erneut ausführen

<?php
$conn = oci_connect('hr', 'welcome', 'localhost/XE');
if (!$conn) {
    $e = oci_error();
    trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR);
}

$stmt = oci_parse($conn, 'SELECT department_id, department_name FROM departments ORDER BY department_id');

// Erster Durchlauf: nur eine Zeile abrufen
oci_execute($stmt);
$row = oci_fetch_array($stmt, OCI_ASSOC);
echo 'Erste Abteilung: ' . $row['DEPARTMENT_NAME'] . PHP_EOL;

// Cursor abbrechen und Statement erneut verwenden
oci_cancel($stmt);

// Zweiter Durchlauf: alle Zeilen
oci_execute($stmt);
while (($row = oci_fetch_array($stmt, OCI_ASSOC)) !== false) {
    echo $row['DEPARTMENT_ID'] . ': ' . $row['DEPARTMENT_NAME'] . PHP_EOL;
}

oci_free_statement($stmt);
oci_close($conn);
?>
Erste Abteilung: Administration 10: Administration 20: Marketing ...

// Wichtig · Fallstricke

Ressourcenverwaltung: Ohne oci_cancel bleibt ein offener Cursor serverseitig bestehen, bis er explizit geschlossen wird. Bei vielen gleichzeitigen Verbindungen kann die Oracle-Datenbank an die Grenze der erlaubten offenen Cursor stoßen (ORA-01000: maximum open cursors exceeded). oci_cancel hilft, dieses Problem zu vermeiden.

Kein Ersatz für oci_free_statement: oci_cancel schließt das Statement-Handle nicht. Um das Handle und alle damit verbundenen Ressourcen vollständig freizugeben, muss anschließend oci_free_statement aufgerufen werden.

Nur für SELECT-Statements: oci_cancel macht nur bei SELECT-Statements Sinn, die einen Cursor erzeugen. Für DML-Statements (INSERT, UPDATE, DELETE) hat die Funktion keine Wirkung.