----KIIREELLINEN----KAIKKI APU ERITTÄIN TOIVOTTAVAA, KIITOS!!!----
- Ongelma1: kun tapahtuman kohdalla 0 varausta, tapahtuma ei näy Tapahtumat-sivulla.
- Ongelma2: kun tapahtuman kohdalla 0 varausta, tapahtumaa ei voi poistaa tietokannasta.
SQL-lause:
$sql_lauseke = "SELECT Varaus.Tapahtuma_Id, COUNT(Varaus.Tapahtuma_Id), Tapahtuma.tStatus, Tapahtuma.T_Id, Tapahtuma.tNimi, Tapahtuma.tVuosi, Tapahtuma.tKuukausi, Tapahtuma.tPaiva, Tapahtuma.tViikonpaiva, Tapahtuma.tTarve, Tapahtuma.tAlkaa, Tapahtuma.tLoppuu, Tapahtuma.tSijainti FROM Varaus INNER JOIN Tapahtuma ON Varaus.Tapahtuma_Id = Tapahtuma.T_Id WHERE Tapahtuma.tStatus = 'Tapahtumat' GROUP BY Varaus.Tapahtuma_Id ORDER BY tVuosi, tKuukausi, tPaiva, tNimi";
-------------------------------------------------------
Mikä avuksi? Ongelma lienee tuo varausten määrä eli niitä ei ole (0 kpl)
Lisäys:
-------------------------------------------------
jaketsu + muut.. tässä leikkaus taulusta:
Tapahtumat:
- T_Id
- tNimi
- tPaiva
- tKuukausi
- tVuosi
- tViikonpaiva
- tAlkaa
- tLoppuu
- tSijainti
- tStatus
- tTarve
jne.
Varaus:
Tapahtuma_Id
Asiakas_Id
varno
Lisäys:
--------------------------------------------------------------
tStatus -> "Tulossa" (näytetään Tapahtumat-sivulla).
Nyt kuitenkin epäilen että ongelma nimenomaan tuossa varausten määrässä 0 kpl, en tajua miksei tapahtuman varausten kohdalla voida näyttää 0 !!!
Lisäys:
jaketsu kirjoitti:
Oletko kokeillut INNER JOINin tilalla LEFT tai RIGHT JOIN? Noiden vaikutus tapauksessasi on tietokannan rakenteesta kiinni.
- Valitettavasti ei ole eroa, inner, left, right...
Lisäys:
Yritän hyödyntää opasta, mutta luultavasti vika tuossa COUNT -kohdassa.
AND, OR, BETWEEN ei myöskään tunnu auttavan. Koska countin arvo 0 niin vertaa sitä Tapahtuma tauluun jotenkin ja en tosiaan osaa sanoa,,,, todella turhauttavaa. Olin jo niin pitkällä ja nyt tämä!
-------------------------------------------------------------
SELECT Varaus.Tapahtuma_Id, COUNT(Varaus.Tapahtuma_Id),
- Tässä kohtaan ajattelen niin että Varaus-taulun varauksia ei voi laskea koska niitä ei ole ja siksi niitä ei voi tulostaa.
- No sitten nuo INNER JOIN ,LEFT, RIGHT -niin ne tuovat aina saman lopputuloksen kuten pelkkä JOIN myös??
Lisäys: Valoa tunnelin päässä kiitos RIGHT JOIN -parametrin...
Lisäys: Noniin jaketsu olikin lopulta taas oikeassa, eli miten varmistaa se että saan tuon T_Id:n ... eli tapahtuman id numero puuttuu jos varauksia 0 kpl
Lisäys:
SELECT Varaus.Tapahtuma_Id, COUNT(Varaus.Tapahtuma_Id), Tapahtuma.tStatus, Tapahtuma.T_Id, Tapahtuma.tNimi, Tapahtuma.tVuosi, Tapahtuma.tKuukausi, Tapahtuma.tPaiva, Tapahtuma.tViikonpaiva, Tapahtuma.tTarve FROM Varaus RIGHT JOIN Tapahtuma ON Varaus.Tapahtuma_Id = Tapahtuma.T_Id WHERE Tapahtuma.tStatus = 'Tapahtumat' GROUP BY Varaus.Tapahtuma_Id ORDER BY tVuosi, tKuukausi, tPaiva, tNimi
- Homma toimii nyt 95% oikein...
- Ongelma on vielä, että jos varauksia 0 kpl, niin ei hae tapahtuman id:tä ollenkaan? Pitäisikö tämä tietoa hakea erillisellä SQL-lauseella?
linkki näyttää tältä= http://x.fi/page_id=63&T_Id=
...eli lopussa ei ole mitään...
Lisäys:
No niin lopultakin.. eli tietenkin Tapahtumien ID:t tulevat kahdessa osassa.. [0] ja [3]
..hetki meni tämäkin tajuta. [0] ei ole mukana varaamattomia tapahtumia, sen sijaan [3] viittaa Tapahtumat tauluun, luonnollisesti, kiitos avusta!
Voit ottaa ensimmäisen valittavan kentän pois kokonaan, kun sillä ei tee mitään. Hakkaat sen kanssa päätä seinään uudestaankin, jos jätät sen siihen roikkumaan. :)
Hetkinen mitä tarkoitat? Tällä hetkellä nimittäin nämä toiminnot toimivat hyvin:
- Hae kaikki tapahtumat joissa status = "Tapahtumat"
- Laske varausten määrä
- Tapahtuman voi poistaa, jolloin myös sen varaukset poistetaan
jne.
Mutta tosiaan tarkoitatko (Varaus.Tapahtuma_Id) eli turhaa haetaan nuo rivit kun ne haetaan uudelleen (Tapahtuma.T_Id) ??
Tapahtuma_Id = T_Id
latenleffahylly kirjoitti:
Mutta tosiaan tarkoitatko (Varaus.Tapahtuma_Id) eli turhaa haetaan nuo rivit kun ne haetaan uudelleen (Tapahtuma.T_Id) ??
Kyllä, juuri tuota tarkoitin.
SELECT [Ylimääräinen härpäke poistettu] COUNT(Varaus.Tapahtuma_Id) ...
latenleffahylly kirjoitti:
Tapahtuma_Id = T_Id
Jos tajusin, mitä tuo tarkoittaa, niin näin: Kaikki sql-lauseen osat, eli siis myös ON ja WHERE, "näkevät" kaikki kentät samalla tavalla kuin SELECTkin. Eli kentän ei tarvitse olla SELECTissä, jotta sitä voidaan käyttää muualla.
SELECT Lemmikit.Nimi FROM Lemmikit INNER JOIN Ihmiset ON Ihmiset.Lemmikki_ID = Lemmikki.ID WHERE Ihmiset.ID = 1;
Yllä oleva koodi saa luvan olla esimerkki.
..tarkoitan suunnilleen tuota. Huomasin että minulla on aivan liikaa komentoja koko SQL-lauseessa muutenkin.. Siitä voi tehdä paljon yksinkertaisemman ja toimivamman. (palaan asiaan myöhemmin, sillä uusi ongelma tuli eteeni)
---------------------------------------------------------'
Eli yritän poistaa tapahtuman ja kaikki siihen tehdyt varaukset. Alla oleva SQL-lause tekee tämän, MUTTA kun varauksia 0 kpl - ei tapahtudu mitään, eli palauttaa 0 riviä.
DELETE Varaus, Tapahtuma FROM Varaus INNER JOIN Tapahtuma WHERE Varaus.Tapahtuma_Id = Tapahtuma.T_Id AND Tapahtuma.T_Id = " . $T_Id . "
- Jos varauksia ei ole, tapahtumaa ei voi poistaa
- Myöskään RIGHT JOIN ei auta
..osaatteko sanoa mikä neuvoksi. Tämä kohta on nyt todellakin se viimeinen kompastuskiveni koko projektin suhteen, joka tuntuu vain venyvän ja venyvän.. Luultavasti ratkaisu hyvin samanlainen kuin edellisen SQL-lauseen suhteen. Suurkiitokset jälleen kaikista kommenteista ja ohjeista (olen noviisi)
Enköhän sanonut siinä poistokysymyksen alussa jo, että olisi käytännöllisempää ajaa kaksi erillistä DELETE-kyselyä – yksi kumpaankin tauluun.
Metabolix näköjään ehtikin jo väliin. Eli samalla asialla olin itsekin:
Henkilökohtaisesti näen useammasta taulusta poistamisen (jos tuossa nyt sitä edes yritetään) yhdellä kertaa muuten kuin ryöppyäviä vierasavaimia käyttäen erittäin kyseenalaisena tapana, vaikka se ilmeisesti joissain tietokannoissa onnistuukin.
Eli siis jos haluat poistaa Tapahtuman ja siihen liittyvät varaukset, niin itse tekisin näin:
DELETE FROM Varaus WHERE Tapahtuma_Id= " . $T_Id . " DELETE FROM Tapahtuma WHERE T_Id = " . $T_Id . "
Okei teen niin kuin te sanotte, mutta miten sitten jatkan..
else if($toiminto == "Poista" ) { $sql_lauseke = "DELETE Varaus, Tapahtuma FROM Varaus INNER JOIN Tapahtuma WHERE Varaus.Tapahtuma_Id = Tapahtuma.T_Id AND Tapahtuma.T_Id = " . $T_Id . ""; if( !$kysely = mysql_query($sql_lauseke)) { echo "virhe!"; } else { echo "Tiedot poistettu."; } }
Eli miten saan tuonne sulkujen sisään 2 muuttujaa, mielestäni (,) pilkku ei auta?
Joudut suorittamaan mysql_query:n kahteen kertaan.
Yleisestikään useamman kyselyn erottimena ei käytetä pilkkua vaan puolipistettä, mutta mysql_queryssä on estetty useamman kyselyn suorittaminen kerralla.
Okei.. huoh.. tuota, tuota.. Yritän nyt sitten kaiketi rakentaa tuollaisen IF- IF- koodi-ketjun..
Lisäys: Eli hetkinen voinko laittaa SQL-lauseen tuon ELSE { kohdan sisään..
Ei ole mitään rajoituksia mitä koodia else:n jälkeen tulevien aaltosulkujen väliin voi laittaa.
Eli kyllä voit.
Tai jos et kuitenkaan aio indikoida tarkemmin kumpi kyselyistä epäonnistuu, voit vaikka laittaa seuraavasti:
/... else if($toiminto == "Poista" ) { if (mysql_query('DELETE FROM Varaus WHERE Tapahtuma_Id=' . $T_Id) === false || mysql_query('DELETE FROM Tapahtuma WHERE T_Id=' . $T_Id) === false) { echo "virhe!"; } else { echo "Tiedot poistettu."; } }
Metabolix kirjoitti:
Grez, { on aaltosulku ja ( on kaarisulku.
Joo, kiitos korjauksesta.
Kannattaa välttää pitkiä if-else-sotkuja, niitä on vaikea lukea. On paljon helpompaa katkaista koko koodin suoritus, kun tulee virhe:
// Ensimmäinen kysely: if (!mysql_query("DELETE FROM Varaus WHERE id = 1")) { // Virhe, suoritus päättyy tähän. trigger_error("Poisto epäonnistui!", E_USER_ERROR); } // Toinen kysely: if (!mysql_query("DELETE FROM Tapahtuma WHERE id = 1")) { // Virhe, suoritus päättyy tähän. trigger_error("Poisto epäonnistui!", E_USER_ERROR); } // Tänne päästään vain, jos virhettä ei tapahtunut. echo "Kaikki ok!";
Grez, { on aaltosulku ja ( on kaarisulku.
hmm.. yritän
Lisäys: Sen verran vielä että kaikissa tapahtumissa ei välttämättä ole varauksia, mutta joo tajusin.
latenleffahylly kirjoitti:
Sen verran vielä että kaikissa tapahtumissa ei välttämättä ole varauksia,
Entä sitten? Siitä huolimatta kysely onnistuu ja poistaa kaikki 0 riviä.
else if($toiminto == "Poista" ) { // Ensimmäinen kysely: if (!mysql_query("DELETE FROM Varaus WHERE Tapahtuma_Id= " . $T_Id . "")) { // Virhe, suoritus päättyy tähän. trigger_error("Poisto epäonnistui!", E_USER_ERROR); } // Toinen kysely: if (!mysql_query("DELETE FROM Tapahtuma WHERE T_Id = " . $T_Id . "")) { // Virhe, suoritus päättyy tähän. trigger_error("Poisto epäonnistui!", E_USER_ERROR); } // Tänne päästään vain, jos virhettä ei tapahtunut. echo "Tiedot poistettu!"; }
Yritän rakentaa vielä tälle koodille testi ympäristön, en valitettavasti uskalla vielä koodia suorittaa Työvuoron varaus ohjelmassa.
latenleffahylly kirjoitti:
Yritän rakentaa vielä tälle koodille testi ympäristön, en valitettavasti uskalla vielä koodia suorittaa Työvuoron varaus ohjelmassa.
Hyvä idea. Yleisestikin ottaen suoraan tuotantoympäristöön koodaaminen on huono idea, vaikka mielestään ei tekisi mitään "vaarallista".
Hei testissä tuli ilmoitus joka alkaa näin:
Warning: mysql_query() [function.mysql-query]:
mistäköhän tässä kyse, epäilen että FORM action= linkki on väärin??
Lisäys: Noniin.. vaihdoin tapaa yhdistää tietokantaan ja sulkea yhteys.. ei virheilmoitusta.. jatketaan testausta
Etkai ottanut virheilmoituksia pois tietokannan avaamisen yhteydestä? :)
En ottanut, nyt homma toimii!
- kiitos taas, eli testasin tuota koodin pätkää jonka annoitte testiympäristössä (toimii)
- Nyt uskalsin laittaa valmiiseen ohjelmaan, tein tapahtuman Testi 1 ja poistin sen, (toimii)
--------------------------------------------------------------------
Vaikka olen täällä jankannut kyllästymiseen saakka että tämä olisi se nyt viimeinen juttu ohjelmaan. Niin enköhän juuri saanut puhelun, jossa asiakas toivoo lisäominaisuuksia.
Toinen asia sitten on - osaanko sellaisia toteuttaa. No tällaista, ainakin tämä Työvuoron varaus ohjelman kanssa oppii koko ajan paremmaksi, mitä tulee näihin alkeisiin..
Katsotaan miten jatkossa, mielestäni se mitä yritän ohjelmaan tehdä on hieman liian korkeatasoista itselleni. Thänks!! Grez, sekä toki dartvaneri ja Metabolix.. (kärsivällisyydestä, selkeistä ohjeista ja siitä että ette heti lyttää maanrakoon) ...kuulemiin!
Voisi olla paikallaan käyttää triggeriä: http://net.tutsplus.com/tutorials/databases/
Trigger on tähän aika paha purkkaratkaisu. Oikeasti pitäisi olla FOREIGN KEY ... ON DELETE CASCADE. Tämä tietenkin vaatii sopivan tietokantamoottorin, esimerkiksi InnoDB:n.
Metabolix kirjoitti:
olisi käytännöllisempää ajaa kaksi erillistä DELETE-kyselyä – yksi kumpaankin tauluun.
Se on minusta purkkakoodin väsäämistä. :) SQL:stä riittää vääntöä paljon paljon parempaan.
Alla on koodi, joka ajaa koko poiston kerralla molempiin tauluihin.
DELETE Tapahtumat, Varaukset FROM Tapahtumat LEFT OUTER JOIN Varaukset ON Tapahtumat.ID = Varaukset.Tapahtuma_ID WHERE Tapahtumat.ID = ?
No edelleen tuo ei onnistu läheskään kaikissa tietokantamoottoreissa, vaikka nyt MySQL:ssä onnistuukin. Itse pidän vähemmän purkkana sellaista joka toimii kaikkialla, varsinkin kun tuosta MySQL:ssä mahdollisesta tavasta ei ole suurempaa hyötyä verrattuna kahteen deleteen.
Tai kuten jo aikaa sitten sanoin niin käyttäen "ryöppyäviä vierasavaimia" eli FOREIGN KEY ... ON DELETE CASCADE, joka mielestäni olisi se paras ratkaisu.
Erittäin mielenkiintoista, en tiennyt että tuollaisiakin on olemassa..
LEFT OUTER JOIN
- tulin jopa ajatelleeksi jälkeenpäin, miksi en saa käyttää vain yhtä SQL-lausetta. Miksi juuri DELETE on niin Vaarallinen. No hassua koodaamisessa on se että on niin monta eri tapaa koodata, tyylisuuntia ja eri koulukuntia.
Itse odotan sitä päivää kun yhdellä kielellä voi tehdä kaiken. Ja kaikki käyttävät vain sitä yhtä kieltä.. Koska se on niin hyvä!
latenleffahylly kirjoitti:
Itse odotan sitä päivää kun yhdellä kielellä voi tehdä kaiken. Ja kaikki käyttävät vain sitä yhtä kieltä.. Koska se on niin hyvä!
Kuulostaa kirvesmieheltä joka odottaa sitä päivää kun yhdellä työkalulla (vasaralla?) voi tehdä kaiken. Ja kaikki käyttävät vain sitä yhtä työkalua, koska se on niin hyvä.
Hei, lisää Varaus - taulukkoon status kenttä oletuksella 1. Poistamisen sijaan päivitätä vain statuksen 0:ksi. Silloin ei tarvitse huolehtia muista kentistä, eli Tapahtumat saavat jäädä kantaan (ja muu vastaava tieto), historiatietoa - varten. Haet sitten toki aina varaukset myös status = 1 ehdolla.
Mielestäni kenttä jonka nimi on "status" ja arvot 0 tai 1 ei ole kovin selkeä. Siis ratkaisu on sinänsä hyvä, mutta sen voisi mielestäni toteuttaa inasen paremminkin.
Itsellä on usein (kun esim. juuri historiatiedon takia ei haluta tai voida poistaa tietoja oikeast) kenttä "deleted" eli "poistettu" jonka arvo on oletuksena false ja voidaan muuttaa trueksi, tai myös takaisin falseksi, jos on "peruuta poisto" tai "palauta" -toiminto.
Grez kirjoitti:
Mielestäni kenttä jonka nimi on "status" ja arvot 0 tai 1 ei ole kovin selkeä. Siis ratkaisu on sinänsä hyvä, mutta sen voisi mielestäni toteuttaa inasen paremminkin.
Itsellä on usein (kun esim. juuri historiatiedon takia ei haluta tai voida poistaa tietoja oikeast) kenttä "deleted" eli "poistettu" jonka arvo on oletuksena false ja voidaan muuttaa trueksi, tai myös takaisin falseksi, jos on "peruuta poisto" tai "palauta" -toiminto.
Niin no, status kenttää voidaan hyödyntää eri asteilla. Kun taas 'deleted' on ainoastaan true tai false.
Esim:
jne..
Juu toki tuossa tapauksessa että siellä on muutkin vaihtoehdot kuin 0 ja 1.
Hetkinen.. tässä tapauksessa on erittäin tärkeää että tietokanta pidetään siistinä. Tapahtumia on noin 150 vuodessa eikä niitä haluta arkistoida. Pikemminkin kun uusi lisätään niin vanha poistetaan.
Myöskään työntekijät eivät tässä tapauksessa hyödy siitä että he näkevät kaikki viime vuoden työvuoronsa. Toki jos järjestelmää haluaisi kehittää voi tilastoida jokaisen työntekijän.
- tapahtumien/ työvuorojen kokonaismäärä
- hmm.. no nyt ei tule muuta mieleen, ehkä kokonais tunti määrä
------------------------------------------------------------------------------
Grez kirjoitti:
Kuulostaa kirvesmieheltä joka odottaa sitä päivää kun yhdellä työkalulla (vasaralla?) voi tehdä kaiken. Ja kaikki käyttävät vain sitä yhtä työkalua, koska se on niin hyvä.
Hyvin sanottu, mutta en tunne web-maailmaa niin hyvin että voisin sanoa onko tällaista monitoimityökalua joka aikanaan sopisi yhteen kaikkien laitteiden kanssa. Eikö olisi helppoa jos olisi jokin tapa jolla omat web-sivut saisi esim. skaalautumaan oikein kaikilla maailman näytöillä noin suunnilleen.
Miksi esim. avoimen lähde koodin järjestelmiä pitää olla yli 2000 - aivan järjetöntä 3 on paljon, liikaa.. 1 hyvä ja kaikki panostaa siihen. Kateus pois ja kehitetään kaikki yhtä, jolloin siitä tulee täydellinen.
latenleffahylly kirjoitti:
Eikö olisi helppoa jos olisi jokin tapa jolla omat web-sivut saisi esim. skaalautumaan oikein kaikilla maailman näytöillä noin suunnilleen.
Onhan meillä semmonen hoo tee äm äl -kuvauskieli, johon saa semmosen see äs äs-tyylitiedoston.
latenleffahylly kirjoitti:
Miksi esim. avoimen lähde koodin järjestelmiä pitää olla yli 2000 - aivan järjetöntä 3 on paljon, liikaa.. 1 hyvä ja kaikki panostaa siihen. Kateus pois ja kehitetään kaikki yhtä, jolloin siitä tulee täydellinen.
Yksi ohjelma, joka tekee kaiken ja osaa huomioida kaikkialla maailmassa tarpeelliset seikat olisi kyllä aivan valtava jööti. Joku saattaa haluta softan joka on kevyt ja täyttää hänen tarpeensa. Jo ihan pelkät tiedonvälityskuvaukset kansainvälisestä kaupankäynnistä (tarjouspyynnöt, tarjoukset, tilaukset, toimitukset, laskutus ja maksut jne.) on jotain 3 megaa xsd:tä
http://docs.oasis-open.org/ubl/os-UBL-2.0/xsd/
Sinänsä olen samaa mieltä, että ihmisten työmäärällä saataisiin paljon parempaa jos puhallettaisiin yhteiseen hiileen. Toisaalta väitetään, että kilpailu edistää kehitystä ja tuottaa parempia tuotteita.
Ja toisekseen ei se välttämättä ole kateudesta kiinni, vaan jotkut haluaa tehdä asiat tietyllä tavalla ja jotkut toisella tavalla.
latenleffahylly kirjoitti:
Eikö olisi helppoa jos olisi jokin tapa jolla omat web-sivut saisi esim. skaalautumaan oikein kaikilla maailman näytöillä noin suunnilleen.
Niin... HTML:hän tosiaan toimii just noin, jos tekijä ei tätä toiminnallisuutta erikseen riko :)
Aihe on jo aika vanha, joten et voi enää vastata siihen.