Autor Zpráva
Daves
Profil *
Zdravím, prosím vás potřebuji poradit jak napsat část metody pro update. Například níže je správný dotaz, který bych chtěl zjednodušit.

$database->query('UPDATE users SET ? WHERE id=?', $data, $id);

Představa zjednodušeného dotazu :

$arr = array(
"name" => "Radek",
"age" => 25
);

$database->query('UPDATE $tableName SET $arr);

Rozhodně tohle není správně, proto se ptám na radu zkušenějších jak by šel update dotaz zjednodušit, pokud třeba potřebuji update pro 15 sloupečků v tabulce, tak to vypisovat je katastrofa.

Příklad metody pro insert, která je parádní

$this->getTableDb() je například users
$this->getFieldsDb() je například array("name"=>"Pavle","age"=>35)

$db->save($this->getTableDb(), $this->getFieldsDb());

Nějak tak bych si představoval i metodu pro update... předem děkuji všem za reakce ! :)
Prochy
Profil
U dibi to funguje následovně:
$db->query('UPDATE %n',$tableName, 'SET', $values,'WHERE [id]=%i",$id)

Myslím si, že u Nette databáze bude něco podobného.
Daves
Profil *
Prochy:
Díky zkusím to napodobit.
Alphard_
Profil *
Prochy:
U dibi to funguje následovně
Jen tak pro zajímavost, jde to ještě jednodušeji
$db->update($tableName, $values)->where('[id]=%i', $id)->execute()
Kubo2
Profil
Daves:
Môžeš si naprogramovať metódu (v PHP), ktorá ti bude generovať obdobné dotazy:

UPDATE users u
JOIN (
  SELECT
    2 id,
    'Adela' name,
    16 age
  UNION
  SELECT
    6 id,
    'Blažena' name,
    32 age
) d
USING(id)
SET
  u.name = d.name,
  u.age = d.age

Napríklad $db->update($table, $by, $columnValues):

<?php

$db->update('users', 'id', [
    2 => [ // <-- tento index je id
        'name' => '...',
        'age' => 16,
    ],
    // atd.
]);

// alebo:
$db->update('users', ['id', 'age'], [
    [
        // old value => new value
        'id' => [3 => 18],
        'age' => [29 => 32],
        'name' => 'Karol',
    ],
    // ...
]);

Ale to druhé by už asi bolo príliš komplexné pre nejaké normálne využitie. :-)


Pozri tiež na sqlfiddle.
Daves
Profil *
Jojo to mě taky napadlo, ale chtěl bych něco jednoduššího

Alphard : díky to vypadá elegantně vyzkouším také.

To skládání sql mám pro select, když chci data nebo zjistit zda něco existuje v tabulce, ale i tak si myslím že je to neefektivní, ale funguje to perfektně.

    function select($table, $where, $type) {
        $counter = 0;
        $sql = "SELECT * FROM $table WHERE ";
        foreach ($where as $val => $key) {
            if ($counter == 0) {
                $sql.= $val . "=" . "'" . $key . "'";
            } else {
                $sql.= " AND " . $val . "=" . "'" . $key . "'";
            }
            $counter++;
        }
        // echo $sql;

        if ($type == "data") { // pokud získávám data tak jen vrátím pole hodnot podle dotazu
                 return $this->connect()->query($sql);
        } else if ($type == "exist") { // pokud zjišťuji existenci záznamu 
            $exist = $this->connect()->query($sql);
            foreach ($exist as $val) {
                if (!isset($val['id'])) {
                    return false;
                } else {
                    return true;
                }
            }
        }
    }

Zatím ale mám problém s tím UPDATE, jdu to vyzkoušet a napíšu. Děkuji všem za reakce odzkouším to.


Prosím Vás chtěl bych se zeptat, kde může být chyba....

        $id = 36;
        $tableName = "usersinfo";

        $db = new TableSelection($tableName, $this->connect());

        $values = array("height" => "25", "body" => "maximal");

        $db->update($tableName, $values)->where('[id]=%i', $id)->execute();
Vyhodí to chybu: InvalidArgumentException
Keeehi
Profil
Dle doc.nette.org/cs/2.3/database-selection
... ->where('id', $id)-> ...
Daves
Profil *
Keeehi:
Nepomohlo, ještě dotaz. Když si sql sestavím sám pracnější cestou a použiji dotaz pomocí nette query("dotaz"), tak si nette samo ošetří escape atd že ?
Prochy
Profil
Ta moje rada byla pro Dibi, která za hranaté závorky dosadí zpětný apostrof, u Nette DB to bude asi bez toho. Jinak jestli mohu poradit ptej se spíše přímo na stránkách Nette fóra. Tam ti poradí určitě líp (a asi i rychleji) než tady, i když sem Nettaři chodí určitě taky.
Alphard
Profil
Daves:
Když si sql sestavím sám ... tak si nette samo ošetří escape atd že ?
Myslíte podobnou bezpečnostní katastrofu jako [#6]? Ne, neošetří. Jak by mohlo? Informace o tom, co jsou vnější data, je ztracena.

Nevím, jestli nevymýšlíte naprosté zbytečnosti. Nette db moc neznám, ale dibi jsem používal dlouho a přiměl jsem ho udělat téměř cokoliv, aniž bych si sám textově sestavoval dotaz.
daves
Profil *
Alphard:
Tak nevím zda je to taková katastrofa si ten dotaz sestavit sám. Navíc s nette DB spíše začínám, ještě před měsícem jsem psal čisté sql... takže, vaše doporučení je zkusit používat dibi ?


Asi opravdu vyzkouším DIBI, jediné čeho chci docílit, tak mít metody pro UPDATE,INSERT,SELECT, které budou bezpečné
Alphard
Profil
daves:
Tak nevím zda je to taková katastrofa si ten dotaz sestavit sám.
Obecně samozřejmě ne, ale...
1. Když si dotaz sestavuji sám, musím myslet na escapování, tedy ošetřit si vstupní data. To jste neudělal.
2. Používáte předpokládám docela schopnou knihovnu. Sestavováním dotazů vlastně nahrazujete část její funkčnosti. Nevadí to, ale je to zbytečné. Neznám možnosti Nette db, ale dibi zvládá všechno, co jste zatím chtěl.
Jan Tvrdík
Profil
daves:
Řešení toho původního dotazu pro NDB:

$db->table($tableName)->wherePrimary($id)->update($values);

Vaše odpověď


Prosím používejte diakritiku a interpunkci.

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