Odp: [POMOC] Przygotowanie TRIGGERA do projektu. Pilne!
Dobrze rozumiem, że po każdym INSERT do tabeli sprzedaż powinien być update do tabeli sprzedawca, który automatycznie aktualizuje wielkość sprzedaży? O to chodzi?
Odp: [POMOC] Przygotowanie TRIGGERA do projektu. Pilne!
Dokladnie, dla kazdego sprzedawcy automatycznie powinien dopisac obrot.
Odp: [POMOC] Przygotowanie TRIGGERA do projektu. Pilne!
DROP TABLE IF EXISTS sprzedaz;
DROP TYPE IF EXISTS sposob_zaplaty;
DROP TABLE IF EXISTS sprzedawca;
DROP FUNCTION IF EXISTS aktualizuj_obrot_sprzedawcy();
CREATE TABLE sprzedawca
(
nr_sprzedawcy smallint PRIMARY KEY,
imie text,
nazwisko text NOT NULL,
obrot_sprzedawcy numeric(11, 2) DEFAULT 0 NOT NULL
);
CREATE TYPE sposob_zaplaty AS ENUM ('Gotowka', 'Karta', 'Przelew', 'Raty');
CREATE TABLE sprzedaz
(
pesel_klienta char(11), -- REFERENCES klient(pesel)
nr_podwozia varchar(17), -- REFERENCES samochod(nr_podwozia)
nr_sprzedawcy smallint REFERENCES sprzedawca(nr_sprzedawcy),
sposob_zaplaty sposob_zaplaty,
data_sprzedazy date,
cena_finalna numeric(9,2) NOT NULL
);
Ostatnio edytowany przez gszpetkowski (2011-06-02 05:38:45)
Odp: [POMOC] Przygotowanie TRIGGERA do projektu. Pilne!
Bardzo dziekuje, o to wlasnie mi chodzilo. Wszystko dziala poprawnie. A jesli bym chcial przerobic go tak,aby nie byl on typu " and forget" co trzeba zmienic /dodac?
Pozdr.Patryk
Odp: [POMOC] Przygotowanie TRIGGERA do projektu. Pilne!
Gdyby to było konieczne, to wystarczy dodać kolejne wyzwalacze na UPDATE i DELETE analogicznie tak jak przy INSERT. Przykładowo jeżeli UPDATE miałby spowodować zmianę cena_finalna dla jakiejś sprzedaży, to w funkcji obsługi trigger'a wystarczy obliczyć różnicę między starą i nową cena_filnalna i zaaktulizować obrot_sprzedawcy.
Odp: [POMOC] Przygotowanie TRIGGERA do projektu. Pilne!
Cos takiego dla UPDATE?
"
CREATE FUNCTION aktualizuj_obrot_sprzedawcy_update() RETURNS TRIGGER AS $$
BEGIN
UPDATE sprzedawca
SET obrot_sprzedawcy = obrot_sprzedawcy + (cena_finalna - NEW.cena_finalna)
WHERE nr_sprzedawcy = NEW.nr_sprzedawcy;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER sprzedaz_insert
AFTER UPDATE ON sprzedaz
FOR EACH ROW
EXECUTE PROCEDURE aktualizuj_obrot_sprzedawcy_update();
Ostatnio edytowany przez sali128 (2011-06-02 16:28:23)
Odp: [POMOC] Przygotowanie TRIGGERA do projektu. Pilne!
CREATE FUNCTION aktualizuj_obrot_sprzedawcy_update() RETURNS TRIGGER AS $$
BEGIN
UPDATE sprzedawca
SET obrot_sprzedawcy = obrot_sprzedawcy + (NEW.cena_finalna - OLD.cena_finalna )
WHERE nr_sprzedawcy = NEW.nr_sprzedawcy;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER sprzedaz_update
AFTER UPDATE ON sprzedaz
FOR EACH ROW
EXECUTE PROCEDURE aktualizuj_obrot_sprzedawcy_update();
Odp: [POMOC] Przygotowanie TRIGGERA do projektu. Pilne!
Dziala swietnie. Dziekuje... A czy jest mozliwosc zapisania jednego Triggera dla wszystkich funkcji UPDATE,INSTERT DELETE zamiast 3 osobnych? Chodzi mi o swoiste laczenie ich.
Odp: [POMOC] Przygotowanie TRIGGERA do projektu. Pilne!
CREATE TRIGGER sprzedaz_update
AFTER UPDATE OR INSERT OR DELETE ON sprzedaż
Odp: [POMOC] Przygotowanie TRIGGERA do projektu. Pilne!
Witam,
Poczytalem to co napisaliscie i przeanalizowalem wczesniejsze Triggery @gszpetkowski i doszedlem do czegos takiego-jednak nie dziala.
CREATE FUNCTION obrot_sprzedawcy() RETURNS TRIGGER AS $obrot_sprzedawcy$
BEGIN
IF (TG_OP = 'DELETE') THEN
???
ELSIF (TG_OP = 'UPDATE') THEN
SET obrot_sprzedawcy = obrot_sprzedawcy + (NEW.cena_finalna - OLD.cena_finalna )
WHERE nr_sprzedawcy = NEW.nr_sprzedawcy;
RETURN NEW;
ELSIF (TG_OP = 'INSERT') THEN
SET obrot_sprzedawcy = obrot_sprzedawcy + NEW.cena_finalna
WHERE nr_sprzedawcy = NEW.nr_sprzedawcy;
RETURN NEW;
END IF;
END;
$obrot_sprzedawcy$ LANGUAGE plpgsql;
CREATE TRIGGER obrot_sprzedawcy
AFTER INSERT OR UPDATE OR DELETE ON sprzedawca
FOR EACH ROW EXECUTE PROCEDURE obrot_sprzedawcy() ;
1)Nie wiem co wpisac w DELETE?
2)Prosze przeanalizowac ,bo nie wiem czy to na pewno jest dobrze.
Dziekuje i Pozdrawiam,
Patryk
Ostatnio edytowany przez sali128 (2011-06-06 14:07:54)
Odp: [POMOC] Przygotowanie TRIGGERA do projektu. Pilne!
Odp: [POMOC] Przygotowanie TRIGGERA do projektu. Pilne!
Skladnia wydaje mi sie byc ok, a ma ktos pomysl na warunek DELETE?
Odp: [POMOC] Przygotowanie TRIGGERA do projektu. Pilne!
"A może (chociaż) Harry Potter?"
-- DROP FUNCTION IF EXISTS obrot_sprzedawcy();
CREATE FUNCTION obrot_sprzedawcy() RETURNS TRIGGER AS $$
DECLARE
delta numeric(9,2);
BEGIN
IF (TG_OP = 'INSERT') THEN
UPDATE sprzedawca
SET obrot_sprzedawcy = obrot_sprzedawcy + NEW.cena_finalna
WHERE nr_sprzedawcy = NEW.nr_sprzedawcy;
RAISE NOTICE 'Nowa sprzedaż, zwiększony obrót sprzedawcy % o % zł.',
NEW.nr_sprzedawcy, NEW.cena_finalna;
RETURN NEW;
ELSIF (TG_OP = 'UPDATE') THEN
delta := NEW.cena_finalna - OLD.cena_finalna;
UPDATE sprzedawca
SET obrot_sprzedawcy = obrot_sprzedawcy + delta
WHERE nr_sprzedawcy = NEW.nr_sprzedawcy;
RAISE WARNING 'Korekta sprzedaży, obrót sprzedawcy % różnica % zł.',
NEW.nr_sprzedawcy, delta;
RETURN NEW;
ELSE
UPDATE sprzedawca
SET obrot_sprzedawcy = obrot_sprzedawcy - OLD.cena_finalna
WHERE nr_sprzedawcy = OLD.nr_sprzedawcy;
RAISE WARNING 'Anulowanie sprzedaży, obrót sprzedawcy % zmniejszony o % zł,',
OLD.nr_sprzedawcy, OLD.cena_finalna;
RETURN NEW;
END IF;
END;
$$ LANGUAGE plpgsql;
Samo CREATE TRIGGER już podał rski.
Przykład:
grzegorz=> \t
Showing only tuples.
grzegorz=> INSERT INTO sprzedaz VALUES ('78090726444', 'RE93032MFSDI203VE', 631, 'Karta', '2011-06-06', 355.50);
NOTICE: Nowa sprzedaż, zwiększony obrót sprzedawcy 631 o 355.50 zł.
INSERT 0 1
grzegorz=> SELECT obrot_sprzedawcy FROM sprzedawca WHERE nr_sprzedawcy = 631;
20255.50
grzegorz=> UPDATE sprzedaz SET cena_finalna = 200 WHERE pesel_klienta ~~ '78090726444' AND nr_podwozia ~~ 'RE93032MFSDI203VE';
WARNING: Korekta sprzedaży, obrót sprzedawcy 631 różnica -155.50 zł.
UPDATE 1
grzegorz=> SELECT obrot_sprzedawcy FROM sprzedawca WHERE nr_sprzedawcy = 631;
20100.00
grzegorz=> DELETE FROM sprzedaz WHERE pesel_klienta ~~ '78090726444' AND nr_podwozia ~~ 'RE93032MFSDI203VE';
WARNING: Anulowanie sprzedaży, obrót sprzedawcy 631 zmniejszony o 200.00 zł,
DELETE 1
grzegorz=> SELECT obrot_sprzedawcy FROM sprzedawca WHERE nr_sprzedawcy = 631;
19900.00
Właśnie dlatego narzekałem o ten klucz podstawowy w sprzedaz, żeby nie robić potem konstrukcji typu powyższego.
Te dodatkowe informacje (poziomy NOTICE i WARNING) służą dla czytelności, ale mogą być także umieszczane w logu pracy serwera (jeśli jest to wymagane, np. tylko poziom WARNING).
Ostatnio edytowany przez gszpetkowski (2011-06-06 18:09:47)
Odp: [POMOC] Przygotowanie TRIGGERA do projektu. Pilne!
Witam,
Dziekuje za odpowiedz. Robie wszystko tak jak nalezy,mam kod:
CREATE FUNCTION obrot_sprzedawcy() RETURNS TRIGGER AS $$
DECLARE
delta numeric(9,2);
BEGIN
IF (TG_OP = 'INSERT') THEN
UPDATE sprzedawca
SET obrot_sprzedawcy = obrot_sprzedawcy + NEW.cena_finalna
WHERE nr_sprzedawcy = NEW.nr_sprzedawcy;
RAISE NOTICE 'Nowa sprzedaż, zwiększony obrót sprzedawcy % o % zł.',
NEW.nr_sprzedawcy, NEW.cena_finalna;
RETURN NEW;
ELSIF (TG_OP = 'UPDATE') THEN
delta := NEW.cena_finalna - OLD.cena_finalna;
UPDATE sprzedawca
SET obrot_sprzedawcy = obrot_sprzedawcy + delta
WHERE nr_sprzedawcy = NEW.nr_sprzedawcy;
RAISE WARNING 'Korekta sprzedaży, obrót sprzedawcy % różnica % zł.',
NEW.nr_sprzedawcy, delta;
RETURN NEW;
ELSE
UPDATE sprzedawca
SET obrot_sprzedawcy = obrot_sprzedawcy - OLD.cena_finalna
WHERE nr_sprzedawcy = OLD.nr_sprzedawcy;
RAISE WARNING 'Anulowanie sprzedaży, obrót sprzedawcy % zmniejszony o % zł,',
OLD.nr_sprzedawcy, OLD.cena_finalna;
RETURN NEW;
END IF;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER sprzedaz_update
AFTER UPDATE ON sprzedaz
FOR EACH ROW
EXECUTE PROCEDURE obrot_sprzedawcy();
----WYKORZYSTANIE----
--UPDATE:
s8201=> UPDATE sprzedaz SET cena_finalna=10000 WHERE nr_podwozia LIKE 'FR873432846523H98';
OSTRZEŻENIE: Korekta sprzedaży, obrót sprzedawcy 631 różnica 100.00 zł.
UPDATE 1
--INSERT:
INSERT INTO klient(pesel, nazwisko, imie, kod_pocztowy, miasto, ulica_dom)
values('78090726444','Banicki','Marian','80-312','Szymbark','Dolna 12');
INSERT INTO sprzedaz VALUES ('78090726444', 'GD0920490329FD093', 631, 'Karta', '2009-04-20', 48440);
--DELETE:
DELETE FROM sprzedaz WHERE pesel_klienta ~~ '78090726444' AND nr_podwozia ~~ 'GD0920490329FD093';
Nie dziala w tej funkcji opcja INSERT i DELETE . UPDATE jest ok-wyswietla komunikat.
W insercie i delete nie wyswietla komunikatow i nie zlicza tych nowych wartosci. W insercie najpierw wpisuje nowego klienta
i nastepnie robie insert do tabeli sprzedaz jednak nic sie nie dzieje,tak samo przy delete. Cos robie zle? Moze zle trigger zapisalem?
Pozdr.
Odp: [POMOC] Przygotowanie TRIGGERA do projektu. Pilne!
CREATE TRIGGER sprzedaz_update
AFTER UPDATE ON sprzedaz
FOR EACH ROW
EXECUTE PROCEDURE obrot_sprzedawcy();
Odp: [POMOC] Przygotowanie TRIGGERA do projektu. Pilne!
Faktycznie,przeoczylem....
Wszystko smiga, dziekuje bardzo za cale Wasze zainteresowanie.
Dziekuje i Pozdrawiam.
Patryk