Autor | Zpráva | ||
---|---|---|---|
Andrej.B Profil |
#1 · Zasláno: 19. 9. 2018, 21:44:01
Zdravim,
mam databazu, kde su tieto 4 tabulky: vyrobna_zakazka, podsivka, druh, zakaznik Kod nizsie funguje a vypise, co ma... Vyberam podla vyrobna_zakazka: zakaznik, druh, podsivka... Nakolko to chcem mat uzivatelsky prijemne a chcem vypisat nazov z tabulie zakaznik, druh, podsivka , nielen ako cisla, ale pekne menom... Predsa len ukazat uzivatelovi ze ma zakazku cislo 6003537 a tam zakaznik 1, a druh 5 nieje uzivatelsky privetive. Moja otazka znie... Ide to aj nejako lepsie? Uz takto sa mi vidi po spojeni s frontend dost tazkopadne. Dakujem <?php $id_vyrobna_zakazka = '6003537'; $result1 = $conn->query("SELECT * FROM vyrobna_zakazka WHERE id_vyrobna_zakazka = ".$id_vyrobna_zakazka.""); while ($row1 = $result1->fetch_assoc()) { $result2 = $conn->query("SELECT * FROM zakaznik WHERE id_zakaznik = ".$row1['id_zakaznik'].""); $result3 = $conn->query("SELECT * FROM druh WHERE id_druh = ".$row1['druh'].""); $result4 = $conn->query("SELECT * FROM podsivka WHERE id_podsivka = ".$row1['podsivka'].""); } while ($row2 = $result2->fetch_assoc()) { echo $row2['meno_zakaznik'].' - '; //vypise meno zakaznika z tabulky zakaznik } while ($row3 = $result3->fetch_assoc()) { echo $row3['nazov_druh'].' - ';//vypise nazov druhu } while ($row4 = $result4->fetch_assoc()) { echo $row4['druh_podsivka'].' - '; } ?> DATABAZA CREATE TABLE `vyrobna_zakazka` ( `id_vyrobna_zakazka` int(11) NOT NULL, `id_zakaznik` int(11) NOT NULL, `druh` text COLLATE utf8_bin NOT NULL, `podsivka` tinytext COLLATE utf8_bin NOT NULL, ) CREATE TABLE `podsivka` ( `id_podsivka` int(11) NOT NULL, `druh_podsivka` varchar(255) COLLATE utf8_bin NOT NULL, `info_podsivka` varchar(255) COLLATE utf8_bin NOT NULL ) CREATE TABLE `druh` ( `id_druh` int(11) NOT NULL, `nazov_druh` varchar(255) COLLATE utf8_bin NOT NULL, `info_druh` text COLLATE utf8_bin NOT NULL ) CREATE TABLE `zakaznik` ( `id_zakaznik` int(11) NOT NULL, `meno_zakaznik` varchar(255) COLLATE utf8_bin NOT NULL, `ico` int(11) NOT NULL, `text` text COLLATE utf8_bin NOT NULL ) |
||
Radek9 Profil |
#2 · Zasláno: 19. 9. 2018, 21:55:16
Andrej.B:
Join? SELECT vz.*, p.druh_podsivka, d.nazov_druh, z.meno_zakaznik FROM vyrobna_zakazka vz JOIN podsivka p ON p.id_podsivka = vz.podsivka JOIN druh d ON d.id_druh = vz.druh JOIN zakaznik z ON z.id_zakaznik = vz.id_zakaznik WHERE id_vyrobna_zakazka = :id |
||
Kcko Profil |
#3 · Zasláno: 19. 9. 2018, 22:15:30
A ještě doplním, chápeš co dělá while?
|
||
Kajman Profil |
#4 · Zasláno: 19. 9. 2018, 22:18:23
Pokud by spojení nebylo vždy 1:1, tak mrkněte na
Srovnání dotazů do závislých tabulek |
||
Andrej.B Profil |
#5 · Zasláno: 20. 9. 2018, 05:23:42
Radek9:
tento zapis je pre mna dost nepochopitelny. Co znamena: Select vz.* , ci p.druh_podsivka, pravdepodobne len skratky? Ma tam byt podsivka.druh_podsivky? Viem len id_vyrobna_zakazka z tabulky vyrobna_zakazka a potrebujem druh_podsivka,meno_zakaznik a nazov_druh. Ako potom z takehoto zapisu dostanem vysledok? Dik za trpezlivost Kcko: da mi vysledok do pola? z ktoreho si potom vyberiem, co potrebujem? Asi to nieje koser, kedze potrebujem vzdy len jeden riadok, teda aspon na tomto priklade to tak je... Kajman: podla clanku to mam dost neefektivne.. horsie je ze logiku tych JOIN prikazov horsie chapem. |
||
Taps Profil |
Andrej.B:
pokud vybiras jen jeden zaznam tak je while zbytecne. while muzes pouzit kdyz vybiras 2 a vice zaznamu z databaze p.druh_podsivka ( p = alias, da se rict ze je to zkraceny nazev pro databazovou tabulku) misto aby jsi pouzil podsivka.druh_podsivky tak staci zapis p.druh podsivky |
||
Radek9 Profil |
#7 · Zasláno: 20. 9. 2018, 08:38:59
Andrej.B:
„pravdepodobne len skratky? Ma tam byt podsivka.druh_podsivky?“ Nikoli, jsou to aliasy. Jsou definovány na řádcích 2–5. Takže nic měnit nemusíš, tohle je funkční kód. Pouze musíš dosadit :id . Buď pomocí prepared statementu nebo pomocí spojení stringu, jako to máš teď (v tomhle případě to id ale nezapomeň ošetřit, pokud pochází od uživatele).
„Ako potom z takehoto zapisu dostanem vysledok?“ Ten můj dotaz vybírá všechny sloupce z té první tabulky a potom ty tři konkrétní sloupce z ostatních. Takže k nim prostě jenom přistoupíš: <?php $id_vyrobna_zakazka = 6003537; $result = $conn->query(' SELECT vz.*, p.druh_podsivka, d.nazov_druh, z.meno_zakaznik FROM vyrobna_zakazka vz JOIN podsivka p ON p.id_podsivka = vz.podsivka JOIN druh d ON d.id_druh = vz.druh JOIN zakaznik z ON z.id_zakaznik = vz.id_zakaznik WHERE id_vyrobna_zakazka = ' . $id_vyrobna_zakazka ); $row = $result->fetch_assoc(); echo $row['meno_zakaznik'] . ' - ' . $row['nazov_druh'] . ' - ' . $row['druh_podsivka']; |
||
Kajman Profil |
Andrej.B:
V tabulce vyrobna_zakazka je správně sloupec zákazník jako číslo, ale špatně druh a podšívka jako text, pak se ne to nemusí správně propojit s id druhu a id pošívky. |
||
Andrej.B Profil |
#9 · Zasláno: 20. 9. 2018, 11:26:50
Taps:
ok, myslel som si.. je to vlastne len kopirovane z ineho stareho projektu /8 rokov som neprogramoval/, zacal som sa zase vzdelavat :) Radek9: budem to musiet preluskat nejako, a asi hlavne prerobit trocha tie tabulky, kedze su dost neprehladne (meno_zakaznik vs nazov_druh (malo by byt skor meno_druh) a podobne), ale vypada to super, ze mozem aj inde potom pouzit tieto premenne /$row['meno_zakaznik']/, co vypadnu po dotaze. Osetrenie premennych pouzivam $id_vyrobna_zakazka = HTMLSpecialChars($_POST['id_vyrobna_zakazka']); Kajman: ako som pisal vyssie, troska prerobim tie polia tabuliek, aby to bolo viac prehladne. Dakujem moc, dost ste mi pomohli a urcite to nebude naposledy :) Andrej |
||
Radek9 Profil |
#10 · Zasláno: 20. 9. 2018, 12:00:35
Andrej.B:
„Osetrenie premennych pouzivam“ To je fajn na ošetření textových HTML vstupu, ale neřeší to ošetření SQL injection. Speciálně pro textové vstupy používej ještě mysqli_real_escape_string . U čísel naopak nemusíš používat tebou používanou funkci. Mělo by stačit zkontrolovat, jestli je to opravdu číslo.
|
||
Keeehi Profil |
#11 · Zasláno: 20. 9. 2018, 14:20:03
Radek9:
„To je fajn na ošetření textových HTML vstupu“ Spíš by se to mělo používat u výstupů do HTML. |
||
Kajman Profil |
#12 · Zasláno: 20. 9. 2018, 14:29:11
No z databáze se veznou data - tento vstup se escapováním upraví pro korektní html výstup :-)
|
||
Andrej.B Profil |
#13 · Zasláno: 20. 9. 2018, 20:47:04
pokial mam kod:
$result22 = $conn->query("SELECT * from balik WHERE id_vyrobna_zakazka = ".$id_vyrobna_zakazka." ORDER BY cislo_balik DESC LIMIT 1"); while ($row33 = $result22->fetch_array()) { $cislo_balik = $row33['3']+1; } tak zoberie z DB najvacsie cislo_balik podla $id_vyrobna_zakazka a pripocita 1, pokial tam zatial ziadn zaznam nieje, vyhodi chybu: Incorrect integer value: '' for column 'cislo_balik' at row 1, kedze nemoze vlozit prazdnu premennu $cislo_balik. Nizsie je iba Insert, ktory pracuje spravne, ked je pocet riadkov minimalne 1 ako dosiahnut toho, ze ked vrati prazdny pocet riadkov z DB aby pripocitalo +1. Skusal som vsemozne IF ELSE v spojeni s $result22->num_rows; ale stale vypisuje rozne chyby. POtrebujem docielit toho aby premena $cislo_balik bola +1 ako najvyssia cislo_balik v DB a ak nie je ziadn zaznam tak da 1 uf neviem ci som to dobre napisal. diky |
||
Kajman Profil |
if ($row33 = $result22->fetch_array()) { $cislo_balik = $row33['3']+1; } else { $cislo_balik = 1; } |
||
Keeehi Profil |
#15 · Zasláno: 21. 9. 2018, 00:19:53
Andrej.B:
Úplně si nejsem jistý zda ti rozumím, ale možná to trefím. Nemáš náhodou prehozené pořadí toho selectu a insertu? Když vyžaduješ aby při selectu jsi měl 1+ záznamů neměl by být ten insert před selectem? |
||
Andrej.B Profil |
#16 · Zasláno: 21. 9. 2018, 07:11:59
Kajman:
ked sa do da zlozito, naco to robit jednoducho :) Super... ja som este urobil nakoniec takto, ale vase je krajsie ... $row_cnt = $result22->num_rows; if($row_cnt==0) { $cislo_balik = 1; } else { while ($row33 = $result22->fetch_array()) { $cislo_balik = $row33['3']+1; } } Keeehi: najskor sa pozriet do DB ci tam vobec je balik a az potom dat +1... mam to tazkopadne nakolko cislo balika sa nakoniec sklada ako cislo zakazky 6006363 + cislo balika, ktore je 001 ... 002 atd... Cize cislo balika je nakoniec 6006363001 ... co je dane historicky... Netusil som ako to spravit v DB, takze takto sa mi to videlo najednoduchsie. mam V DB polozku : `cislo_balik` tinyint(3) UNSIGNED ZEROFILL NOT NULL, ktora mi pridava ku kazdemu cislo 1-9 dve 0 a ak je nad desat tak 1... cez rozne podmienky sa mi to nechcelo a takto to funguje :) |
||
Časová prodleva: 2 měsíce
|
|||
Andrej.B Profil |
#17 · Zasláno: 1. 12. 2018, 23:30:11
Zdravim,
minuly kod isiel tak ako mal, ale troska som updatoval cely script aj logiku usporiadania... Teraz mam $id_vyrobna_zakazka = $_GET[zakazkaid]; $result = $conn->query(" SELECT vz.*, z.meno_zakaznik, d.nazov_material FROM vyrobna_zakazka vz JOIN zakaznik z ON z.id_zakaznik = vz.id_zakaznik JOIN sklad_material d ON d.id_material = vz.id_top WHERE id_vyrobna_zakazka = '".$id_vyrobna_zakazka."'"); $row = $result->fetch_assoc(); echo $row['meno_zakaznik']; echo $row['nazov_material']; // vyberie ten id_top meno_zakaznika vyberie dobre. Potom mi vybera aj z tabulky sklad_material - id_top, vyberie dobre... lenze v tabulke vyrobna_zakazka mam okrem id_top aj id_middle a id_down, to je vlastne z coho sa sklada ten vyrobok... Ako to mozem urobit v tom selecte z databazy aby to vedelo, ze berie vsetky tri id_top,id_middle, id_down vyberie mi len ten prvy ako echo $row['nazov_material'];
Ako mam na ten Join v databaze ist? Skusal som rozne JOIN sklad_material d ON d.id_material = vz.id_top OR d.id_material = vz.id_middle ale neviem ako to urobit takto v jednom dotaze ten vypis cez $row[] tabulka vyrobna_zakazka CREATE TABLE `vyrobna_zakazka` ( `id_vyrobna_zakazka` int(11) NOT NULL, `id_zakaznik` int(11) NOT NULL, `id_top` int(11) NOT NULL, `id_middle` int(11) NOT NULL, `id_down` int(11) NOT NULL, `odpocet_chyby` float NOT NULL DEFAULT '0.25', `datum_zakazka` int(11) NOT NULL, ) ENGINE=InnoDB DEFAULT CHARSET=utf8; diky za rady |
||
Kajman Profil |
Můžete připojit třikrát tu stejnou tabulku, stačí použít jiné aliasy. Jistější bude left join. Pak i vybíranému sloupci s názvem dejte různé aliasy.
Něco jako SELECT vz.*, z.meno_zakaznik, mt.nazov_material nazov_top, mm.nazov_material nazov_middle, md.nazov_material nazov_down FROM vyrobna_zakazka vz LEFT JOIN zakaznik z ON z.id_zakaznik = vz.id_zakaznik LEFT JOIN sklad_material mt ON mt.id_material = vz.id_top LEFT JOIN sklad_material mm ON mm.id_material = vz.id_middle LEFT JOIN sklad_material md ON md.id_material = vz.id_down WHERE id_vyrobna_zakazka = '$id_vyrobna_zakazka' Ale možná by tomu slušela samotná vazební tabulka místo těch tří sloupců, abyste mohl mít libovolný počet materiálů k jedné zakázce. |
||
Andrej.B Profil |
#19 · Zasláno: 2. 12. 2018, 11:16:14
wau... tie aliasy som skusal vseliako, len mi to chyby hadzalo... Diky...
Pri tvoreni vyrobnej zakazky si vyberam vrchny, stredny a spodny material ... mozem mat nekonecno /cca 200x40x20/ roznych variacii materialov. A takto mam prehlad, kolko materialu ktoreho sa minulo... Skusal som si zadefinovat material z tych 3 roznych , ze budem mat v tabulke vyrobna_zakazka polozku id_laminat a ten by bral z tabulky laminat tieto tri id_top, id_middle a id_down , ale to by znamenalo , ze by som musel mat tieto laminaty uz dopredu urobene a bolo by ich velmi vela a mal by som to uz moc rozbite a osobne pre mna dost neprehladne potom robit na to selecty do statistiky a podobne... Uz teraz mam problem len vytvorit poriadny dotaz na db :) Ale viem, ze toto este nieje definitivne ... super diky moc |
||
Časová prodleva: 5 let
|
0