Fórumok
Helló!
Van két táblám. Egyszerűség kedvéért
stock(id,stock,NOW())
trans(id,product_id,mennyiseg);
Azt szeretném, ha bármilyen SQL művelet van a trans táblán, akkor annak utolsó rekordjának az egyik mezeje alapján a stock táblába menjen egy REPLACE ahol eltárolom a termékhez tartozó aktuális készletet. Valamiért a NEW és az OLD rohadtul nem adódik át.
Mit rontok el?
CREATE TRIGGER trans_update
AFTER UPDATE ON trans
FOR EACH ROW
REPLACE INTO stock SET stock = (SELECT SUM(mennyiseg) as mennyiseg FROM trans WHERE product_id = 'OLD.product_id'), id = 'OLD.product_id';
CREATE TRIGGER trans_insert
AFTER INSERT ON trans
FOR EACH ROW
REPLACE INTO stock SET stock = (SELECT SUM(mennyiseg) as mennyiseg FROM trans WHERE product_id = 'NEW.product_id'), id = 'NEW.product_id';
CREATE TRIGGER trans_delete
AFTER DELETE ON trans
FOR EACH ROW
REPLACE INTO stock SET stock = (SELECT SUM(mennyiseg) as mennyiseg FROM trans WHERE product_id = 'OLD.product_id'), id = 'OLD.product_id';
Hozzászólások
Ne string ként add at:
= 'OLD.product_id'),
helyesen
= OLD.product_id),
Kösz. Pont most lett meg, hogy ezt basztam el.
őőő, lehet, hogy hülyeség, de egyébként delete-re beírhatod, hogy =0, nem, insertre pedig, hogy mennyiseg? Vagy félreértem a dolgot...Bocsi, közben rájöttem...Másik kérdés, Te ismered a programod, de muszáj ezt triggerből? Halál tud lenni, amikor egy logika 15 helyen van.
Még egy kérdés (de csak okoskodás), a trans táblába nem csak insert lehet? + értékkel, vagy - értékkel (bejön a készlet, kimegy)? Az olyan logikus lenne (ennyi infó alapján). :) Bocsi az okoskodásért
Nem osztottam meg mindent.
ok. :)
Pont igy lesz majd egy helyen.
hat en ezt akkor is egy tranzakcioba raknam... transba be az insert, utana a stock allitas, commit. mysql szepen megoldja hogy ez atomi legyen.
a REPLACE INTO, az ugye egy delete+insert. fixme, de azzal szep lukakat lehet csinalni a data fajlban.
meg nem ismerem annyira a triggert. az atomi muveletkent hajtodik vegre? belekerul a transba az uj adat, a trigger vegrehajtasa kozben meg lehal a mysql (oom baltasgyilkos), akkor nemfog szetcsuszni a dolog?
A vegtelen ciklus is vegeter egyszer, csak kelloen eros hardver kell hozza!
Nem tudom, hogy atomi szintű, de úgy írtam meg, hogy ne számítson vagyis minig nyom egy full sum-ot és nem csak hozzáad és elvesz a jelenlegi értékből (tranzakciókezelésnél ez lenne az olcsóbb).
Jelenleg nálam is ez egy kísérlet, hogy lesz-e eltérés. Ha huzamosabb ideig nem, akkor olvasni is fogom a stock táblát.
Ha tranzakcióba rakod, akkor a kliens manipulál és nem az sqlszerver, mert a TRIGGER klienstől független. Azt gondolom, sok minden átköltöztethető kliensről az sql szerverre.
Kódismétlés miatt helyesebb lenne készítenem egy tárolt eljárást amit mind a három trigger meghív eljárás(old|new.mező)-ként.
Postgres, Oracle alatt a trigger beletartozik a tranzakcióba (szerintem minden normális SQL szerver alatt). Ezt nem tudod úgy megírni, hogy ne számítson, hogy atomi szintű. Számít. Egyébként inkonzisztensé válna az adatbázisod, ha bármi miatt nem fut végig a trigger.
Megint csak tippelek, de nem egy html oldal a kliens, és valami PHP script, vagy hasonló a szerver oldali alkalmazásod (ami a html-eket is generálja mellesleg)? Vagy mindegy, hogy mi, de valami hasonló a felállás? (bocsi, lehet, hogy nem így van, csak tippelem) Ha igen, akkor szerintem teljesen normális, ha ott vannak az update-jeid, és nem triggerekben. Ezzel a trigger dologgal azt nyered max, hogy ha kézzel update-elsz, akkor az amellett, hogy lehet (biztos), hogy lassú lesz (mert rekordonként fut majd egy select sum-al), akkor is rendben lesz a másik táblád.
Azt nyerem vele, hogy 2 nagyságrenddel többször kell lekérdezni a készletet, mint írni.
Szerintem félreértjük egymást. Nem arra gondoltam, hogy csinálj gyakrabban bármilyen lekérdezést, hanem azt, hogy ahol az 1 db insert van, vagy 1 db update, vagy 1 db delete van a programodban, ott hívd meg (abban a tranzakcióban) a szummázót, és ne triggerben. Csak a helyét teszed át. De elfogadtam, hogy nem lehet valami oknál fogva. :)
Nem csak számla a tranzakció, hanem még ezernyi belső dokumentum ami az árufeldolgozásával kapcsolatos. Sok ilyennek a teljesítésének a dátuma is változik pl cronból, abban az esetben, ha az adott dolog nem készül el, de foglalás él. Szóval nem csak annyi van, hogy van egy számlázó ami egyetlen egy felületen basztatja az sql-t.
Ok, így már tényleg értem a dolgot.
Materialized View lehet, hogy egyszerűbb az ilyesmire.nvm