

mysql - automatický update a kontrola data
Dobrý den, řeším jeden problém: dělám jako BP jeden web (php) s databází (mysql) a potřebuji vyřešit toto:
Mám tabulku kde kromě jiných atributů je atribut "stav" a atribut "datum"..obojí je vyplněno a já potřebuju aby až nastane to datum, které je ve sloupci "datum" uloženo, databáze sama změnila ve stejném řádku ve sloupci "stav" hodnotu...
názorný příklad:
id | stav | datum |
---------------------------------
1 | připraveno | 2012-03-02 |
2 | probíhá | 2012-02-22 |
3 | připraveno | 2012-03-04 |
---------------------------------
tedy v 0:00 2. března 2012 potřebuju, aby se sama změnila hodnota "stav" u id 1 na probíhá a to stejné u id 3 4. března 2012...
Moc děkuji za pomoc
Databaze sama o sobe nic delat nebude. Je to v podstate soubor.
Ta zmena by mela znamenat, ze se neco spustilo a probiha, ne ze jde o aktualni den. Pokud by melo jit jen o aktualni den,. pak ten sloupec nema zadny smysl a muzes to vyresit primo v SQL dotazu
Pokud trvas na tom, ze by se mel stav meni, napis si PHP skript, ktery bude menit stav na zaklade aktualniho dne a pres CRON ten skript pravidelne po pulnoci spoustej
JJ, zkusím si nastudovat ten Cron....jen jaké jsou podmínky k používání Cronu? Protože to bude běžet na školním serveru, kde si nebudu moc jen tak říct - teď doinstaluju toto a toto...díky
CRON musí být nakonfigurovaný a povolený na serveru (musí jej podporovat hosting).
Ale není bezpodmínečně nutný CRON. Stačí ten skript zavolat kdykoliv při zobrazení stránky.
proc CRON (mimochodem proc mam pocit, ze jsem prave tento okamzik jiz v zivote zazil.. no to je jedno) ? Pokud se ptá na DB tak (viz link dole) MYSQL umí také nějaké scheduler joby, které to umí ohlídat, je to sice náročnější - na druhou stranu lze joby naplánovat přesně podle toho data, ne? Tedy select (min) from tabulka a na tu dobu naplánuju ten job, ten mi to updatne a naplanuje dalsi. Cimz to zustava v DB a dokonce je mozne se vyhnout pravidelnemu neefektivnimu checku.
ako tu uz bolo pisane, priamo v databaze je to dost nestastne, ale nie nemozne.
Pozri si nieco o MySQL events.
proc je to v DB nestatne?
Jinak za mne je uplně nejlepší řešení VIEW s daným CASE, který tam může v runtime doplnit tu hodnotu, podobně jako refreshovane materiealized view (pokud umí MYSQL) ci trigger na selectu (nevim jestli umí mysql)
necital som cely prispevok a myslel som si, ze chce pravidelne checkovat nejake tabulky s presnostou na sekundu, ale ked je to len raz denne, tak samozrejme eventy su uplne v poho.
MySQL od verzie 5 vie triggre (ale len insert, update, delete), materializovane view uz je na mysql asi moc.
Inak k jeho tabulke mam este jednu pripomienku. Stav by rozhodne mal byt nejaky identifikator a mala by existovat zvlast tabulka stavov, lebo takto je to pekne blbe.
O existenci stavu tabulky tabulky nemam zadny nazor - to je teorie, prakticky to udela slozitejsi DB a vykonove to taky nebude lepsi - u nas mame treba tabulku s 500ti sloupci, protoze je to vykonve nejlepsi nez to spojovat s jinejma tabulema, NF at jdou k certu, kdyz to pod nima nebezi. U tehle single tabulky bych to videl nejak podobne - na co to komplikovat dalsi tabulkou. Ovsem kdyz dropne vsechny stavy tak prichazi o informaci stavu - jeden z duvodu proc to drzet v NF, nicmene já bych preferoval udrzovani informace co všechno tam bude mít na urovni CONSTRAINT CHECKu, jestli to tedy umi mysql...
CHECK mysql bohuzial stale nevie. Asi nie je dost ludi ako ja, ktori by tvorcov s takymito vecami otravovali :D.
Neviem ako oracle, ale taky MS SQL ma obmedzenie velkosti riadku na 7000 znakov (bajtov). Pokial je teda v tabulke vela stlpcov typu NVARCHAR(100) = 200 bajtov, tak sa rychlo dostaneme na limit. Riesenim su polia typu ntext, avsak manipulacia s nimi je ako skrabat sa pravou rukou na lavom uchu :(.
//edit: dokonca teraz citam, ze kvoli prenositelnosti tabuliek, mysql check constraint v prikaze zhltne a nevypise chybu, avsak ziadny constraint nevytvori, cize clause je ignorovana :D
Přiznám se, že nevím kolik je omezení Oracle - maximum je 1000 sloupců, ale celková délka řádku nevím. Oracle tam umí dát datové typy (v mssql musi existovat neco podobneho) jako NCLOB, BLOB apod. které se do 4000b mužou ukládat jako "in row" a nebo "out of rows" a pak je tam uložen jen lokátor a je to link do jiné části dat a to klidně muže mít až 128TB a nemusi tam bejt jeden.
Oracle musi mit podstatne vic - nez 7k uz jen kvuli clustrovanejm tabulkam, ma bloky o velikosti 32KB a umi to roztahnout do vice bloku, je to muj milášek.
Napisu si script a zkusim to kolik se toho tam vejde ;) Pro VARCHAR2 je logicke maximum 4000Bx1000sloupcu - uvidime zda to vezme |:D
no som zvedavy, kolko to da.
BLOB a NTEXT a pod. samozrejme idu, ale to je vhodne pre nejake polia, kde ide vela textu. Pokial mame subor 50znakovych poli, tak je to problem, lebo niekedy nad nimi potrebujeme robit rozne selecty a pouzit ich vo where. pri NTEXT to nejde, pretoze realne je NTEXT len nejaky odkaz na text.
btw, ked uz ta tu tak mam, mas nejake skusenosti s Caché databazami?
Caché databazami // tim myslíš co? Oralce má na to několik pohledu od TIMES-TEN, což jsou podle mne baliky, kdy je možné trošku zachízet z pamětí a tedy použít CACHE pro výsledky nějakých selectu a nějaké pohledy kdy se invalidují výsledky funkci, nahrvání debendencies apod. Nicméně reálně u zaměstanavatele moc ne, spíše teoreticky.
cache
přímo tohle vubec, diky za link - pouze to co je pod Oracle, podle tech par vet si myslim ze prave to times-ten je oracli verze teto db. Mimochodem jede na tom čikákská burza
Jsem u tabulky číslo 420 tedy 420 sloupcu krát 4000 znaků a zatim to jede
Tak jsem si vyjel jednu z tech tabulek 690:
Délka: 2762079 B
Řádků: 1
Bloky 748 bloku (hustý jeden řádek rozmrdnutej přes 740 bloku)
Je to 690*4000 což je nějakých 2760000B v jednom řádku.
A ted se jdu projit se sluchátkama nočním Kladnem s touto muzikou : watch a az se vratim tak se mrknu na tu nejvetsi, kterou to udela - je to dost pomale, nechtel jsem se srat s LOBama, tak to kazdej sloupec updatuje, pac jsem nechtel presahnout tech 32KB kodu do varchar2.
je to tu : XHAF_1000 - založilo to tablku s 1000 sloupcema VARCHAR2 - plnejma 4000 znaku.
Počet řadku: 1
Počet bloku: 1000
Počet empty bloku : 24
Prumerna dálka řádku : 4003009B
oracle neumi taky trigger na selectu, ale dá se to pomoci autonmnich transakci, locku a auditovacích funkcí, policy apod zařídit. Nic hezkého, co si budeme vykládat :D, nicméně když Oracle BI v praci co mame neumi zavolat PLSQL funkci, delame tam ruzne kulisarny aby to slo :D
Ou, tady se to rozjelo...
Takže trochu upřesním - padl tu návrh abych to kontroloval při vstupu na stránky....toto tak mám zatím ale jen nouzově- je to prasečinka...i když 100% funkční...
Jde totiž o to, že na stránce mám el.hlasování, kde po přihlášení můžou uživatelé hlasovat...
Požadavky byly:
-možnost nastavit od kdy do kdy je možné hlasovat
-kdykoliv přerušit předčasně hlasování a vyhlásit výsledky
-každy z reg. uživatelů max. 1x hlasovat
-není dán pevný počet možností - někdy 2, někdy i 10...(min 2)
-možnost přiložit k anketě přílohu (soubor)
-zobrazovat datum od kdy do kdy je možné hlasovat
udělal jsem to v dbs takto:
-2 tabulky-(ankety, ankety-moznosti-vysledky):
-v tabulce ankety jsou tyto atributy:
-id,nadpis,text,pocet_moznosti,odhlasoval,stav,zac atek(typ date),konec(typ date)
-v tabulce ankety-moznosti-vysledky jsou tyto atributy:
-id,id_ankety(cizí klíč - tab. ankety),id_moznosti,text_moznosti,pocet_hlasu
ještě nedávno nebyl chtěn požadavek zrušit anketu předčasně, takže tam nebyl atribut "stav" a vše se řídilo dle data "začátek" a "konec"...když aktuální datum splňovalo rozmezí, anketa se zobrazila a šlo hasovat, když už bylo po datu "konec", tak se ukázalo vyhodnocení...
jenže teď přibyl požadavek na předčasné ukončení, takže jsem musel přidat atribut "stav" (hodnoty čeká, probíhá, ukončeno)... a tady potřebuji aby když datum začátek nastalo tak se změní stav na probíhá, když nastane datum konec, stav se změní na ukončeno...
Sorry za případné překlepy - mám bezdrát.klávesnici a docházej baterky tak to vynechává...
Ja jsem to přečetl a me view je ta sama odpoved jako od JaFIho ta prvni - jde to udelat jen upravou selectu a mozna jeste lepe pridat jen atribut FORCE_CLOSET a pak to vybirat jen vhodne ulozenym selectem. Dalsi moznost je tabulka stavu a vhodny JOIN, ktery to zase udela v selectu, aby jsi nemusel ukládat stavy jinde- ta logika je jasná - bud je to v tom intervalu a neni flag y nebo je flag n a je to taky jasné.
Tak jsem zkoušel nastavit ty eventy, ale bohužel to nějak nefunguje-zkoušel jsem různé příklady z netu a event se sice vytvoří, ale už nespustí...
zkusil jsem toto (en tak na zkoušku, bez data apod...):
zkusil jsem i toto:
a taky nic..event si sedí v databázi a nic nedělá...
Nevíte kde dělám chybu...když totiž rozchodím ty eventy, tak budu mít vyřešený můj problém dokonale...díky za rady
commit?
myslíš jako za to přidat příkaz commit? zkusím....ještě jeden problém... pokusy jsem dělal na pc a tam i když nešly ty eventy, tak šly alespoň zobrazit...teď budu do konce týdne na notebooku a zaboha nemůžu přijít/vzpomenout na ten příkaz pro zobrazení uložených eventů...show event to není...
neviem ti teraz narychlo povedat v com je problem, musim si pozriet dokumentaciu. Ja som to kedysi skusal a mne to urcite islo.
Btw nepouzivaj != ale <>. != nie je standardny zapis. Sice funguje, ale je to nezmysel.
no to s tou podmínkou slyším poprvé...na škole jsme měli předminulý semestr databáze a učil nás týpek z akademie věd a na férovku nás tyto druhy zápisu učil...
a jak se pak mají porovnávat řetězce?
Zítra zkusím vycucat nějaké rady od kolegů ve škole,ale začínám z toho být na prášky...A aby toho nebylo málo, tak jsem dnes hodil ty nové webovky na školní server a zjistil jsem že mi nefunguje upload souborů ani ukládání vygenerovaných souborů (fpdfp)-asi je to na tom servru zakázané nebo co... když jsem zkoušel upload, tak jsem si vypsal chybu (error_reporting(0);) a vypsalo to chybu číslo 22527, tak nevím...
ako som pisal, namiesto != by som radsej pouzil dva zobaky <> (nerovna sa). Funguje aj ten tvoj zapis, ale podla standardu je to nespravne. Ten kto vas ucil bol mozno odchovany na C++ :).
to je nesmysl, != je v javě, v c++ apod. <> je v jinejch jazycich. Podle mne je to uplne jedno, zapisu != stejne jako <> musi rozumet kazdej. Chapal bych kdyby jsi byl proti zapisu ^= /nevim jestli mysql podporuje, oracle ano/ ten moc lidi nezna.
to je vsetko ok, mysql a aj ostatne db systemy podporuju oba zapisy (vynimkou je DB2). Tam ide skor o to, ze <> je ANSI standard zatial co != nie :).
<> Hlavně vypadá líp, dost se to podobá učetelkám zeměpisu
Zabudni na eventy, triggre a podobné prasačiny. Na toto ti stačí jednoduchý select, ako tu už niekoľko razy bolo spomenuté.
dobře, jednoduchý select...ok...jsem zvědavej jak selectem budu updatovat tabulku...
protože první co mi u obhajoby vytknou je: "Proč při každém přístupu na tuto stránku kontrolujete stav položky v databázi (a případně měníte stav)? Vždyť to zbytečně moc zatěžujete server...nešlo použít něco jiného?"
EDIT:PRávě jsem zjistil, že eventy podporuje databáze myslq od verze 5.1.xxx, ale na mém notebooku i na školní serveru je verze 5.0.9xx, takže nic...takže se mám na co vymluvit a udělám si na to v php funkci...
Prečo by si chcel selectom updatovať tabuľku? Prečo by si chcel vôbec čímkoľvek updatovať tabuľku? Veď v tomto prípade potrebuješ len čítať z tabuľky. A na to je select (prípadne si nad tým môže spraviť view, ale imho v tomto prípade je to zbytočnosť).
Ak by si to obhajoval u mňa, tak prvé čo by som sa spýtal by bolo, prečo si sa rozhodol použiť trigger, event alebo cron. A nech by si odpovedal čokoľvek, už by som si myslel svoje.
Načo tam vôbec potrebuješ stĺpec stav? Veď stav objektu je popísaný tými dátumami platnosti od-do a indikátorom, či bolo hlasovanie predčasne ukončené. Takže v tom selecte nepotrebuješ ani case. Navyše, o reprezentácii stavu textovým reťazcom by sa tiež dalo diskutovať.
Ano, právě že to porovnávání dle data mám teď tak udělané - pokud datum počátku hlasování je/bylo a zároveň datum ukončení bude/je, tak je možné hlasovat...
A ten stav je právě to předčasné ukončení...(předělám na netextový)...sice jsem mohl předčasně ukončit hlasování tak, že bych updatoval konečné datum, jenže já potřebuji aby i po ukončení bylo vidět nastavené původní datum od-do...
A právě jsem si myslel, že když by databáze sama vždy v noci zkontrolovala to rozmezí data a příp.změnila podle toho stav, tak při hlasování by stačilo pro zobrazení jen obyč. select where stav neukončená...a odpadlo by nějaké vyhodnocování apod...
ale ok-nechám to tak jak mám no...když je to lepší...
Los myslí že si selcetneš ty řádky, vytáhneš si to datum a pomocí PHP si to porovnáš a vypíšeš.. má pravdu že je zbytečný sloupec stav