Autor Zpráva
form
Profil *
Ahoj, ukládám do databáze tagy,
$query = 'INSERT INTO tagy (nazev, pocet) VALUES(:nazev, 1) ON DUPLICATE KEY UPDATE pocet = pocet + 1';
$stmt = $db->prepare($query);
foreach ($tagy as $temp) {
  $stmt->execute(['nazev' => $temp]);
}
Ale nechápu proč mi nejdou indexy ID následovně po sobě, 54, 55, 56, 57,...
Mě to přeskakuje... obrázek
na ID mám auto increment
Nevíte v čem je problém?


mám tam natom transakci, zkoušel jsem to i bez ale jde to stejně špatně.


je to kvůli tomu insert, zvýší se zároveň i číslo indexu i když se nic neuloží... ale nevíte jak to vyřešit?


teď jsem zkoušel tam po TOM "DUPLICATE KEY UPDATE" přidat i "ID = LAST_INSERT_ID(ID)", ale výsledek je stejný
Kajman
Profil
Je možné, že se alokuje další id pro insert a až poté se zjistí, že je kolize na jiném sloupci, než je primární klíč. Dělá to i aktuální verzi databáze? Vadí to něčemu?

Edit: tak v dokumentaci to popisují jako vlastnost innodb
dev.mysql.com/doc/refman/8.0/en/insert-on-duplicate.html
form
Profil *
Kajman:
nevím jestli mám nejnověší úplně. Ale jak to mám teda udělat aby to bylo v jednom dotazu.
napsal sje mtohle, ale je to asi pro proceduru.... jak to mám udělat aby to bylo přez klasický dotaz
IF EXISTS (SELECT ID FROM tagy WHERE nazev = :nazev) THEN
        BEGIN
               UPDATE tagy SET pocet = pocet + 1 WHERE nazev = :nazev
           END

        ELSE 
        BEGIN
            INSERT INTO tagy (nazev, pocet) VALUES(:nazev, 1)
        END

2) Proč mi ale nefunguje to s tím "ID = LAST_INSERT_ID(ID)"?


aha, v tom if else sem nemel ukonceni a stredniky,... ale pořád nevím proč nefunogvala verze s tim "ID = LAST_INSERT_ID(ID)"
$query = 'INSERT INTO tagy (nazev, pocet) VALUES(:nazev, 1)
ON DUPLICATE KEY UPDATE
ID = LAST_INSERT_ID(ID),
pocet = pocet + 1';
Kajman
Profil
Funkce last_insert_id() bez parametru vrátí automatické id z minulého dotazu. Funkce volaná s parametrem, vratí ten parametr, ale když se v dalším dotaze zeptáte na last_insert_id(), dostanete také ten parametr. Takže při kolizi a náledném update upravujete ID za ID, což se v update neprojeví, ale alokování id pro prvotní insert to nezabrání, jen můžete zpět do aplikace nebo následujícího dotazu dostat id řádku, který jste upravil.

dev.mysql.com/doc/refman/8.0/en/information-functions.html#function_last-insert-id
dev.mysql.com/doc/refman/8.0/en/mysql-insert-id.html

Pokud jsou pro Vás díry v id problém, stačí jednoduchý update
UPDATE tagy SET pocet = pocet + 1 WHERE nazev = :nazev
a když to neovlivní žádný řádek, udělat druhý dotaz na vložení.
INSERT INTO tagy (nazev, pocet) VALUES(:nazev, 1)

Možná by šlo použít insert select z té samé tabulky, ale přehlednosti v kódu to asi nepomůže.
INSERT INTO tagy (id, nazev, pocet) 
SELECT t.id, x.nazev, 1
FROM   (SELECT :nazev nazev
        FROM   DUAL) x
LEFT JOIN tagy t
       ON x.nazev = t.nazev  
ON DUPLICATE KEY UPDATE pocet = tagy.pocet + 1

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0