dantaros
Goto Top

PHP - MySQL Datensatz in eine andere Tabelle kopieren und löschen

Hallo zusammen,

ich habe aktuell ein Problem.
Ich habe eine Tabelle die über eine Eingabemaske von Usern gefüllt wird. In dieser werden aktuell anstehende Lieferungen aufgelistet.
Wenn eine Lieferung abgeschlossen ist, sollen die dazugehörigen Daten über einen "Archivieren-Button" in eine neue Tabelle geschrieben und aus der alten gelöscht werden.

Dafür verwende ich PHP. Das Löschen klappt soweit auch, nur das "Archivieren" in die neue Tabelle will nicht klappen.
Anbei der Code den ich für das Löschen verwende.

// Sicherheitsabfrage Archivierung
if (isset($_GET['aktion']) and $_GET['aktion'] == 'sicherheitarchivieren') {  
    if ( isset($_GET['id'])) {  
        $id_einlesen = (INT) $_GET['id'];  
        echo '<h1>Sicherheitsabfrage Archivieren</h1>';  
        echo '<p>Soll der folgende Datensatz archiviert werden?</p>';  
        echo '<p><a href="?aktion=archivieren&id='. $id_einlesen.'">Archivieren!</a></p>';  
        $_GET['aktion'] = 'anzeigen';  
    }
}
//
if (isset($_GET['aktion']) and $_GET['aktion'] == 'anzeigen') {  
    if ( isset($_GET['id'])) {  
        $id_einlesen = (INT) $_GET['id'];  
        if ($id_einlesen > 0) {
            $dseinlesen = $db->prepare("SELECT id, Datum, Kunde , Zeitfenster, Kennzeichen, Eintreffzeit, Papiere, Belabelt, Beladen, DFUE, Abfahrt, Bemerkung  
                                               FROM abholung WHERE id = ? ");  
            $dseinlesen->bind_param('i', $id_einlesen);  
            $dseinlesen->execute();
            $dseinlesen->bind_result($id, $Datum, $Kunde, $Zeitfenster, $Kennzeichen, $Eintreffzeit, $Papiere, $Belabelt, $Beladen, $DFUE, $Abfahrt, $Bemerkung );
            $dseinlesen->fetch();       
            echo "Datum: <b> $Datum </b><br>";            
            echo "Kunde: <b> $Kunde </b><br>";                  
            echo "Zeitfenster: <b> $Zeitfenster </b><br>";                  
            echo "Kennzeichen: <b> $Kennzeichen </b><br>";                  
            echo "Eintreffzeit <b> $Eintreffzeit </b><br>";                  
            echo "Papiere: <b> $Papiere </b><br>";                  
            echo "Belabelt: <b> $Belabelt </b><br>";                  
            echo "Beladen: <b> $Beladen </b><br>";                  
            echo "DFUE: <b> $DFUE </b><br>";                  
            echo "Abfahrt: <b> $Abfahrt </b><br>";                  
            echo "Bemerkung: <b> $Bemerkung </b><br>";                  
            echo '<p><a href="_test.php">Tabelle anzeigen</a>';  
            $dseinlesen->close();
            exit;   
        }
    }
}
if (isset($_GET['aktion']) and $_GET['aktion']=='archivieren') {  
    if (isset($_GET['id'])) {  
        $id = (INT) $_GET['id'];  
        if ($id > 0)
        {
            $loeschen = $db->prepare("DELETE FROM abholung WHERE id=(?) LIMIT 1");  
            $loeschen->bind_param('i', $id);  
            if ($loeschen->execute()) {
                echo "<p>Datensatz wurde gelöscht</p>";  
            }
        }       
    }
}

Ich habe schon einiges versucht und lange gesucht, aber bisher habe ich keine Lösung für das Archivieren gefunden.
Ein Teil meines letzten Lösungsansatzes war:
$archivieren= $db->prepare (" INSERT INTO archiv SELECT * FROM abholung WHERE id= ? LIMIT 1" );  

Ich hoffe ihr könnt mir weiterhelfen.

Mit freundlichen Grüßen

Daniel

Content-ID: 466583

Url: https://administrator.de/contentid/466583

Ausgedruckt am: 28.11.2024 um 21:11 Uhr

Pjordorf
Pjordorf 27.06.2019 um 15:02:30 Uhr
Goto Top
Hallo,

Zitat von @Dantaros:
Dafür verwende ich PHP. ... nur das "Archivieren" in die neue Tabelle will nicht klappen.
Was genau will nicht klappen? Fehlermeldungen?
https://stackify.com/php-debugging-guide/

Gruß,
Peter
eisbein
eisbein 27.06.2019 um 15:20:41 Uhr
Goto Top
Hallo,

Ein Teil meines letzten Lösungsansatzes war:
$archivieren= $db->prepare (" INSERT INTO archiv SELECT * FROM abholung WHERE id= ? LIMIT 1" );  

Warum postest du nur einen Teil und nicht den ganzen Lösungsansatz inkl. genauer Problemschilderung und Fehlermeldungen?

Gruß
eisbein
Dantaros
Dantaros 27.06.2019 um 16:20:35 Uhr
Goto Top
Hallo,

leider hatte ich durch das ganze testen nicht mehr alles.

Mein aktueller Test sieht so aus:

if (isset($_GET['aktion']) and $_GET['aktion']=='archivieren') {  
    if (isset($_GET['id'])) {  
        $id = (INT) $_GET['id'];  
        if ($id > 0)
        {
			$archivieren= $db->prepare (" INSERT INTO archiv SELECT * FROM abholung WHERE id= ? LIMIT 1" );  
			$archivieren->bind_param('i', $id);  
            if ($archivieren->execute()) {
                echo "<p>Datensatz wurde archiviert</p>";  
            }
        }       
    }
}

Wenn mein Archiv leer ist, dann wird der Datensatz mit der ID 6 in die Archiv-Tabelle kopiert.
Sobald der Datensatz dann kopiert wurde, kann ich keinen weiteren mehr kopieren, da er immer versucht den Datensatz mit der ID 6 zu kopieren.
eisbein
eisbein 27.06.2019 um 16:48:35 Uhr
Goto Top
Und welcher Wert wird jeweils mit der Variable $_GET["id"] übergeben?

Schreib mal zwischen Zeile 5 und 6
echo $id;
und lass dir den jeweiligen Wert für $id ausgeben.
Dantaros
Dantaros 28.06.2019 um 15:56:21 Uhr
Goto Top
Hallo,

entschuldige die späte Antwort.

Es wurde immer die niedrigste id aus der Tabelle angezeigt.

Ich konnte den Fehler allerdings ausfindig machen.
Als mir aufgefallen ist, dass meine Bearbeiten- und Löschen-Funktion plötzlich auch den selben Fehler haben, habe ich den Fehler wo anders gesucht und gefunde.

Das Kopieren in die neue Tabelle funktioniert jetzt mit dem Code von oben.

Allerdings habe ich es jetzt noch nicht hinbekommen das Löschen nach dem Kopieren auszuführen.
Dafür wollte ich folgendes verwenden:

$loeschen = $db->prepare("DELETE FROM abholung WHERE id=(?) LIMIT 1");  

Nachdem das Kopieren ausgeführt wurde, springt er wieder in die Ausgangssituation ohne das Löschen auszuführen.
ukulele-7
ukulele-7 28.06.2019 um 16:23:33 Uhr
Goto Top
Das LIMIT 1 macht keinen Sinn beim Archivieren, selbst wenn es mehrere Datensätze mit der gleichen ID geben sollte (was vermutlich anderweitig nicht möglich sein soll) wäre es ja sinnvoll alle Datensätze gleich zu behandeln oder der Schlüssel ist der falsche. LIMIT 1 ist in dem Zusammenhang sinnfrei in vielerlei Hinsicht.

Bei DELETE wird LIMIT vermutlich einen Fehler provozieren, auch hier ist es sinnfrei. Aber vor allem müsste das hier ein Syntax Problem geben, zumindest bei MSSQL kann ich kein DELETE TOP 1 FROM tabelle machen.
Dantaros
Dantaros 01.07.2019 um 09:03:58 Uhr
Goto Top
Das Limit beim Archivieren hab ich jetzt entfernt, beim löschen hab ichs noch drin und es gibt keine Probleme.

$loeschen = $db->prepare("DELETE FROM abholung WHERE id=(?) LIMIT 1");  
            $loeschen->bind_param('i', $id);  
            if ($loeschen->execute()) {
                echo "<p>Datensatz wurde gelöscht</p>";  
            }


Mein Problem ist jetzt, dass ich das Archivieren/Kopieren und Löschen nicht nacheinander ausgeführt bekomme, wenn ich eins von beidem ausführe, werde ich direkt wieder zur Ursprungsseite weitergeleitet.
eisbein
eisbein 02.07.2019 um 12:49:08 Uhr
Goto Top
Mahlzeit!

Mein Problem ist jetzt, dass ich das Archivieren/Kopieren und Löschen nicht nacheinander ausgeführt bekomme, wenn ich eins von beidem ausführe, werde ich direkt wieder zur Ursprungsseite weitergeleitet.

Wie führst du Archivieren und Kopieren aus bzw. wie und wo werden die Funktionen aufgerufen?

Wenn nach Archivieren immer ein Löschen folgt, würde ich das gleich in eine Funktion packen und nicht extra. (Also alles bei Archivieren).

Ohne konkreten Programmcode kann man das nicht nachvollziehen.

Gruß
eisbein
Dantaros
Dantaros 03.07.2019 um 11:10:18 Uhr
Goto Top
Das ist mein Block in dem das Archivieren und Löschen stattfinden soll:

// Sicherheitsabfrage Archivierung
if (isset($_GET['aktion']) and $_GET['aktion'] == 'sicherheitarchivieren') {  
    if ( isset($_GET['id'])) {  
        $id_einlesen = (INT) $_GET['id'];  
        echo '<h1>Sicherheitsabfrage Archivieren</h1>';  
        echo '<p>Soll der folgende Datensatz archiviert werden?</p>';  
        echo '<p><a href="?aktion=archivieren&id='. $id_einlesen.'">Archivieren!</a></p>';  
        $_GET['aktion'] = 'anzeigen';  
    }
}

if (isset($_GET['aktion']) and $_GET['aktion']=='archivieren') {  
    if (isset($_GET['id'])) {  
        $id = (INT) $_GET['id'];  
        if ($id > 0)
        {
			$archivieren= $db->prepare (" INSERT INTO archiv SELECT * FROM abholung WHERE id= ?","  DELETE FROM abholung WHERE id=(?) LIMIT 1 " );  
			$archivieren->bind_param('i', $id);  
            //$loeschen = $db->prepare("DELETE FROM abholung WHERE id=(?) LIMIT 1"); 
            //$loeschen->bind_param('i', $id); 
            if ($archivieren->execute()) {
                echo "<p>Datensatz wurde archiviert</p>";  
            }
        }       
    }
}

}

Ganz unten ist der Block in dem die Schritte ausgeführt werden sollen.
Mein letzter Versuch war es beide SQL-Anweisungen in $archivieren zu packen und es dann per execute zu starten, allerdings klappt es nicht.
Sobald ich auf den Button klicke, werde ich nur auf eine weiße Seite weitergeleitet.

Ein anderer Versuch steht oben im Code auch noch dabei, ist aber auskommentiert.
eisbein
Lösung eisbein 03.07.2019 um 11:42:02 Uhr
Goto Top
Sobald ich auf den Button klicke, werde ich nur auf eine weiße Seite weitergeleitet.

Was genau macht der Button und welche Parameter werden damit übergeben?

Der Code den du gepostet hast zeigt lediglich wie die Parameter abgefragt/verarbeitet werden aber sonst auch schon nichts.
Damit in deinem Code auch dein INSERT und DELETE funktioniert, musst du vor Zeile 19 noch ein execute() ausführen, dann erst wieder ein neues prepare() face-wink
Dantaros
Dantaros 03.07.2019 aktualisiert um 12:07:11 Uhr
Goto Top
Mein Button ist in dem Fall kein richtiger Button sondern ein Link.
Den findest du in Zeile 7.

Ich hab den Löschen-Part in den execute-Teil vom Kopieren gepackt, jetzt funktioniert es.

if (isset($_GET['aktion']) and $_GET['aktion']=='archivieren') {  
    if (isset($_GET['id'])) {  
        $id = (INT) $_GET['id'];  
        if ($id > 0)
        {
	$archivieren= $db->prepare (" INSERT INTO archiv SELECT * FROM abholung WHERE id= ? LIMIT 1 " );  
	$archivieren->bind_param('i', $id);  
            if ($archivieren->execute()) {
                $loeschen= $db->prepare (" DELETE FROM abholung WHERE id=(?) LIMIT 1 " );  
				$loeschen->bind_param('i', $id);  
				if ($loeschen->execute()) {
					echo "<p>Datensatz wurde archiviert</p>";  
				}
            }
        }       
    }
}


Danke für die Hilfe. face-smile