3. díl - MySQL krok za krokem: Vkládání a mazání dat v tabulce

MySQL MySQL krok za krokem: Vkládání a mazání dat v tabulce

V minulém dílu seriálu tutoriálů o MySQL databázi jsme si vytvořili databázi a v ní tabulku uživatelů. Dnes budeme vkládat a mazat záznamy, tedy uživatele.

Vložení záznamu do tabulky

Vložení nového uživatele si ukážeme opět nejprve přes phpMyAdmin. Rozklikněte si tabulku uzivatele. V horní liště vybereme možnost Vložit. Vyplníme pouze ta pole v sloupci Hodnota a pole uzivatele_id ponecháme prázdné. To se vyplní samo díky vlastnosti AUTO_INCREMENT. Obsah polí vyplníme jak potřebujeme a potvrdíme tlačítkem Proveď:

Vložení záznamu do tabulky v phpMyAdmin

Nyní si tabulku rozklikneme a vidíme, že Jan Novák je opravdu uložen v databázi.

phpMyAdmin nám ukázal další SQL dotaz, tím je INSERT. Vložit Jana Nováka bychom mohli stejně i tímto dotazem:

INSERT INTO `uzivatele` (
        `jmeno`,
        `prijmeni`,
        `datum_narozeni`,
        `pocet_clanku`
)
VALUES (
        'Jan',  'Novák',  '1984-11-03', 17
);

První řádek je opět jasný, prostě říkáme "Vlož do uživatelů", další řádky jsou sloupce, ve kterých bude mít nová položka nějaké hodnoty. Sloupec s id zde neuvádíme. Následuje slovo values a další výčet prvků v závorkách, tentokrát hodnot. Ty jdou v tom pořadí, jaké jsme uvedli u názvů sloupců. Textové hodnoty jsou v uvozovkách nebo apostrofech, všechny hodnoty oddělujeme čárkami.

POZOR! Pokud vkládáme do SQL dotazu text (zde třeba jméno uživatele), nesmí obsahovat uvozovky, apostrofy a pár dalších znaků. Tyto znaky samozřejmě do textu zapsat můžeme, jen se musí ošetřit, aby si databáze nemyslela, že jde o část dotazu. Ještě se k tomu vrátíme.

Vložte si pomocí SQL dotazu několik uživatelů, pokud nemáte fantazii, klidně vložte ty z tabulky na začátku:

Uživatelé v MySQL tabulce

Vymazání záznamu

Zkusme si někoho vymazat. Asi byste přišli na to, že se to dělá tím červeným tlačítkem odstranit. Zkuste si to.

Vymazání se v jazyce SQL dělá pomocí příkazu DELETE:

DELETE FROM `uzivatele` WHERE `uzivatele_id` = 2;

Zkuste si to, phpMyAdmin je na DELETE opatrný a bude se vás ptát.

Příkaz je jednoduchý, voláme "vymaž z uživatelů", kde se hodnota ve sloupci uzivatele_id rovná 2. Zaměřme se na klauzuli WHERE, která definuje podmínku. Potkáme ji i v dalších dotazech. Jelikož zde mažeme podle primárního klíče, jsme si jisti, že vždy vymažeme právě jednoho uživatele. Podmínku samozřejmě můžeme rozvinout, závorkovat a používat operátory AND (a zároveň) a OR (nebo):

DELETE FROM `uzivatele` WHERE (`jmeno` = 'Jan' AND `datum_narozeni` >= '1980-1-1') OR (`pocet_clanku` < 3);

Příkaz výše vymaže všechny Jany, kteří byli narození po roce 1980 nebo všechny uživatele, kteří napsali méně než 3 články.

POZOR!, nikdy na klauzuli WHERE nezapomeňte, pokud napíšete jen:

DELETE FROM `uzivatele`;

Budou vymazáni všichni uživatelé v tabulce!

SQL injection

SQL injection je termín, označující narušení databázového dotazu škodlivým kódem od uživatele.

Rozhodl jsem se tuto pasáž vložit hned na začátek seriálu. Pokud vás nějak zmate, tak si z toho nic nedělejte, hlavní je o riziku vědět, stejně si bezpečnou práci s databází ukážeme vždy u příslušného jazyka.

Co je SQL injecton

Představme si, že naše tabulka s uživateli je součástí databáze nějaké aplikace. A také, že umožníme uživateli (naší aplikace) mazat uživatele podle příjmení. Do dotazu vložíme tedy nějakou proměnnou, která pochází od uživatele:

DELETE FROM `uzivatele` WHERE `prijmeni` = '$prijmeni';

$prijmeni je proměnná, obsahující třeba tento text:

Novák

Dotaz se tedy sestaví takto:

DELETE FROM `uzivatele` WHERE `prijmeni` = 'Novák';

Dotaz se provede a vymaže všechny Nováky. To zní jako to, co jsme chtěli. Teď si ale představte, co se stane, když někdo do proměnné zadá toto:

' OR 1 --

Výsledný dotaz bude vypadat takto:

DELETE FROM `uzivatele` WHERE `prijmeni` = '' OR 1 --';

Protože 1 je z logického hlediska vždy pravda a v podmínce je, že buď musí mít uživatel prázdné příjmení nebo musí platit pravda (což platí), vymaže dotaz všechny uživatele v tabulce. Poslední uvozovky se útočník zbavil komentářem (dvě pomlčky), který v dotazu zruší vše do konce řádku. Šikovnější útočníci dokáží udělat injekci v kterémkoli SQL příkazu, nejen v DELETE.

Řešení

Nebojte, řešení je velmi jednoduché. Problém dělá několik speciálních znaků v proměnné, jako jsou uvozovky a několik dalších. Pokud tyto znaky potřebujeme, musíme je tzv. odescapovat, tedy předsadit zpětným lomítkem. V aplikaci to za nás nějakým způsobem řeší ovladač databáze, buď to dělá úplně sám nebo data musíme pomocí něj před vložením do dotazu nejprve odescapovat. Určitě si to zjistěte, než začnete s databází pracovat. Pokud budete používat zdejší návody, bude to v nich vždy uvedeno.

Odescapovaný dotaz by vypadal takto:

DELETE FROM `uzivatele` WHERE `prijmeni` = '\' OR 1 --';

Takový dotaz je neškodný, protože část vložená uživatelem je považována jako text. V textu se nevyhodnotí uvozovka a tím pádem ani komentář. Další variantou, jak aplikaci zabezpečit proti injekci, je obsah proměnné do dotazu vůbec nezadávat. V dotazu jsou poté uvedeny pouze zástupné znaky (otazníky):

DELETE FROM `uzivatele` WHERE `prijmeni` = ?;

A proměnné se pošlou databázi potom zvlášť a najednou. Ona si je tam sama navkládá tak, aby nevzniklo žádné nebezpečí. To je však teorie okolo konkrétního ovladače databáze a jak bylo řečeno, naleznete ji u jazyka, ze kterého budete s databází komunikovat (např. v sekci PHP).

Editace záznamů

Databáze umožňuje 4 základní operace, které jsou často označovány zkratkou CRUD (Create, Read, Update, Delete). Jsou to tedy vytvoření záznamu, načtení (vyhledání), update (editace) a vymazání záznamu. Vytvoření a vymazání již umíme. Chybí nám tedy ještě editace a vyhledávání. Vyhledávání věnujeme celý příští článek, editaci si vysvětlíme ještě dnes.

Na editaci v phpMyAdminu byste jistě přišli, stačí rozkliknout tabulku a u daného záznamu kliknout na Upravit. K úpravě slouží SQL dotaz UPDATE, úprava nějakého uživatele by vypadala asi takto:

UPDATE `uzivatele` SET `prijmeni` = 'Dolejší', `pocet_clanku` = `pocet_clanku` + 1 WHERE `uzivatele_id` = 1;

Za klíčovým slovem UPDATE následuje název tabulky, poté slovo SET a vždy název sloupce = hodnota. Můžeme měnit hodnoty více sloupců, pouze se oddělí čárkou. Můžeme dokonce použít předchozí hodnotu z databáze a třeba ji zvýšit o 1, jako v ukázce výše.

Příště půjdeme na slíbené vyhledávání.


 

  Aktivity (1)

Článek pro vás napsal David Čápka
Avatar
Autor pracuje jako softwarový architekt a pedagog na projektu ITnetwork.cz (a jeho zahraničních verzích). Velmi si váží svobody podnikání v naší zemi a věří, že když se člověk neštítí práce, tak dokáže úplně cokoli.
Unicorn College Autor se informační technologie naučil na Unicorn College - prestižní soukromé vysoké škole IT a ekonomie.

Jak se ti líbí článek?
Celkem (15 hlasů) :
55555


 



 

 

Komentáře
Zobrazit starší komentáře (4)

Avatar
Kit
Redaktor
Avatar
Kit:

Nic. Až to budeš potřebovat, přijdeš na to.

Odpovědět 23.10.2012 8:56
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Vašek
Neregistrovaný
Avatar
Vašek:

Ahoj,
mám takovej problem a potřeboval bych poradit, nebo spíš nakopnout. Chci pro známého vytvořit web s formulářem, do kterého by zástupci jednotlivých SVJ zapisovali spotřeby tepla na výrobu tepla a teplé už. vody. Problém je, že každé SVJ má různý počet bytů ve správě a další mnohem složitější (alespoň pro mne) je ten, že web se dělá pro lidi, kteří s PC pracují jen z donucení a není tedy příliš vhodné, aby se pro vložení údajů jednotlivých bytových jednotek vygeneroval malý formulář, do které by vložili údaje o bytě a tyto údaje odeslali, načež by se vygeneroval formulář pro vložení dalšího bytu. Pro tyto lidi je myslím vhodnější vygenerovat tabulku s inputy pro všechny byty a hodnoty najednou. Asi takto : http://test.doauta.eu a teď přichází můj pro mě, jak dostanu takovou tabulku do mysql? Popravdě řečeno napadlo mě, že musí být nějaké řešení, když opačné řešení pro zobrazení dat z tabulky je relativně snadné

for($i=0; $i<$pocet; $i++):
$Firma = mysql_Result($result, $i, "CisloBytu");
endfor;

,ale na to už moje škeble nestačí, tak to zkouším u Vás. Díky každému za radu.

 
Odpovědět 25.6.2013 0:07
Avatar
ucenidolazni
Člen
Avatar
ucenidolazni:

Ahoj, prosím mám takový problém. Mám vytvořený skript pro uložení uživatelů do databáze (registrace), k mysql se bez problému připojím a všemi kroky skript projde, ale data se do databaze vubec neuloží, nevíte prosím kde může být chyba ?
Obsah souboru config.php :

$mysql_ip = "localhost";
$mysql_user = "root";
$mysql_pass = "";
$mysql_name = "registrace";
include "config.php";
                        mysql_connect($mysql_ip,$mysql_user,$mysql_pass);
                        mysql_select_db($mysql_name);
                        $q = mysql_query("SELECT * FROM registrace WHERE prezdivka='".$_POST['prezdivka']."'");
                        if(mysql_num_rows($q) == 0)
                        {
                          $pass = md5($_POST['heslo']);
                          mysql_query("INSERT INTO registrace values(0,'".$_POST['prezdivka']."','".$pass."','".$_POST['email']."')");

                    echo "<center><strong><p /><font color='green'>Registrace proběhla úspěšně›</font></strong></center></center>";
                    echo"<meta http-equiv='refresh' content='2;url=index.php'>";
                } else {
                    echo "<center><strong><p /><font color='fuschia'>Uzivatel jiz existuje</font></strong></center>";
                }
Editováno 26.2.2014 10:40
 
Odpovědět 26.2.2014 10:38
Avatar
mkub
Redaktor
Avatar
mkub:
  1. oprav si SQL injection
  2. okrem toho ti hrozi, ze z toho kodu budes mat gulas...
 
Odpovědět 26.2.2014 10:47
Avatar
Pavel
Redaktor
Avatar
Pavel:

Ahoj,

řeším problém s delete a SQL co neumí SUBDOTAZ.

Potřebuji smazat víc než 10 zaznamů(prvních 10 nechat), ID uživatele, tříděno podle data (datumVlozeni)

Zkoušel jsem:

DELETE FROM banery WHERE iduzivatele=1 AND id NOT IN
(SELECT id FROM banery WHERE iduzivatele=1 ORDER BY datumVlozeni DESC LIMIT 10);

nebo

DELETE FROM banery WHERE iduzivatele=1 ORDER BY datumVlozeni LIMIT
(SELECT COUNT(*) FROM banery WHERE iduzivatele=1)-10;

Díky

Pavel

Editováno 22.6.2015 21:15
 
Odpovědět 22.6.2015 21:15
Avatar
Jakub Jan Kadlec:

Ahojky všem, moc se mi líbí vaše návody. Mám Minecraft server a serverový web. Na webu bych rád nějaký formulář, který by uživatel vyplnil, odeslal a automaticky by se napsané údaje zapsaly do databáze. Šlo by to nějak udělat? Děkuji Jakub

 
Odpovědět 13. ledna 16:56
Avatar
Odpovědět 13. ledna 23:22
I have a charger. I have Note 7. Umh I haven't Note7.
Avatar
Robert
Člen
Avatar
Robert:

Ako upravím konkrétný riadok v tabuľke?

 
Odpovědět 6. listopadu 14:33
Avatar
Robert
Člen
Avatar
Odpovídá na Robert
Robert:

Už som asi na to prišiel. Ja som to spravil cez WHERE.

UPDATE uzivatelia SET datum_narodenia= '1992-2-2' WHERE priezvisko = 'Novotný';

 
Odpovědět 6. listopadu 14:38
Avatar
Odpovídá na Robert
Michal Štěpánek:

Ano, ale pozor na to, když tam bude víc "Novotných", tak se to tímto způsobem změní u VŠECH. Lepší je k úpravě konkrétního záznamu (řádku) použít sloupec s IDčkem, které bude unikátní...

Odpovědět 6. listopadu 14:53
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 10 zpráv z 14. Zobrazit vše