Wer kennt's nicht: Man arbeitet gerade an einem TYPO3 Upgrade und es gibt noch M-N Tabellen, die uid_foreign und uid_local nicht als Primary/Secondary Fields gesetzt haben. Mit diesem Script, lässt sich das Problem einfach lösen und der Upgrade-Wizard wieder auf 100% bringen

Duplicate Entry Fehlermeldung

Diese Fehlermeldung kommt oft bei einem TYPO3 Update:

 

Core: Exception handler (WEB): Uncaught TYPO3 Exception: #1062: An exception occurred while executing a query: Duplicate entry 'X' for key 'PRIMARY'

 

Sie besagt, dass es doppelte Einträge für Eintrag X in der Tabelle vorhanden sind. Im Upgrade Wizard bekommen mittlerweile die meisten M-N Tabellen einen Primary/Secondary Key gesetzt, damit die Tabelle nicht vollmüllt, leider passiert das erst bei höheren Versionen und dann trifft es einem nach einem TYPO3 Upgrade. In meinem Fall oft von 11 oder älter auf 12/13.

Man könnte jetzt die Tabelle herunterladen im .sql Format und händisch die Duplikate rausfischen und entfernen.

Oder man nutzt meinen PHP Script, der direkt in der Datenbank danach sucht und die Duplikate entfernt:

 

<?php


$host = "localhost";
$dbname = "dbname";
$username = "dbuser";
$password = "dbpass";


$tableName = "sys_category_record_mm";

try {
    $pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8", $username, $password);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    echo "Verbindung erfolgreich!<br>";

    $query = "SELECT uid_local, uid_foreign, COUNT(*) as count
              FROM $tableName
              GROUP BY uid_local, uid_foreign
              HAVING count > 1";

    $stmt = $pdo->query($query);
    $duplicates = $stmt->fetchAll(PDO::FETCH_ASSOC);

    if (empty($duplicates)) {
        echo "Keine doppelten Einträge gefunden.<br>";
        exit;
    }

    echo "Doppelte Einträge gefunden, bereinige jetzt...<br>";

    // Doppelte Einträge löschen, nur einen behalten
    foreach ($duplicates as $row) {
        $uid_local = $row['uid_local'];
        $uid_foreign = $row['uid_foreign'];

        // Lösche alle bis auf einen mit LIMIT 1
        $deleteQuery = "DELETE FROM $tableName 
                        WHERE uid_local = :uid_local AND uid_foreign = :uid_foreign 
                        LIMIT :limit";

        $deleteStmt = $pdo->prepare($deleteQuery);
        $deleteStmt->bindValue(':uid_local', $uid_local, PDO::PARAM_INT);
        $deleteStmt->bindValue(':uid_foreign', $uid_foreign, PDO::PARAM_INT);
        $deleteStmt->bindValue(':limit', ($row['count'] - 1), PDO::PARAM_INT);
        $deleteStmt->execute();

        echo "Duplikate für uid_local=$uid_local und uid_foreign=$uid_foreign gelöscht.<br>";
    }

    echo "Bereinigung abgeschlossen!";
} catch (PDOException $e) {
    die("Fehler bei der Verbindung oder Abfrage: " . $e->getMessage());
}
?>

 

Es geht ganz einfach, oben werden die Zugangsdaten zur Datenbank eingetragen, dann der Name der Tabelle, die von dem Fehler betroffen ist (In meinem Fall die News M-N Tabelle) und dann wird die PHP Datei im Browser oder per CLI ausgeführt. Nun kann im Migrator der Upgrade-Wizard durchgeführt werden.

Previous PostDDEV Composer: Curl Error 28 while Downloading ... Failed to connect to Port 443
Next PostTYPO3 Extbase Snippet: Storage PID via Variable im Controller setzen