it-swarm.com.de

mit Einfügen bei doppelter Schlüsselaktualisierung - Aktualisierung mehrerer Zeilen gleichzeitig

Mit der neuesten Joomla-Version versuche ich, eine Abfrage für die Datenbank durchzuführen und mehrere Zeilen gleichzeitig zu aktualisieren.

Ich möchte eine Frage wie folgt stellen:

INSERT INTO `tablename`
(`id`,`date`) VALUES 
('79','2018-12-01'),('78','2018-10-01'),('76','2018-06-01'),('80','2019-01-01')
ON DUPLICATE KEY UPDATE
(`date` = '2018-12-01'),(`date` = '2018-10-01'),(`date` = '2018-06-01'),(`date` = '2019-01-01')

Wenn ich dies einrichte und debugge:

$query
        ->insert($db->quoteName('#__tablename'))
        ->columns($db->quoteName($columns))
        ->values($values);

dies erzeugt nur die ersten 3 Zeilen meiner Suchabfrage. Wie kann ich erweitern, um den Text "ON DUPLICATE KEY UPDATE" und andere Array-Werte am Ende hinzuzufügen? Oder gibt es einen anderen Weg, dies zu tun? Ist es möglich, mehrere Abfragen zu setQuery hinzuzufügen oder Abfragen zu verketten?

3
almost okey

Das Erstellen einer REPLACE INTO - Abfrage ist genauso einfach wie das Erstellen eines INSERT ... ON DUPLICATE KEY UPDATE. Beachten Sie, dass es gibt einen Unterschied zwischen REPLACE INTO UND ON DUPLICATE KEY UPDATE .

Code:

$columns = ['id', 'date'];
$data = [
    [79, '2018-12-01'],
    [78, '2018-10-01'],
    [76, '2018-06-01'],
    [80, '2019-01-01']
];

$db = JFactory::getDbo();
try {
    foreach ($data as &$row) {
        $row = (int)$row[0] . ", " . $db->q($row[1]); // flatten 2-dim array and apply security techniques
    }
    $query = $db->getQuery(true)
                ->insert($db->qn('#__tablename'))
                ->columns($db->qn($columns))
                ->values($data);
    $db->setQuery(substr_replace($query, 'REPLACE', 0, 8));    // swap INSERT for REPLACE
    // in other words: $db->setQuery(str_replace("\r\nINSERT", "REPLACE", $query));
    // or:             $db->setQuery(preg_replace("~^\s+INSERT~", "REPLACE", $query));
    // Joomla puts \r\n at the start of the query; see via var_dump($db) after setQuery()
    /*
    echo "<pre>";
        print_r($db);   // see the updated sql object
    echo "</pre>";
    */
    $db->execute();
} catch (Exception $e) {
    echo  "Syntax Error: " , $e->getMessage();  // never show php's error message to the public
}
echo "<div>" , $db->getAffectedRows() , " row(s) inserted</div>";

Dies ist die Abfrage:

REPLACE INTO `#__tablename`
(`id`,`date`) VALUES 
(79, '2018-12-01'),(78, '2018-10-01'),(76, '2018-06-01'),(80, '2019-01-01')

Dadurch wird [~ # ~] immer [~ # ~] die gleiche Anzahl betroffener Zeilen für Ihren Stapel von vier Einträgen gedruckt:

4 Zeile (n) eingefügt



Für ON DUPLICATE KEY UPDATE... Ist dies so einfach wie das Anhängen der Klausel an das Ende der von Joomla generierten Abfrage und das Einschließen von VALUES() syntax . (nur ersetzen die $db->setQuery() -Zeile aus dem obigen Snippet)

$db->setQuery($query . " ON DUPLICATE KEY UPDATE `date` = VALUES(`date`)");

so erstellen Sie diese Abfrage:

INSERT INTO `#__tablename`
(`id`,`date`) VALUES 
(79, '2018-12-01'),(78, '2018-10-01'),(76, '2018-06-01'),(80, '2019-01-01')
ON DUPLICATE KEY UPDATE `date` = VALUES(`date`)

Dieser Abfragetyp verhält sich anders und gibt in Bezug auf betroffene Zeilen unterschiedliches Feedback.

Wenn in der Datenbanktabelle für alle Zeilen, die Sie hinzufügen möchten, identische Zeilen vorhanden sind, werden die betroffenen Zeilen mit 0 Angezeigt. Wenn die PRIMARY-ID bereits vorhanden ist - Nehmen wir an, 1 Zeile hat einen anderen date -Wert als in der Abfrage angegeben -, werden betroffene Zeilen mit 2 Angezeigt (ich habe dies auf meinem eigenen localhost ausgeführt) und trotz anderer Dinge, die ich gelesen habe, muss dies entfernt und dann hinzugefügt werden. Diese Art von Informationen kann also entweder sehr hilfreich oder sehr verwirrend sein, je nachdem, was Sie ermitteln möchten. Stellen Sie sich vor, Sie haben bereits alle vier ids in Ihrer Tabelle dargestellt und zwei der vier Zeilen benötigen den Wert date, um aktualisiert zu werden. Nachdem die Abfrage ausgeführt wurde, werden Sie benachrichtigt, dass 4 - Zeilen betroffen sind.

Hier ist eine relevante Antwort, die ich vor ein paar Jahren auf StackOverflow gepostet habe .

2
mickmackusa