Signatur
Beschreibung
oci_lob_copy() kopiert die Daten eines Large Object (LOB) aus einem Quell-LOB-Deskriptor in einen Ziel-LOB-Deskriptor. Die Funktion arbeitet serverseitig innerhalb der Oracle-Datenbank und ist daher effizienter als das manuelle Auslesen und Schreiben der LOB-Daten über PHP.
Über den Parameter length kann die Anzahl der zu kopierenden Bytes gesteuert werden. Wird 0 übergeben oder der Parameter weggelassen, wird der gesamte Inhalt des Quell-LOBs kopiert. Dies ist besonders nützlich für das Duplizieren von CLOB- oder BLOB-Spalten in Oracle-Tabellen.
Beide LOB-Deskriptoren müssen zuvor mit einer entsprechenden OCI-Abfrage (z. B. via SELECT ... FOR UPDATE für das Ziel-LOB und SELECT ... für das Quell-LOB) geöffnet worden sein. Die Änderungen werden erst durch ein oci_commit() dauerhaft in die Datenbank geschrieben.
Die Funktion eignet sich in Szenarien, in denen große Mengen binärer oder textueller Daten innerhalb der Datenbank vervielfältigt werden sollen, ohne diese vollständig über das Netzwerk zu den PHP-Prozessen übertragen zu müssen.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $lob_to Pflicht | OCILob | Der Ziel-LOB-Deskriptor, in den die Daten kopiert werden. Muss mit Schreibzugriff (SELECT ... FOR UPDATE) geöffnet worden sein. |
|
| $lob_from Pflicht | OCILob | Der Quell-LOB-Deskriptor, aus dem die Daten gelesen werden. | |
| $length | int | 0 | Anzahl der zu kopierenden Bytes. Bei 0 (Standardwert) wird der gesamte Inhalt des Quell-LOBs kopiert. |
Rückgabewert
true bei Erfolg zurück. Im Fehlerfall wird false zurückgegeben, z. B. wenn ein ungültiger LOB-Deskriptor übergeben wurde oder der Datenbankzugriff fehlschlägt.Beispiele
Kompletten LOB-Inhalt von einer Zeile in eine andere kopieren
<?php
$conn = oci_connect('hr', 'welcome', 'localhost/XE');
if (!$conn) {
$e = oci_error();
trigger_error($e['message'], E_USER_ERROR);
}
// Quell-LOB lesen
$stmtFrom = oci_parse($conn, 'SELECT beschreibung FROM dokumente WHERE id = :id');
oci_bind_by_name($stmtFrom, ':id', $sourceId);
$sourceId = 1;
oci_execute($stmtFrom);
$rowFrom = oci_fetch_assoc($stmtFrom);
$lobFrom = $rowFrom['BESCHREIBUNG'];
// Ziel-LOB mit Schreibzugriff öffnen
$stmtTo = oci_parse($conn, 'SELECT beschreibung FROM dokumente WHERE id = :id FOR UPDATE');
oci_bind_by_name($stmtTo, ':id', $targetId);
$targetId = 2;
oci_execute($stmtTo, OCI_NO_AUTO_COMMIT);
$rowTo = oci_fetch_assoc($stmtTo);
$lobTo = $rowTo['BESCHREIBUNG'];
// LOB kopieren
if (oci_lob_copy($lobTo, $lobFrom)) {
oci_commit($conn);
echo 'LOB erfolgreich kopiert.';
} else {
oci_rollback($conn);
echo 'Fehler beim Kopieren des LOBs.';
}
$lobFrom->free();
$lobTo->free();
oci_close($conn);
?>
Nur die ersten 1024 Bytes eines LOBs kopieren
<?php
$conn = oci_connect('hr', 'welcome', 'localhost/XE');
$stmtFrom = oci_parse($conn, 'SELECT bild FROM fotos WHERE id = 10');
oci_execute($stmtFrom);
$rowFrom = oci_fetch_assoc($stmtFrom);
$lobFrom = $rowFrom['BILD'];
$stmtTo = oci_parse($conn, 'SELECT bild FROM fotos WHERE id = 20 FOR UPDATE');
oci_execute($stmtTo, OCI_NO_AUTO_COMMIT);
$rowTo = oci_fetch_assoc($stmtTo);
$lobTo = $rowTo['BILD'];
// Nur die ersten 1024 Bytes kopieren
$result = oci_lob_copy($lobTo, $lobFrom, 1024);
if ($result) {
oci_commit($conn);
echo 'Erste 1024 Bytes erfolgreich kopiert.';
} else {
oci_rollback($conn);
echo 'Fehler beim partiellen Kopieren.';
}
$lobFrom->free();
$lobTo->free();
oci_close($conn);
?>
// Wichtig · Fallstricke
Transaktionen: Das Ziel-LOB muss zwingend mit OCI_NO_AUTO_COMMIT und einer FOR UPDATE-Abfrage geöffnet werden, da LOB-Schreiboperationen einen offenen Transaktionskontext benötigen. Vergisst man das oci_commit(), werden die Änderungen verworfen.
Speicherverwaltung: LOB-Deskriptoren sollten nach der Verwendung mit OCILob::free() freigegeben werden, um Speicherlecks zu vermeiden.
Deprecation: In PHP 8.0 wurde die interne Klasse von OCI-Lob in OCILob umbenannt. Die Funktion oci_lob_copy() ist weiterhin verfügbar, jedoch sollte bei neuen Projekten auf eine aktuelle Oracle-Datenbankerweiterung geachtet werden.
Alternativer Ansatz: Ist der Kopiervorgang vollständig serverseitig möglich, kann auch ein direktes UPDATE ... SET lob_col = (SELECT lob_col FROM ...) in manchen Oracle-Versionen effizienter sein.