Update dat do databeze pomoci DUPLICATE KEY UPDATE
- parti
- Člen | 117
Ahoj nepomohl by mi nekdo se sestavenim dotazu pro update dat do DB. Mam zatim tohle.
while ($row = fgets($fileOpen)!== FALSE) { //fgets ziskava radky ze souboru
// pri kazdem pruchodu bude v $row dalsi radek
$cols = explode(',', $row);//delimeter
//\Tracy\Debugger::barDump($folder);
$a = isset($cols[0]) ? $cols[0] : '' ;
$b = isset($cols[1]) ? $cols[1] : '' ; //isset vraci true nebo false, jestli volany index pole existuje.
$c = isset($cols[2]) ? $cols[2] : '' ;
//
$sql-> mysql_query("INSERT into tabulka (a, b, c) VALUES ('".$a."','".$b."','".$c."') ON DUPLICATE KEY UPDATE
mysql_query($sql) or die(mysql_error()))");
// $row = $this->presenter->database->table('parking_user')->insert(array('parking_user_id'));
//fclose($fileOpen);
}
Dekuji moc za kazdu radu
- parti
- Člen | 117
Cilem dotazu :
Dotaz by mel vlozit data do db. Napriklad $a – prezivka $b – jmeno $c –
prijmeni. Jmeno a prijmeni muzu mit dva lidi stejny ale prezivku ne ta je
unikatni.
Ve skratce mam csv ktere obsahuje naprikad prezivku, jmeno a prijmeni. A tyto
udaje potrebuji dostat do db.Pridat nove a popripade stare updatovat.
nasel jsem si tohle a podle toho jsem i postupoval ale jak si rikal neni to nette dotaz do db.
http://dev.mysql.com/…plicate.html
Editoval parti (13. 1. 2017 9:31)
- parti
- Člen | 117
Pokud by doslo ke vlozeni duplicitni prezivky tak to zahodi jako ze tam ten
uzivatel uz je (existuje) jenom zkontroluje jestli se nezmenilo jeho jmeno nebo
prijmeni.A jde dal.
A pokud by to byl novy uzivatel z prezivkou ktera tam uz uxistuje tak mu to
vyhodi ze tato prizivka je uz obsazena.
Editoval parti (13. 1. 2017 9:53)
- parti
- Člen | 117
hm no bylo mi receno ze mam pouzit ON DUPLICATE KEY UPDATE tak jsem ted
torchu zmateny.
Ten doatz zacinal Insertem a pak tam bylo ON DUPLICATE KEY UPDATE
$sql-> mysql_query("INSERT into tabulka (a, b, c) VALUES ('".$a."','".$b."','".$c."') ON DUPLICATE KEY UPDATE
// mysql_query($sql) or die(mysql_error()))");
Nevim co ty nato??
Jeste se zeptam pokud to takto pustim tak mi to vyhodi
Undefined variable: sql
Kde ji ma definovat?
Nezlob se za tento typ dotazu ale ucim se dokumentace nette je v tom trochu
zkromna :o( tak se ptam.
Editoval parti (13. 1. 2017 10:03)
- CZechBoY
- Člen | 3608
Jak dokumentace Nette? Však Nette nepoužíváš :D
Pro upřesnění: Chceš aby při vložení duplicitních dat se zkontrolovalo jméno+příjmení a zároveň chceš aby se to nezaložilo. tzn. pokud jsou údaje shodné tak je to ok, ale když se liší jméno/příjmení tak to nedovolit?
while ($row = fgets($fileOpen)!== FALSE) {
$cols = explode(',', $row);
$a = isset($cols[0]) ? $cols[0] : '' ;
$b = isset($cols[1]) ? $cols[1] : '' ; //isset vraci true nebo false, jestli volany index pole existuje.
$c = isset($cols[2]) ? $cols[2] : '' ;
try {
$this->databaseContext->table('table')->insert(array ( // zkusim vlozit radek
'a' => $a,
'b' => $b,
'c' => $c,
));
} catch (\Nette\Database\UniqueConstraintViolationException $e) {
$row = $this->databaseContext->table('table')->where('a', $a)->fetch(); // vytahnu existujici radek podle A
if ($row->b === $b && $row->c === $c) {
// ok
} else
// neco se zmenilo
}
}
}
- parti
- Člen | 117
No pokud budu nove udaje tak je tam vlozi.V zasade jde jenom o
1 – pridani novych uzivatelu.
2 – pokud by novy uzivatel ma prezivku ktera tam uz je tak ho to
zahodi.(kontrola vkladanych uzivatelu podle prezivky)
3 – a starych uzivateloch jenom zkontroluje.Jestli nedoslo ke zmene jmena
napriklad se slecna vda a zmeni se ji prijmeni tak se nahraje nove prijmeni.
Nette tady pouzivam ale to je jenom cast kodu co jsem poslal.
Editoval parti (13. 1. 2017 10:41)
- CZechBoY
- Člen | 3608
while ($row = fgets($fileOpen)!== FALSE) {
$cols = explode(',', $row);
$jmeno = isset($cols[0]) ? $cols[0] : '' ;
$prijmeni = isset($cols[1]) ? $cols[1] : '' ;
$prezdivka = isset($cols[2]) ? $cols[2] : '' ;
if (trim($prezdivka) === '') { // pokud je prazdna prezdivka
continue; // preskocit dalsi zpracovani
}
try {
$this->databaseContext->table('uzivatel')->insert(array ( // zkusim vlozit radek
'jmeno' => $jmeno,
'prijmeni' => $prijmeni,
'prezdivka' => $prezdivka,
));
} catch (\Nette\Database\UniqueConstraintViolationException $e) {
$row = $this->databaseContext->table('uzivatel')
->select('jmeno')
->select('prijmeni')
->where('prezdivka', $prezdivka)
->fetch(); // vytahnu existujici radek podle A
if ($row->prijmeni === $prijmeni) {
if ($row->jmeno === $jmeno) {
// ok
} else {
// zmenilo se jmeno
$row->update(['prijmeni' => $prijmeni]);
}
} else
// prijmeni je jine (a jmeno mozna taky)
}
}
}
Upozorním, že řešení předpokládá unikátní klíč na sloupci
prezdivka
.
- Mysteria
- Člen | 797
@CZechBoY Já to psal na tohle zadání:
Dotaz by mel vlozit data do db. Napriklad $a – prezivka $b – jmeno $c – prijmeni. Jmeno a prijmeni muzu mit > dva lidi stejny ale prezivku ne ta je unikatni.
Ve skratce mam csv ktere obsahuje naprikad prezivku, jmeno a prijmeni. A tyto udaje potrebuji dostat do > db.Pridat nove a popripade stare updatovat.
Pak by mu to fungovalo, když bude unikátní klíč na přezdívce, tak to vloží všechny nové a u existujících přezdívek to změní jména a příjmení na aktuální.
Záleží jak konkrétně myslí bod:
2 – pokud by novy uzivatel ma prezivku ktera tam uz je tak ho to zahodi.(kontrola vkladanych uzivatelu podle prezivky)
Pokud se v případě existující přezdívky má změnit jméno a příjmení na tu z CSV, tak moje fungovat bude. Pokud nechce v takovém případě dělat nic (tzn. nechat jméno a příjmení původní z databáze), tak bude potřeba použít to, co jsi navrhl ty.
- parti
- Člen | 117
Ahoj jenom pridavam svoje reseni na ukol.
Ukol byl nahravani a update dat pomoci csv.
Chci podekovat CZechBoY za pomoc a inspiraci.
Jsem jenom zacatecnik takze klidne mi to muzete zkritizovat.
$folder = dirname(__DIR__).'_DATA_'.'CSV/'. $year . '/' .$month. '/'.$date;
FileSystem::createDir($folder);
// save uploaded file to storage
$file = $values['csv'];
$file->move($folder. '/parking_'.substr(md5(rand()), 0, 8).'.'.'csv');
$fileOpen = fopen($file,'r');
$i = 1;
while ($row = fgets($fileOpen, 1024)) {
if ($i > 1) {
$cols = explode(';', $row);
$prezivka = Nette\Utils\Strings::trim(isset($cols[0])? $cols[0] : '');
$jmeno = Nette\Utils\Strings::trim(isset($cols[1])? $cols[1] : '');
$prijmeni = Nette\Utils\Strings::trim(isset($cols[2])? $cols[2] : '');
$params = [$prezivka, $jmeno, $prijmeni,$prezivka, $jmeno, $prijmeni];
$sql = 'INSERT INTO parking_user(prezivka,jmeno,prijmeni)
VAlUES (?,?,?)
ON DUPLICATE KEY UPDATE prezivka = ?, jmeno = ?, prijmeni = ?';
$this->presenter->database->queryArgs($sql, $params);
}
$i++;
}
Jenom by me ciste ze zvedavosti a teoreticky zaojimalo jestli ma nette nejake
moznosti na konci uploudu vypsat pocet uspesnych nahrani napriklad „bylo
nahrano 100 zaznamu z toho 5 neuspesnych“.
Je to len ciste teoreticka otazka.
- CZechBoY
- Člen | 3608
@parti Nikdy nepřistupuj k property presenteru! Ani pokud by to měl
být BasePresenter.
V té tvé službě/komponentě použij dependency injection a předej si
všechny závislosti (např. databázi) přes konstruktor. https://doc.nette.org/…dependencies
Ohledně vypsání nějaké hlášky – existuje flashMessage jak
v presenteru tak i komponentě (každý si vypisuje ty svoje).
https://doc.nette.org/…n/components#…
- parti
- Člen | 117
OK dekuji za informace.
Jen by me jeste zaojimalo pokud bych chtel rozsirit exploed o vice oddelovacu
jako je carka dvojetcka ma nette neco nato?
zkusil jem neco take
$delimiters = Array(";",",",":","|","-");
$cols = explode($delimiters[0],$row);
ale nedela to co by to melo.
Co se tyka te db tak to je tady cele spatne napsane a suhlasim stebou.
Editoval parti (16. 1. 2017 9:53)
- parti
- Člen | 117
Ahoj tak zase zpatky. Nevite kde mam chybu? Respektive pokud nahravam stejny csv se stejnym obsahom dat tak to projde a vlozit to do db stejne data. Pokud je v csv nejaka zmena tak to pracuje spravne ale kdyz tam neni tak to nahraje znovu vsechno. Takze se muze stat ze to uzivatel nahraje dva krat.SPATNE
$folder = dirname(__DIR__).'_DATA_'.'CSV/'. $year . '/' .$month. '/'.$date;
FileSystem::createDir($folder);
// save uploaded file to storage
$file = $values['csv'];
$file->move($folder. '/parking_'.substr(md5(rand()), 0, 8).'.'.'csv');
$fileOpen = fopen($file,'r');
$i = 1;
while ($row = fgets($fileOpen, 1024)) {
if ($i > 1) {
$cols = explode(';', $row);
$prezivka = Nette\Utils\Strings::trim(isset($cols[0])? $cols[0] : '');
$jmeno = Nette\Utils\Strings::trim(isset($cols[1])? $cols[1] : '');
$prijmeni = Nette\Utils\Strings::trim(isset($cols[2])? $cols[2] : '');
$params = [$prezivka, $jmeno, $prijmeni,$prezivka, $jmeno, $prijmeni];
$sql = 'INSERT INTO parking_user(prezivka,jmeno,prijmeni)
VAlUES (?,?,?)
ON DUPLICATE KEY UPDATE prezivka = ?, jmeno = ?, prijmeni = ?';
$this->presenter->database->queryArgs($sql, $params);
}
$i++;
}
Nevite co mam spatne??
- parti
- Člen | 117
Jde o to ze v csv muze byt pouzit misto stredniku carka a v tom pripade
kdzy tam bude carka tak to neoddeli a vse hodi v DB do jednoho sloupce.
priklad:
mrkva;petrzel;brambora – OK vlozi do db spravne a rozdeli do slopcu.
mrkva;petrzel;brambora
mrkva,petrzel,brambora -vlozi spatne vse do jednoho sloupce
$cols = explode(';', $row);
zkousel jsem musltiexplode, dale to dat do pole atd.. ale nic
Editoval parti (16. 1. 2017 15:32)
- h4kuna
- Backer | 740
SplFileObject má možnost čtení jako csv
$splFile = new \SplFileObject($file);
$splFile->setFlags(SplFileObject::READ_CSV | SplFileObject::SKIP_EMPTY | SplFileObject::DROP_NEW_LINE);
foreach($splFile as $row) {
dump($row);
}