Michał P.

Michał P. Kierownik, AEGON
Towarzystwo
Ubezpieczeń na Życie
S.A.

Temat: Wyzwalacz - jak go napisać ?

Witam,
Proszę o pomoc w napisaniu wyzwalacza.

Mam dwie tabele:
bibliografia (osoba_id, tytuł pozycji),
osoby (osoba_id, nazwisko, imie, liczba_publikacji).

Wyzwalacz powinien po dopisaniu nowej publikacji zaktualizować liczbę publikacji danej osoby w tabeli osoby.
Zakładamy, że wpis w tabeli bibliografia dotyczy tylko 1 publikacji.

Próbowałem coś kombinować ale nie mam pojęcia jak to "ugryźć" :-(
Znalazłem jakieś wzory w necie ale tylko takie gdzie wyzwalacz ma pilnować jakiegoś warunku itp.
Kompletnie nie wiem jak zliczyć liczbę publikacji danej osoby w tabeli bibliografia i jak sprawdzić z danymi w tabeli osoby.
Próbowałem coś takiego:

CREATE TRIGGER akt_LiczbaPublikacji
ON bibliografia
FOR INSERT, UPDATE
AS
BEGIN
DECLARE @liczba_publikacji INT
SELECT @liczba_publikacji = count(osoba_id) FROM inserted;
IF @liczba_publikacji <
-- jak to sprawdzić z tabelą osoby?


Z góry serdecznie dziękuję za pomoc
Pozdrawiam

konto usunięte

Temat: Wyzwalacz - jak go napisać ?

Po pierwsze. Fajnie byłoby napisać jakiej bazy danych dotyczy problem. Dziś nawet pod Windows jest wybór. ;)

Co do pytania. Najprościej w wyzwalaczu robić za każdym razem pełnego counta. Czyli na insert,update i delete wyznaczasz nową ilość publikacji. Aktualizacja pola i po temacie. Jak zrobisz wyzwalacz reagujący na typ operacji - to przy delete możesz zmniejszyć o 1, przy insert, zwiększyć, a dla update trzeba sprawdzić, bo może być zmiana autora i wtedy zmieniają się 2 rekordy, albo żaden jeżeli zmiana nie dotyczy autora...
Założę się, że w googlach znajdę przykłady obu rozwiązań w 10 minut, dla MS SQL Servera.
Dawid Rokita

Dawid Rokita CTO picAds.pl

Temat: Wyzwalacz - jak go napisać ?

Tu masz przykład w pgSQL :-)

CREATE OR REPLACE FUNCTION sum_cash_for_user()
RETURNS trigger AS
$BODY$DECLARE
cash_count numeric := 0;
curs_sum_cash CURSOR (user_id integer) IS SELECT SUM(cash) FROM users_cash_operations WHERE users_id=user_id;
BEGIN
OPEN curs_sum_cash(OLD.users_id);
FETCH curs_sum_cash INTO cash_count;
CLOSE curs_sum_cash;

IF cash_count IS NULL THEN cash_count=0; END IF;
UPDATE users SET cash=cash_count WHERE "id"=OLD.users_id;
NEW.processed = true;

RETURN NEW;
END;$BODY$
LANGUAGE 'plpgsql' VOLATILE
COST 100;
ALTER FUNCTION sum_cash_for_user() OWNER TO postgres;Dawid Rokita edytował(a) ten post dnia 01.09.10 o godzinie 12:29
Michał P.

Michał P. Kierownik, AEGON
Towarzystwo
Ubezpieczeń na Życie
S.A.

Temat: Wyzwalacz - jak go napisać ?

Po pierwsze. Fajnie byłoby napisać jakiej bazy danych dotyczy problem. Dziś nawet pod Windows jest wybór. ;)

Ms Sql Server

i naprawdę szukałem i nie mogę znaleźć :-(

konto usunięte

Temat: Wyzwalacz - jak go napisać ?

Michał Z.:
Po pierwsze. Fajnie byłoby napisać jakiej bazy danych dotyczy problem. Dziś nawet pod Windows jest wybór. ;)

ale to widać że w T-SQL-u jest pisane
Bartosz Ślepowronski

Bartosz Ślepowronski Problem? Jaki
problem?

Temat: Wyzwalacz - jak go napisać ?

CREATE TRIGGER akt_LiczbaPublikacji
ON bibliografia
AFTER INSERT
AS
BEGIN
DECLARE @liczba_publikacji INT
DECLARE @autor NVARCHAR(100) --albo INT jesli to id, cokolwiek jest w Twojej bazie

SET @autor = (SELECT autor FROM inserted)

SELECT @liczba_publikacji = count(osoba_id) FROM bibliografia
WHERE autor = @autor

UPDATE tamgdziemaszzrobicupdate
SET liczbapublikacji = @liczba_publikacji
WHERE autor = @autor
END


Napisane na pałe, więc nie bierze pod uwagę rekursji, wstawiania wielu wierszy itd. Ale na początek powinno wystarczyć :)Bartosz Ślepowronski edytował(a) ten post dnia 01.09.10 o godzinie 12:50
Michał P.

Michał P. Kierownik, AEGON
Towarzystwo
Ubezpieczeń na Życie
S.A.

Temat: Wyzwalacz - jak go napisać ?

Dziękuję bardzo - działa :-)

Chciałbym jeszcze prosić o pomoce przy poniższym.

Za pomocą wyzwalacza zapewnij niemożność dwukrotnego zapisania publikacji
o tej samej nazwie, wykonanej przez tego samego autora.

Próbuję na początku z samym tytuł ale i tak mi nie wychodzi :-(

ALTER TRIGGER duplikat_publikacji
ON bibliografia
FOR INSERT
AS
DECLARE @tytul VARCHAR(30)
--DECLARE @osoba_id_id INT

SELECT @tytul = tytul from inserted;
IF @tytul = (SELECT tytul FROM bibliografia)
BEGIN
ROLLBACK
RAISERROR ('Taka publikacja już istnieje w bazie',1,2)
END;
Bartosz Ślepowronski

Bartosz Ślepowronski Problem? Jaki
problem?

Temat: Wyzwalacz - jak go napisać ?

Michał Paluch:
ALTER TRIGGER duplikat_publikacji
ON bibliografia
FOR INSERT
AS
DECLARE @tytul VARCHAR(30)
--DECLARE @osoba_id_id INT

SELECT @tytul = tytul from inserted;
IF @tytul = (SELECT tytul FROM bibliografia)

Spróbuj raczej
IF exists(SELECT 1 FROM bibliografia WHERE tytul = @tytul)
BEGIN
ROLLBACK
RAISERROR ('Taka publikacja już istnieje w bazie',1,2)
END;

Rolback w triggerze chyba zawsze wyrzuca dodatkowy błąd 3609 (niech ktoś mnie poprawi jeśli się mylę i da się to jakoś wyłączyć)

Alternatywnie możesz użyć triggera INSTEAD OF

ALTER TRIGGER duplikat_publikacji
ON bibliografia
INSTEAD of INSERT
AS
BEGIN

DECLARE @tytul NVARCHAR(10)
SELECT @tytul = tytul from inserted;

IF exists(SELECT 1 FROM bibliografia WHERE tytul = @tytul)
BEGIN
RAISERROR ('Taka publikacja już istnieje w bazie',1,2)
RETURN
END
ELSE
BEGIN
INSERT into bibliografia
SELECT * FROM inserted
END

END


Coś w ten deseń.

[EDIT] w sumie to wystarczy print zamiast raiserror, chyba ze gdzies przechwytujesz nr bledu.Bartosz Ślepowronski edytował(a) ten post dnia 01.09.10 o godzinie 15:14
Michał P.

Michał P. Kierownik, AEGON
Towarzystwo
Ubezpieczeń na Życie
S.A.

Temat: Wyzwalacz - jak go napisać ?

działa

A jak do tego dodać jeszcze autora czyli osoba_id?

Za pomocą wyzwalacza zapewnij niemożność dwukrotnego zapisania publikacji
o tej samej nazwie, wykonanej przez tego samego autora.
Bartosz Ślepowronski

Bartosz Ślepowronski Problem? Jaki
problem?

Temat: Wyzwalacz - jak go napisać ?

No bez przesady - dokładnie tak samo! :)

konto usunięte

Temat: Wyzwalacz - jak go napisać ?

Michał Paluch:
działa

A jak do tego dodać jeszcze autora czyli osoba_id?

Za pomocą wyzwalacza zapewnij niemożność dwukrotnego zapisania publikacji
o tej samej nazwie, wykonanej przez tego samego autora.

IF exists (sprawdzasz)
rollback

wydajniejszy by chyba był constrain albo primary key
Michał P.

Michał P. Kierownik, AEGON
Towarzystwo
Ubezpieczeń na Życie
S.A.

Temat: Wyzwalacz - jak go napisać ?

Witam,
Pewnie się "nie popiszę" ale nie wiem jak zrobić aby sprawdzony był warunek publikacji i autora.

Jak wstawiam tak samo tylko dla osoba_id to zawsze mam komunikat, że taki tytuł istnieje i wykonywany jest PRINT ('Taka publikacja już istnieje w bazie')
A przecież może mieć miejsce sytuacja, że w bazie jest tytuł autora o id 1 a ja chcę wprowadzić ten sam tytuł ale autora o id 3.

Z góry dziękuje za pomoc
Mariusz Płaskowicki

Mariusz Płaskowicki Software Developer,
Oxford Computer
Consultants Ltd

Temat: Wyzwalacz - jak go napisać ?

IF exists(SELECT 1 FROM bibliografia WHERE tytul = @tytul AND authorID = @AuthorID) ?

Może przekaż to komuś kto będzie miał jakieś pojęcie o tym co pisze?
Michał P.

Michał P. Kierownik, AEGON
Towarzystwo
Ubezpieczeń na Życie
S.A.

Temat: Wyzwalacz - jak go napisać ?

Sęk w tym, że mi chodzi o naukę a nie mam nikogo "pod ręką" kogo mógłbym poprosić o pomoc.

Serdecznie dziękuję za pomoc
Pozdrawiam

konto usunięte

Temat: Wyzwalacz - jak go napisać ?

Michał Paluch:
Sęk w tym, że mi chodzi o naukę a nie mam nikogo "pod ręką" kogo mógłbym poprosić o pomoc.

Serdecznie dziękuję za pomoc
Pozdrawiam
wciskasz F1 i masz odpowiedz na wiekszosc pytan
Piotr Tybulewicz

Piotr Tybulewicz
Projektant/programis
ta business
intelligence/SQL

Temat: Wyzwalacz - jak go napisać ?

Bartosz Ślepowronski:


SET @autor = (SELECT autor FROM inserted)

Bartosz Ślepowronski:

Michał Paluch:

SELECT @tytul = tytul from inserted;

Michał Paluch:

W obu przypadkach założyliście, że w inserted będzie dokładnie jeden wiersz, co jest proszeniem się o problemy. Pierwszy kod jest o tyle lepszy od drugiego, że w sytuacji z wieloma wierszami się po prostu wywali, podczas gdy drugi oleje wszystkie wiersze oprócz ostatniego.
Bartosz Ślepowronski

Bartosz Ślepowronski Problem? Jaki
problem?

Temat: Wyzwalacz - jak go napisać ?

Piotr Tybulewicz:
W obu przypadkach założyliście, że w inserted będzie dokładnie jeden wiersz, co jest proszeniem się o problemy.

Khm. Czytaj posty ktore komentujesz, to bylo wyraznie zaznaczone:
Bartosz Ślepowronski:
Napisane na pałe, więc nie bierze pod uwagę rekursji, wstawiania wielu wierszy itd. Ale na początek powinno wystarczyć

Jak ktos nie zna podstaw SQL to pokazuje sie rozwiazania w najprostszy mozliwy sposob. Jak bedzie potrzebowal wiecej to sie dopyta.Bartosz Ślepowronski edytował(a) ten post dnia 11.09.10 o godzinie 22:59



Wyślij zaproszenie do