Jak pracují databáze na Webu
Náročnější manipulace s daty

Jiří Kosek ml.

Minule jsme si ukázali, jak vypsat obsah tabulky a jak vytvořit formulář a skript pro přidávání údajů do tabulky. Každá aplikace, která to s daty myslí vážně, musí nabízet mnohem více -- možnost data mazat, modifikovat či selektivně prohledávat. O tom všem bude dnešní pokračování seriálu.

Když umíme záznamy přidávat, nebyla by na škodu možnost i nepotřebné záznamy mazat. Smazání záznamu je v SQL jednoduchá věc -- stačí znát hodnotu primárního klíče záznamu, který chceme smazat, a vše vyřeší příkaz ve tvaru:

DELETE FROM Zamestnanci 
WHERE OsobniCislo = hodnota
Před námi stojí úkol, jak od uživatele získat osobní číslo zaměstnance, kterého chce smazat. Jednou z možností, která je poměrně uživatelsky přítulná, je doplnění našeho výpisu obsahu tabulky o tlačítka vyvolávající smazání jednotlivých záznamů (viz obr. 1).

Obr. 1: Pohodlný způsob, jak si vybrat záznam určený ke smazání
Pohodlný způsob, jak si vybrat záznam určený ke smazání

Tlačítka doplníme jednoduše tak, že do každého řádku tabulky přidáme buňku s malým formulářem. Formulář bude obsahovat pouze dvě pole -- tlačítko pro odeslání a skryté pole, které bude sloužit k přenosu osobního čísla zaměstnance, kterého chceme smazat. Do skriptu pro výpis zaměstnanců z minulého dílu přidáme následující příkaz:

echo "<TD><FORM ACTION=16-01.php3>
      <INPUT TYPE=HIDDEN NAME=OsobniCislo
      VALUE=".
      ODBC_Result($vysledek, "OsobniCislo").">
      <INPUT TYPE=Submit VALUE=\"Smazat\"></TD></FORM>";
Takže pro první záznam tabulky bude skriptem vygenerován formulářík:
<TD><FORM ACTION=16-01.php3>
<INPUT TYPE=HIDDEN NAME=OsobniCislo
       VALUE=1023>
<INPUT TYPE=Submit VALUE="Smazat"></TD></FORM>
Pozorný čtenář nyní možná objevil malou nesrovnalost v HTML zápisu -- kříží se nám elementy TD a FORM. Pokud však ukončovací tagy uvedeme ve správném pořadí </FORM></TD>, bude buňka tabulky zvětšena o neesteticky velké prázdné místo. Je to způsobeno tím, že za konec každého formuláře se vkládá kousek prázdného místa. Překřížení elementů tento neduh odstraní. Nečisté, leč o to účinnější řešení.

Elegantnější řešení, které však funguje jen v prohlížečích s dobrou podporou kaskádových stylů (testováno v MSIE 4.0), využívá vlastnost margin, která ovlivňuje velikost okrajů:

<TD><FORM ACTION=16-01.php3
          STYLE="margin: 0px">
<INPUT TYPE=HIDDEN NAME=OsobniCislo
       VALUE=1023>
<INPUT TYPE=Submit VALUE="Smazat"></FORM></TD>
Pokud naleznete elegantnější a všeobecně použitelné řešení tohoto problému, dejte mi vědět. Rád se o ně podělím s ostatními čtenáři.

Samotný skript pro smazání záznamu je obdobou skriptu pro přidání nového záznamu. Pouze se liší prováděný SQL-příkaz. Skript obdrží osobní číslo zaměstnance určeného k výmazu v proměnné $OsobniCislo.

<HTML>
<HEAD>
<TITLE>Smazání záznamu</TITLE>
</HEAD>
<BODY>
<?
@$spojeni = ODBC_Connect("test", "", "");
if (!$spojeni):
  echo "<H1>Nepodařilo se připojit 
            k databázi!</H1>";
else:
  @$vysledek = ODBC_Exec($spojeni,
    	      "DELETE FROM Zamestnanci 
    	       WHERE OsobniCislo = $OsobniCislo");
  if (!$vysledek):
    echo "<H1>Záznam se 
              nepodařilo smazat!</H1>";
  else: ?>
    <H1>Záznam byl úspěšně smazán</H1>
    <FORM ACTION=15-04.php3>
    <INPUT TYPE=Submit 
           VALUE="Prohlížení seznamu zaměstnanců">
    </FORM>
<?
  endif;
  ODBC_Close($spojeni);
endif;
?>
</BODY>
</HTML>
Nyní nás čeká úkol na první pohled nejnáročnější -- umožnit uživateli měnit stávající údaje o zaměstnancích. Prvním krokem bude vytvoření tlačítka, které vyvolá modifikaci určitého záznamu. Tlačítko přidáme k tabulce s výpisem stejným způsobem jako jsme přidali tlačítko pro mazání. Stisk tlačítka však nyní vyvolá formulář (16- 02.php3), který bude sloužit pro modifikaci záznamu. Jak takový formulář může vypadat? Velice podobně jako formulář pro zadání nového záznamu -- jen se v něm zobrazí údaje z aktuálně vybraného záznamu a bude umožněna jejich editace. Uživateli umožníme editovat všechny údaje kromě primárního klíče (osobního čísla). Pokud bychom umožnili i změnu primárního klíče, museli bychom ošetřit spoustu věcí: zda již takový primární klíč neexistuje, zda se změnou klíče neporuší vazby na jiné tabulky, kde je primární klíč v roli cizího klíče apod.
<HTML>
<HEAD>
<TITLE>Modifikace záznamu v tabulce Zamestnanci</TITLE>
</HEAD>
<BODY>
<?
@$spojeni = ODBC_Connect("test", "", "");
if (!$spojeni):
  echo "<H1>Nepodařilo se připojit 
            k databázi!</H1>";
else:
  @$vysledek = ODBC_Exec($spojeni,
   	      "SELECT * FROM Zamestnanci 
   	       WHERE OsobniCislo = $OsobniCislo");
  if (!$vysledek || !ODBC_Fetch_Row($vysledek)):
    echo "<H1>Záznam se 
              nepodařilo najít!</H1>";
  else: 
    $Jmeno = ODBC_Result($vysledek, "Jmeno");
    $RC = ODBC_Result($vysledek, "RC");   
    $Adresa = ODBC_Result($vysledek, "Adresa");  
    $Plat = ODBC_Result($vysledek, "Plat"); ?>
    <H1>Modifikace záznamu 
        v tabulce Zamestnanci</H1>
    <STRONG>Opravte údaje o zaměstnanci:</STRONG>
    <FORM ACTION=16-03.php3>
    <TABLE>
    <TR><TD>Osobní číslo:
        <TD><?echo $OsobniCislo?>
           <INPUT TYPE=HIDDEN NAME=OsobniCislo
                   VALUE=<?echo $OsobniCislo?>>
    <TR><TD>Jméno:
        <TD><INPUT NAME=Jmeno VALUE="<?echo $Jmeno?>">
    <TR><TD>Rodné číslo:
        <TD><INPUT NAME=RC VALUE="<?echo $RC?>">
    <TR><TD>Adresa:
        <TD><INPUT NAME=Adresa VALUE="<?echo $Adresa?>">
    <TR><TD>Plat:
        <TD><INPUT NAME=Plat VALUE="<?echo $Plat?>">
    <TR><TH COLSPAN=2>
        <INPUT TYPE=Submit VALUE="Zapsání změn">
    </TABLE>
    </FORM>
<?
  endif;
  ODBC_Close($spojeni);
endif;
?>
</BODY>
</HTML>
Výsledek našeho snažení přináší obrázek 2. Uživatel může údaje změnit a odeslat je. My tedy ještě musíme vytvořit skript, který změnu údajů promítne do tabulky. S výhodou k tomu využijeme SQL-příkaz UPDATE.

Obr. 2: Formulář pro modifikaci záznamu
Formulář pro modifikaci záznamu
Skript pro samotné zapsání změn do tabulky může vypadat třeba takto:
<HTML>
<HEAD>
<TITLE>Změna záznamu v tabulce Zamestnanci</TITLE>
</HEAD>
<BODY>
<?
@$spojeni = ODBC_Connect("test", "", "");
if (!$spojeni):
  echo "<H1>Nepodařilo se připojit 
            k databázi!</H1>";
else:
  @$vysledek = ODBC_Exec($spojeni,
   	      "UPDATE Zamestnanci 
   	       SET Jmeno = '$Jmeno',
   	           RC = '$RC',
               Adresa = '$Adresa', 
               Plat = $Plat
           WHERE OsobniCislo = $OsobniCislo");
  if (!$vysledek):
    echo "<H1>Záznam se 
              nepodařilo změnit!</H1>";
  else: ?>
    <H1>Záznam byl úspěšně změněn</H1>
    <FORM ACTION=15-04.php3>
    <INPUT TYPE=Submit 
           VALUE="Prohlížení seznamu zaměstnanců">
    </FORM>
<?
  endif;
  ODBC_Close($spojeni);
endif;
?>
</BODY>
</HTML>
Poslední věcí, o které se zmíníme v souvislosti s databázemi, je možnost vyhledávání. Představme si, že v naší tabulce o zaměstnancích je několik stovek či tisíců záznamů. Pokud si tabulku necháme jen tak vypsat celou v prohlížeči, získáme nepřehledný dlouhý seznam, který se navíc bude natahovat nepřiměřeně dlouho. Řešením je vytvoření jednoduchého formuláře, který uživateli umožní zadat prvních pár písmen ze jména zaměstnance a skript pak zobrazí pouze vyhovující záznamy:
<HTML>
<HEAD>
<TITLE>Prohledávání seznamu zaměstnanců</TITLE>
</HEAD>
<BODY>
<H1>Prohledávání seznamu zaměstnanců</H1>
<FORM ACTION="16-04.php3">
Zadejte začátek jména zaměstnance:
<INPUT NAME=Jmeno VALUE="<?echo $Jmeno?>">
<INPUT TYPE=Submit VALUE="Hledej">
</FORM>
<HR>
<?
if ($Jmeno!=""):
  @$spojeni = ODBC_Connect("test", "", "");
  if (!$spojeni):
    echo "Nepodařilo se připojit k databázi.";
  else:
    @$vysledek = ODBC_Exec($spojeni,
        "SELECT * FROM Zamestnanci 
         WHERE Jmeno like '$Jmeno%'");
    if (!$vysledek):
      echo "Chyba při provádění dotazu v databázi";
    else: 
      echo "Počet nalezených zaměstnanců: ".
           ODBC_Num_Rows($vysledek)."<BR>\n";

        ...Vypsání výsledků dotazu,
        to už umíme...

    endif;
    ODBC_Close($spojeni);
  endif;
endif;
?>
</BODY>
</HTML>
Zajímavostí může být použití operátoru LIKE v příkazu SELECT. V parametru LIKE, který určuje řetězec k porovnání můžeme použít znak `%', který zastupuje libovolný počet libovolných znaků. Tím dosáhneme toho, že výsledkem dotazu budou pouze ty záznamy, jejichž atribut Jmeno začíná na řetězec uložený v proměnné $Jmeno.

Poslední skripty, které pracovaly s databázemi, jsou už přece jen delší. Ne vždy jsme je tedy mohli na stránkách Computerworldu uvést celé. Proto jsem pro vás na Web umístil kompletní zdrojové texty posledního příkladu pro práci s tabulkou zaměstnanci. Naleznete je na stránkách seriálu http://www.kosek.cz/clanky/iweb/.

Příště naše povídání o skriptech ukončíme. Ale nebojte se, nečeká nás stránka plná sentimentu, ale mnoho užitečných informací a praktických ukázek.

© Jiří Kosek 1999