Signatur
Beschreibung
pg_put_copy_end() schließt eine zuvor mit pg_put_copy_data() gestartete COPY-Operation ab. Die Funktion teilt dem Server mit, dass keine weiteren Daten mehr gesendet werden, und beendet den COPY-FROM-STDIN-Modus der Verbindung.
Wenn ein Fehlertext im Parameter error übergeben wird, wird die gesamte COPY-Operation als fehlgeschlagen markiert und vom Server abgebrochen. Dies ist nützlich, wenn während des Datentransfers auf der Client-Seite ein Fehler aufgetreten ist und die Transaktion sauber rückabgewickelt werden soll.
Der typische Ablauf eines COPY-Vorgangs sieht so aus: Zunächst wird mit pg_query() ein COPY ... FROM STDIN-Befehl gesendet, dann werden Datenzeilen mit pg_put_copy_data() übermittelt, und schließlich wird pg_put_copy_end() aufgerufen, um den Vorgang zu beenden. Diese Methode ist für große Datenmengen deutlich effizienter als viele einzelne INSERT-Befehle.
Nach dem Aufruf von pg_put_copy_end() kann das Ergebnis der Operation mit pg_get_result() abgerufen werden, um den Status zu prüfen.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $connection Pflicht | PgSql\Connection | Eine aktive PostgreSQL-Datenbankverbindung, die sich im COPY-FROM-STDIN-Modus befindet. | |
| $error | ?string | null | Optionaler Fehlertext. Wird ein nicht-leerer String übergeben, wird die COPY-Operation als fehlgeschlagen markiert und mit diesem Fehlertext abgebrochen. null oder ein leerer String schließt die Operation erfolgreich ab. |
Rückgabewert
true zurück, wenn das Ende der COPY-Operation erfolgreich an den Server übermittelt wurde, oder false bei einem Fehler (z. B. wenn die Verbindung ungültig ist oder die Verbindung sich nicht im COPY-Modus befindet).Beispiele
Massendaten mit COPY FROM STDIN einfügen
<?php
$conn = pg_connect('host=localhost dbname=testdb user=postgres password=secret');
if (!$conn) {
die('Verbindung fehlgeschlagen.');
}
// Tabelle vorbereiten
pg_query($conn, 'CREATE TEMP TABLE produkte (id INT, name TEXT, preis NUMERIC)');
// COPY-Befehl starten
$result = pg_query($conn, 'COPY produkte FROM STDIN WITH (FORMAT CSV)');
if (!$result) {
die('COPY-Befehl konnte nicht gestartet werden: ' . pg_last_error($conn));
}
// Datenzeilen senden
$zeilen = [
"1,Apfel,0.99\n",
"2,Banane,1.49\n",
"3,Kirsche,2.99\n",
];
foreach ($zeilen as $zeile) {
if (!pg_put_copy_data($conn, $zeile)) {
// Bei Fehler: Operation mit Fehlermeldung abbrechen
pg_put_copy_end($conn, 'Fehler beim Senden der Daten');
die('Fehler beim Senden der Zeile.');
}
}
// COPY erfolgreich beenden
if (!pg_put_copy_end($conn)) {
die('COPY konnte nicht abgeschlossen werden: ' . pg_last_error($conn));
}
// Ergebnis prüfen
$res = pg_get_result($conn);
if (pg_result_status($res) !== PGSQL_COMMAND_OK) {
die('COPY fehlgeschlagen: ' . pg_result_error($res));
}
echo 'Datensätze erfolgreich eingefügt: ' . pg_cmdtuples($res) . PHP_EOL;
pg_close($conn);
COPY-Operation bei Client-seitigem Fehler abbrechen
<?php
$conn = pg_connect('host=localhost dbname=testdb user=postgres password=secret');
pg_query($conn, 'CREATE TEMP TABLE log_eintraege (ts TIMESTAMP, nachricht TEXT)');
pg_query($conn, 'COPY log_eintraege FROM STDIN WITH (FORMAT CSV)');
$daten = [
'"2024-01-01 10:00:00","Anmeldung erfolgreich"' . "\n",
'"2024-01-01 10:05:00","Datei hochgeladen"' . "\n",
];
$fehler = false;
foreach ($daten as $zeile) {
if (!pg_put_copy_data($conn, $zeile)) {
$fehler = true;
break;
}
}
if ($fehler) {
// Fehler signalisieren – Server verwirft alle gesendeten Daten
pg_put_copy_end($conn, 'Unerwarteter Fehler auf Client-Seite');
echo 'COPY-Operation wurde abgebrochen.' . PHP_EOL;
} else {
pg_put_copy_end($conn);
$res = pg_get_result($conn);
echo 'Eingefügte Zeilen: ' . pg_cmdtuples($res) . PHP_EOL;
}
pg_close($conn);
// Wichtig · Fallstricke
Reihenfolge beachten: pg_put_copy_end() darf erst aufgerufen werden, nachdem der COPY-FROM-STDIN-Modus mit einem entsprechenden COPY ... FROM STDIN-SQL-Befehl initiiert wurde. Ein Aufruf ohne vorangehenden COPY-Befehl führt zu einem Fehler.
Ergebnis-Abfrage: pg_put_copy_end() selbst liefert nur Auskunft darüber, ob das Ende-Signal gesendet werden konnte. Das eigentliche Ergebnis der COPY-Operation (Anzahl eingefügter Zeilen, mögliche Constraint-Verletzungen) muss mit pg_get_result() abgefragt werden.
Transaktionssicherheit: Für kritische Datenimporte empfiehlt es sich, den COPY-Befehl innerhalb einer Transaktion (BEGIN/COMMIT/ROLLBACK) auszuführen, um bei Fehlern einen konsistenten Datenbankzustand zu gewährleisten.