Start · Sprachen · PHP · Referenz · pg_put_copy_end

pg_put_copy_end

Funktion

Signalisiert dem PostgreSQL-Server den Abschluss einer COPY-FROM-STDIN-Operation und beendet den Datentransfer.

seit PHP 5.6.0 Kategorie: db

Signatur

pg_put_copy_end(PgSql\Connection $connection, ?string $error = null): bool

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

Typ
bool
Beschreibung
Gibt 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);
Datensätze erfolgreich eingefügt: 3

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);
Eingefügte Zeilen: 2

// 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.