Moi,
Yritän rakentaa HTML-taulukkoa, hyödyntäen PHP/SQL. Ohessa koodi:
<?php $stid = oci_parse($conn, "select distinct concat(concat(order_no, '_'), sequence_no) from database where order_no LIKE 'M114244' and release_no = '1'"); oci_execute($stid); $stid2 = oci_parse($conn, "select oper_status_code from database where order_no LIKE 'M114244' and release_no = '1' and operation_no = '22'"); oci_execute($stid2); ?> <table style=" width: 60%; text-align: left; position: absolute; top:220px; left:440px; font-size: 10px;"> <tbody> <tr> <th>ORDER</th></td><th>STAGE</th></td> </td> <?php while (($row = oci_fetch_array($stid, OCI_BOTH))) { foreach ($row as $item) { echo '</tr><td>'.($row[0]).'</td>'; }} while (($row = oci_fetch_array($stid2, OCI_BOTH))) { foreach ($row as $item) { echo '</td><td>'.($row[0]).'</td>'; }} ?> </tbody> </table>
Saan tulokseksi tietyn määrän M-numeroja, jotka muodostuvat tulostetun taulukon sarakkeeseen sinänsä oikein mutta jostain syystä duplikaattina. Sen sijaan oper_status_code- sarakkeen tiedot tulostuvat HTML-taulukon alimmalle riville vaakatasossa.
Tähän tyyliin:
M114244_3
M114244_3
M114244_2
M114244_2
M114244_1
M114244_1 SULJETTU SULJETTU SULJETTU SULJETTU SULJETTU SULJETTU
Koodin tulostus tulisi siis olla näin:
M114244_1 SULJETTU
M114244_2 SULJETTU
M114244_3 SULJETTU
Lopullisena tarkoituksena olisi lisää noita vaihetietoja ja lisätä niiden tietoa seuraaviin sarakkeisiin. Esim. näin:
M114244_1 SULJETTU ALOITETTU
M114244_2 SULJETTU ALOITETTU
M114244_3 SULJETTU ALOITETTU
Pääsettekö kiinni ongelmaani, kaikki apu olisi tervetullutta.
Jokaista solua ennen tulostetaan '<td>' ja solun jälkeen '</td>' Samoin jokaista riviä, missä on noita soluja sitten, ennen tulostetaan '<tr>' ja noiden rivillä olevien solujen jälkeen taas '</tr>'. Onko sulla nää ehdot voimassa?
Rakenne pitäisi olla siis jotakuinkin:
<table> <tr> <td>solu1</td> <td>solu2</td> </tr> /*suljetaan eka rivi */ <tr> /*aloitaan uus rivi */ <td>solu3</td> <td>solu4</td> </tr> </table>
Kiitos Petri,
Pääsin hieman eteenpäin.
Perehdyn hieman lisää ja saatan kysyä jatkokysymyksiä:)
mkl76 kirjoitti:
Kiitos Petri
Kiitti kiitoksesta.
Tässä vielä RED-kielinen esimerkki. Homma hoituu siis kahdella sisäkkäisellä silmukalla. Ulommassa loopataan rivejä ja sisemmässä datoja...Koodirivit kannattaa sisentää, niin sieltä näkee helpommin, mihin niitä datojen ja rivien lopetus- ja aloitus tägejä pitää laittaa.
Siis tällä koodilla tulee tälläinen: https://petke.info/taulukko.html
Red[] rivienlkm: 4 ; rivejä on 4 kpl datojenlkm: 6 ;joka rivillä on 6 data alkiota rivi: 1 print "<table>" loop rivienlkm [ print "<tr>" data: 1 loop datojenlkm [ print "<td>" print rejoin ["Solu " rivi "_" data] print "</td>" data: data + 1 ] print "</tr>" rivi: rivi + 1 ] print "</table>" halt
L-kirjaimen muotoisen ongelman ydin on (HTML-virheen lisäksi) siinä, että HTML:ssä ei voi tulostaa taulukkoa sarake kerrallaan, vaan taulukko tehdään rivi kerrallaan. Eli PHP:ssä ei voi olla erillistä silmukkaa kummallekin sarakkeelle. Tiedot pitää järjestää tai hakea eri tavalla, jotta samassa silmukassa saa tulostettua molemmat sarakkeet.
Datan kahdentuminen johtuu siitä, että yksi tulosrivi (eli yksi arvo, koska SQL-kyselyissä haetaan vain yksi sarake) haetaan asetuksella OCI_BOTH, joka luo $row-taulukkoon sarakkeet sekä nimillä että numeroilla, esimerkiksi siis oper_status_code ja 0, ja sitten foreach-silmukassa tulostetaan nämä molemmat. Pitäisi siis luopua foreach-silmukasta ja tulostaa vain $row-taulukon kohta 0.
Tuo koko rakennelma on riskialtis, kun haetaan useampi asia omilla kyselyillään ja oletetaan, että tulosrivit ovat täsmälleen samat. Yleensä olisi järkevää muotoilla kysely niin, että kaikki tulosrivit saa samalla kyselyllä, tai sitten tuloksiin kannattaa sisällyttää ainakin riittävät tiedot, jotta yhteen kuuluvat tiedot pystyy varmuudella yhdistämään toisiinsa ennen tulostusta.
Minulla on nyt tällainen tuotos, koodi:
<table style=" width: 60%; text-align: left; position: absolute; top:220px; left:440px; font-size: 10px;"> <tbody> <tr> <th>ORDER</th><th>REL</th><th>SEQ</th><th>VAIHE 1</th><th>VAIHE 2</th> </tr> <?php while (($row = oci_fetch_array($stid2, OCI_BOTH))) { echo '<tr><td>'.$row[0].'</td>'; echo '<td>'.$row[1].'</td>'; echo '<td>'.$row[2].'</td>'; echo '<td>'.$row[48].'</td>'; while (($row = oci_fetch_array($stid3, OCI_BOTH))) { echo '<td>'.$row[0].'</td>'; }} ?> </tbody> </table>
Jälkimmäinen looppi ei tulosta vaihetietoja taulukon viimeiseen sarakkeeseen. Pääsetkö kiinni tuohon ilman tulosteen tarkempaa kuvausta. Ylempi looppi tulostaa haetut tiedot taulukkoon aivan kuten haluankin mutta alemman loopin lisäys rikkoo taulukon rakenteen. Tänne kun ei voi lisätä kuvaa ongelman selventämiseksi.
Oletko katsonut, mitä tuosta tulee sivun HTML-koodiksi? Eli nythän sinulla on kaksi silmukkaa sisäkkäin. Taulukon ensimmäisen rivin loppuun tulostat peräkkäin kaikki viimeisen sarakkeen arvot (vierekkäin eikä allekkain, koska näin HTML:n taulukko toimii), ja myöhemmille riveille ei jää viimeiseen sarakkeeseen mitään.
Periaatteessa tuo toimii, jos jälkimmäisen while-silmukan tilalle laitat if-lauseen, mutta varoituksena lue silti edellisen viestini viimeinen kappale.
Metabolix kirjoitti:
(05.07.2022 22:32:42): L-kirjaimen muotoisen ongelman ydin on (HTML...
Jep, asiallista kommenttia. Olenkin jo poistanut foreach- silmukat ja vienyt koodia juuri tuohon kirjoittamaasi suuntaan. Silmukat on itselle vielä hieman hepreaa. Tuon kyselyn kun saisikin yhteen ja samaan kyselyyn mutta en ole siinä vielä onnistunut kun rajatut tiedot pitää vielä saada tulostettuakin taulukkoon. Kyselyn laajentaminen sisältämään enemmän tietoa kun tuppaa omilla koodaustaidoilla tulostelemaan taulukkoon ylimääräistä tietoa.
Metabolix kirjoitti:
(05.07.2022 22:42:41): Oletko katsonut, mitä tuosta tulee sivun HTML...
Voiko if-lausetta käyttää while sijaan koska if pyörähtää vain yhden kerran?
Mutta nythän juuri tarkoitus olisi saada jokaiselle riville jälkimmäisestä kyselystä vain yksi tulos. Taulukkosi on pielessä juuri siksi, että while hakee kaikki jälkimmäisen kyselyn tulokset jo ensimmäiselle taulukon riville.
Metabolix kirjoitti:
Mutta nythän juuri tarkoitus olisi saada jokaiselle riville jälkimmäisestä kyselystä vain yksi tulos. Taulukkosi on pielessä juuri siksi, että while hakee kaikki jälkimmäisen kyselyn tulokset jo ensimmäiselle taulukon riville.
En saa tätä toimimaan. Olisiko sinulla kiinnostusta pureutua tähän aiheeseen esimerkkien kera, vaikka pientä korvausta vastaan? Kenties joku etäkeskustelu esim. Teams tms.?
Jotenkin tälleen alkuperäisen viestin ongelma voisi tuolla tietorakenteella toimia.
<?php $stid = oci_parse($conn, "select distinct concat(concat(order_no, '_'), sequence_no) from database where order_no LIKE 'M114244' and release_no = '1' order by order_no, sequence_no"); oci_execute($stid); $stid2 = oci_parse($conn, "select concat(concat(order_no, '_'), sequence_no), oper_status_code from database where order_no LIKE 'M114244' and release_no = '1' and operation_no = '22' order by order_no, sequence_no"); oci_execute($stid2); ?> <table style=" width: 60%; text-align: left; position: absolute; top:220px; left:440px; font-size: 10px;"> <tbody> <tr> <th>ORDER</th><th>STAGE</th> </tr> <?php $stat = oci_fetch_array($stid2, OCI_NUM); while ($row = oci_fetch_array($stid, OCI_NUM)) { echo '<tr><td>'.$row[0].'</td><td>'; while ($stat && $stat[0]==$row[0]) { echo $stat[1] . ' '; $stat = oci_fetch_array($stid2, OCI_NUM); } echo '</td></tr>'; } ?> </tbody> </table>
Olennaiset muutokset kyseylyissä on, että myös jälkimmäisessä kyselyssä on otettu order_no ja sequence_no ja järjestetty molemmat sen mukaan, jotta tiedetään että ne tulee keskenään samassa järjestyksessä.
Tämähän nyt on hirveä purkkaviritys, mutta kun tietokantarakennekin näyttää olevan purkkaviritys (kaikki samassa database nimisessä taulussa, tilaukset toistettuna ilmeisesti niin monta kertaa kuin on tapahtumia, jne), niin ehkä se sopii.
Jälkimmäiseen 05.07.2022 22:37:19 laitettuun viestiin en nyt ala heittämään arvailuja, kun siinä ei edes näy kyselyitä eikä näin ollen pysty päättelemään mitään siitä miten sidosten ehkä olisi tarkoitus toimia.
Grez kirjoitti:
(11.07.2022 16:15:00): Jotenkin tälleen alkuperäisen viestin ongelma...
Juu, tuossa taulussa on paljon tietoa, käytännössä samalle tilaukselle ja rivinumerolle (sequence_no) voi olla 7-10 eri vaihetta ja näiden kanssa pitäisi pärjätä.
Koodin kyselyt on nyt ao. muodossa. Tilausnumerot muodostuu hyvin järjestyksessä HTML- taulun sarakkeeseen 1 ja vaiheen 20 tiedot seuraa hyvin perässä sarakkeeseen 2. Seuraavaksi pitäisi saada vaiheen nro. 22 tiedot seuraavaan sarakkeeseen nro. 3.
<?php $stid = oci_parse($conn, "select concat(concat(order_no, '_'), sequence_no) from database where order_no LIKE 'M114244' and release_no = '1' group by concat(concat(order_no, '_'), sequence_no) order by concat(concat(order_no, '_'), sequence_no)"); oci_execute($stid); $stid2 = oci_parse($conn, "select concat(concat(order_no, '_'), sequence_no), oper_status_code from database where order_no = 'M114244' and release_no = '1' and operation_no = '20' group by concat(concat(order_no, '_'), sequence_no), oper_status_code order by concat(concat(order_no, '_'), sequence_no), oper_status_code"); oci_execute($stid2); $stid3 = oci_parse($conn, "select concat(concat(order_no, '_'), sequence_no), oper_status_code from database where order_no = 'M114244' and release_no = '1' and operation_no = '22' group by concat(concat(order_no, '_'), sequence_no), oper_status_code order by concat(concat(order_no, '_'), sequence_no), oper_status_code"); oci_execute($stid3); ?>
Eli tämä pitäisi seuraavaksi ymmärtää ja muokata kolmannen sarakkeen tulostamiseksi:
Onko tiedot jostain syystä pakko hakea kesken tulostuksen? Olisi helpompaa kerätä niistä ensin yksi PHP-taulukko ja sitten vasta tulostaa.
$data = []; // Kerää kaikkien kyselyiden tulokset $data-taulukkoon näin: $stid = oci_parse($conn, "SELECT ..."); oci_execute($stid); while ($row = oci_fetch_array($stid, OCI_NUM)) { // $row[0] on se yhteinen tunniste eli concat(...) // $row[1] on kyselyn toinen sarake eli esimerkiksi oper_status_code. $data[$row[0]][] = $row[1]; } // Tulostus: echo "<table>\n"; foreach ($data as $key => $row) { echo "<tr>\n"; echo "<td>", htmlspecialchars($key), "</td>\n"; foreach ($row as $col) { echo "<td>", htmlspecialchars($col), "</td>\n"; } echo "</tr>\n\n"; } echo "</table>\n";
Edellistä viestiä toistaen: tuollainen komentojen suorittaminen kesken tulostuksen on ns. vanhakantaista PHP:tä eli paskaa koodia. Hae tiedot ensin ja suorita tulostus joskus myöhemmin. Tämä helpottaa myös debuggaamista, koska voit tällöin vaikka dumpata haetun datan minne tahansa HTML-dokumentissa.
Jos yrität debugata tuota paskaa koodiasi, niin se on vaikeampaa jo siitä syystä, että selain saattaa renderöidä tulosteen ihan eri tavalla kuin mitä se on lähdekoodissa. (Ongelman voi toki kiertää katsomalla raakaa tulostetta selaimen renderöimän näkymän sijaan, mutta siltikin tuloste voi olla vaikeaa lukea.)
muuskanuikku kirjoitti:
(12.07.2022 22:20:57): Edellistä viestiä toistaen: tuollainen...
Nämä kommentit ei edistä asian ratkaisemista vaikka koodi olisi kokonaisuudessaan iso paskakasa.
mkl76 kirjoitti:
Koodin kyselyt on nyt ao. muodossa. Tilausnumerot muodostuu hyvin järjestyksessä HTML- taulun sarakkeeseen 1 ja vaiheen 20 tiedot seuraa hyvin perässä sarakkeeseen 2. Seuraavaksi pitäisi saada vaiheen nro. 22 tiedot seuraavaan sarakkeeseen nro. 3.
No kai voisit soveltaa tuota aikaisemmin annettua ratkaisua. Katsot mitä siinä tehdään ja teet vastaavan toisellekin.
mkl76 kirjoitti:
Nämä kommentit ei edistä asian ratkaisemista vaikka koodi olisi kokonaisuudessaan iso paskakasa.
Ongelmanhan voi yleensä ratkaista monella tavalla. Metabolixin ehdottama tietojen lukeminen muistiin ensin ja taulukon muodostaminen vasta sitten voisi selkeyttää asiaa ja sen toteuttamisessa ei montaa minuuttia pitäisi kestää.
Metabolix kirjoitti:
(12.07.2022 21:54:01): Onko tiedot jostain syystä pakko hakea kesken...
Tähän asti pyörittelemäni koodinpätkissä olen tosiaan hakenut ja tulostellut pienissä erissä. Nyt kuitenkin yo. esimerkin innostamana onnistuin muodostamaan laajemman kyselyn, jossa tarvittavat tiedot haetaan yhdellä kyselyllä ja ryhmitetään GROUP BY- ehdolla. Tämä ryhmittely on käsittääkseni ehdoton, koska muuten haetut tiedot leviää tulostuksen yhteydessä ihan miten sattuu. Testattu on.
<?php $stid = oci_parse($conn, "select concat(concat(a.order_no, '_'), a.sequence_no), a.sarake1, a.sarake2, a.sarake3 from taulu1 a FULL JOIN taulu2 b ON a.order_no = b.order_no and a.sequence_no = b.sequence_no FULL JOIN taulu3 c ON a.order_no = c.order_no where a.order_no LIKE 'M%' and a.release_no = '1' and 'lisää määrittelyjä tauluista 1,2 ja 3' group by concat(concat(a.order_no, '_'), a.sequence_no), 'jne...' order by concat(concat(a.order_no, '_'), a.sequence_no), 'jne'"); while ($row = oci_fetch_array($stid, OCI_NUM)) { // $row[0] on se yhteinen tunniste eli concat(...) // $row[1] on kyselyn toinen sarake eli esimerkiksi oper_status_code. $data[$row[0]][] = $row[1] ; } // Tulostus: echo "<table>\n"; foreach ($data as $key => $row) { echo "<tr>\n"; echo "<td>", htmlspecialchars($key), "</td>\n"; foreach ($row as $col) { echo "<td>", htmlspecialchars($col), "</td>\n"; } echo "</tr>\n\n"; } echo "</table>\n"; ?>
Nyt pitäisi saada vielä lisäopastusta kuinka valittuja sarakkeita tulostetaan HTML- taulukkoon, $row[2], $row[3] jne., kohdassa:
while ($row = oci_fetch_array($stid, OCI_NUM)) { // $row[0] on se yhteinen tunniste eli concat(...) // $row[1] on kyselyn toinen sarake eli esimerkiksi oper_status_code. $data[$row[0]][] = $row[1] ; }
Yllä olevaan koodiin saat useamman sarakkeen samasta kyselystä näin:
$data[$row[0]][] = $row[1]; $data[$row[0]][] = $row[2]; # jne.
Tämä on tietysti ihan pöllö ratkaisu tilanteessa, jossa olet sittenkin tehnyt yhden kyselyn (alkuperäisen monen kyselyn viritelmän sijaan). Kuitenkin tämä on nyt lyhyin muutos, jolla saat nykyisen koodisi toimimaan.
Kaksi muuta vaihtoehtoa ovat, että opettelet PHP:tä kunnolla tai tilaat työt joltakulta, joka osaa sitä. Montako tuntia olet jo itse käyttänyt näiden parin koodirivin säätämiseen vain siksi, että yksinkertainen taulukko ja silmukka ovat vieraita?
Lienee syytä opetella kunnolla, jotta ei tarvitse näitä kysymyksiä foorumeille heitellä. Kiitoksia näistä vinkeistä, niistä oli paljon apua.
Aihe on jo aika vanha, joten et voi enää vastata siihen.