tiny ‘n’ smart
database layer

Odkazy: dibi | API reference

Oznámení

Omlouváme se, provoz fóra byl ukončen

INSERT … ON DUPLICATE KEY UPDATE – jen reálný update

před 10 lety

maarlin
Člen | 207

Řeším aktuálně tento problém:

Mám napsaný dotaz:

$this->connection->query('INSERT INTO ', $this->table, $data, ' ON DUPLICATE KEY UPDATE %a', $data);

po kterém ale chci, aby zároveň neprováděl UPDATE, když „není co updatovat“, resp. neupdatoval, když se data shodují s těmi, co jsou v databázi (když se shodují všechny sloupce, tj. nejen shodné klíče)…

Jde to udělat jedním dotazem, nebo to opravdu musím rozepsat do dvou? Popř. šlo by to napsat nějakým subquery?

Editoval maarlin (30. 1. 2010 17:16)

před 10 lety

phx
Člen | 652

Kapku nechapu…

To co mas zaznam vlozu kdyz NENI kolize PK nebo unikatnich klicu. Pokud je kolize tak provede udpate.

Ve vysledku je celkem jedno zda update zapise ty sama data jakou jsou aktualne v DB. Tusim, ze MySQL je tak chytra, ze update neprovadi kdyz se nic nezmeni.

před 10 lety

maarlin
Člen | 207

phx napsal(a):
Ve vysledku je celkem jedno zda update zapise ty sama data jakou jsou aktualne v DB.

Právě že mě to jedno není :-)

Tusim, ze MySQL je tak chytra, ze update neprovadi kdyz se nic nezmeni.

Buď opravdu tak chytrá není, nebo něco dělám špatně…

Jde o to, že v tabulce je jeden sloupec – last_update, který má dávat najevo poslední změnu toho záznamu – je typu DATETIME.

Možná by to nějak šlo s TIMESTAMP a CURRENT_TIMESTAMP jako default…

Zkusím.

před 10 lety

phx
Člen | 652

100% vim, ze kdyz provadis normalni update tak pri shodnych datech mi mysql vraci affected rows = 0. Osobne jsem to ale netestoval pri ON DUPLICATE KEY UPDATE.

Pokud tam je sloupecech timestamp tak ten se sam automaticky nastavi na aktualni hodnotu kdyz provadis update.

před 9 lety

westrem
Člen | 398

phx napsal(a):

100% vim, ze kdyz provadis normalni update tak pri shodnych datech mi mysql vraci affected rows = 0. Osobne jsem to ale netestoval pri ON DUPLICATE KEY UPDATE.

Pokud tam je sloupecech timestamp tak ten se sam automaticky nastavi na aktualni hodnotu kdyz provadis update.

Ten vysledok 0 pri affected rows si myslel, ze na konzole vidis 0 alebo ti to vrati nejaka metoda z dibi?

Ono totiz, ja osobne toto povazujem za skryty bug, co bugom nie je. Ked sa pytame na affected rows tak je to naozaj 0, castokrat vsak clovek testuje uspech // neuspech dotazu typu UPDATE pomocou affected rows v dibi. Problem nastava, ked existuje riadok vyhovujuci update, ale ako sam vravis data su rovnake takze vysledok v affected rows je 0. Ak clovek v kode potom testuje podmienkou, ze ak je affected rows rovny nule tak nastala chyba, ktoru treba oznamit, moze oznamovat chyby – nechyby.

Problem je jednak pri nativnych php funkciach pre mysql ale aj v dibi .. osobne som to zariesil tak, ze som si nad tuto funkciu dibi napisal vlastnu, ktora vracia spravne to co od takejto kontroly ocakavam.

Aky je Vas nazor na tuto problematiku?

před 9 lety

David Grudl
Nette Core | 6806

westrem napsal(a):

Ono totiz, ja osobne toto povazujem za skryty bug, co bugom nie je. Ked sa pytame na affected rows tak je to naozaj 0, castokrat vsak clovek testuje uspech // neuspech dotazu typu

Pokud dojde k chybě, dibi vyhodí výjimku. Tedy testování if (dibi::query(...)) je z principu špatné.

před 9 lety

westrem
Člen | 398

David Grudl napsal(a):

westrem napsal(a):

Ono totiz, ja osobne toto povazujem za skryty bug, co bugom nie je. Ked sa pytame na affected rows tak je to naozaj 0, castokrat vsak clovek testuje uspech // neuspech dotazu typu

Pokud dojde k chybě, dibi vyhodí výjimku. Tedy testování if (dibi::query(...)) je z principu špatné.

„Prasarnu“ ako if (dibi::query(...)) by som nikdy nepouzil .. testovanie uspechu query pri update robim ako som vravel pomocou affectedRows s tym, ze mam original dibi funkciu zaobalenu do jednej svojej, ktora riesi par evnetualit ..