kamillo1290
28.04.2010, 12:27:28
W MSQL Server 2008 nie działa mi:
--Napisz wyzwalacz nie pozwalający na obniżanie pensji pracownikom – w przypadku takiej próby ma zwracać odpowiedni komunikat.
CREATE TRIGGER notupdate BEFORE UPDATE OF pensja ON pracownik2
REFERENCING NEW AS after_update OLD AS before_update
FOR EACH ROW
BEGIN
IF after_update.pensja = before_update.pensja THEN
RAISERROR 30002 'You cannot decrease a salary';
END IF;
END
wzorowałem się na skrypcie pokazującym jak napisać podobny wyzwalacz, błędy są takie:
Msg 102, Level 15, State 1, Procedure notupdate, Line 1
Incorrect syntax near 'BEFORE'.
Msg 156, Level 15, State 1, Procedure notupdate, Line 5
Incorrect syntax near the keyword 'THEN'.
Msg 102, Level 15, State 1, Procedure notupdate, Line 7
Incorrect syntax near ';'.
Jeszcze mam, jak dla mnie, trudniejsze zadanie:
--Utwórz wyzwalacz Archiwizuj, który po usunięciu pracownika z tabeli pracownik automatycznie umieszcza jego dane w tabeli pracownik_archiwum, wraz z datą usunięcia i nazwą użytkownika dokonującego operacji usuwania (select user_name() zwraca nazwę aktualnego użytkownika).
CREATE TRIGGER archiwizuj
ON pracownik2
AFTER DELETE
AS
tu zastanawiałem się nad użyciem REFERENCING, nie mam pojęcia jak przekierować dane z tabeli pracownik do pracownik_archiwum
kamillo1290
5.05.2010, 09:24:35
--Napisz wyzwalacz nie pozwalający na obniżanie pensji pracownikom – w przypadku takiej próby ma zwracać odpowiedni komunikat.
CREATE TRIGGER notupdate
ON pracownik2
FOR UPDATE
AS
DECLARE
@pensja DECIMAL(6,2);
BEGIN
SELECT @pensja=pensja FROM inserted;
IF @pensja < pensja
RAISERROR 30002 'You cannot decrease a salary';
END
-- SELECT pensja FROM pracownik2
-- IF (@pensja<pensja)
-- SELECT pensja FROM pracownik2
-- WHERE nr_pracownika IN (SELECT nr_pracownika FROM inserted WHERE @pensja<pensja)
Kombinowalem jak się da z tym ciałem funkcji, ale mimo to wywołuje błąd lecz zmienia przy tym wartości pensji, może ktoś napisać jak zmodyfikować poprawnie? Byłbym wdzięczny za szybką odpowiedź
--UPDATE pracownik2 SET pensja=pensja-50.00
prachwal
5.05.2010, 19:32:29
inserted jest wirtualną tabelą i musiał byś pracować kursorem lub operować zbiorami żeby określić to co uległo zmianie, a zmianie mogło ulec zarówno w przód jak i tył
np. zapytanie
SELECT pr.*
FROM pracownik2 AS pr JOIN inserted prn ON pr.id = prn.id
WHERE pd.pensja <> prn.pensja
zwróci ci zbiór tego co uległo zmianie
jak policzysz rekordy z tego czegoś i dasz np.
IF EXISTS (SELECT pr.*
FROM pracownik2 AS pr JOIN inserted prn ON pr.id = prn.id
WHERE pd.pensja <> prn.pensj)
BEGIN
ROLLBACK TRAN
RAISERROR('You cannot decrease a salary', 16, 1) WITH SETERROR
END
a opakowanie tego w trigger zostawiam już tobie
kamillo1290
7.05.2010, 18:35:37
Dzięki za pomoc.
Mam takie zadanie:
--3.Napisz wyzwalacz, który uniemożliwi usunięcie rekordu z tabeli pracownik - powinien zostać wypisany komunikat: "Usuwanie rekordów z tabeli pracownik nie jest dozwolone".
CREATE TRIGGER notdelete ON pracownik2
INSTEAD OF DELETE AS
BEGIN
SET NOCOUNT ON
IF ((SELECT nr_pracownika FROM deleted) = (SELECT nr_pracownika FROM deleted))
RAISERROR 30001 'Usuwanie rekordów z tabeli pracownik nie jest dozwolone'
END
--DELETE FROM pracownik2 WHERE nr_pracownika='0012';
--DELETE FROM pracownik2 WHERE imie='JAREK';
powyżej mój pomysł na rozwiązanie, teoretycznie działa, lecz ten warunek nie do końca mi się podoba, może ktoś ma jakieś sugestie do korekty?
prachwal
10.05.2010, 23:20:15
nie zrobiłeś rollbacka transakcji więc nastąpił (auto)Commit
elektro1212
22.05.2011, 18:59:36
Cytat(kamillo1290 @ 28.04.2010, 13:27:28 )

Jeszcze mam, jak dla mnie, trudniejsze zadanie:
--Utwórz wyzwalacz Archiwizuj, który po usunięciu pracownika z tabeli pracownik automatycznie umieszcza jego dane w tabeli pracownik_archiwum, wraz z datą usunięcia i nazwą użytkownika dokonującego operacji usuwania (select user_name() zwraca nazwę aktualnego użytkownika).
CREATE TRIGGER archiwizuj
ON pracownik2
AFTER DELETE
AS
Czy ktoś byłby w stanie mnie naprowadzić jak napisać takiego triggera ? (mojego pierwszego triggera;))