Jacek Michalski

Jacek Michalski Entrepreneur

Temat: Trigger dbo.ZAMOWIENIE a grupowa zmiana statusów

Witam,
napisałem trigger na tabeli ZAMOWIENIE, który po zmianie statusu na określony ma dodawać pewną wartość do POLE2


ALTER TRIGGER [dbo].[tm_status_helper]
ON [dbo].[ZAMOWIENIE]
AFTER UPDATE
AS
BEGIN

SET NOCOUNT ON;

DECLARE @id_zamowienia numeric(18, 0), @typ tinyint, @trybrejestracji tinyint, @status_zam varchar(1), @pole2 varchar(100)

DECLARE cs_update_zamowienie CURSOR FOR SELECT ID_ZAMOWIENIA, TYP, TRYBREJESTRACJI, STATUS_ZAM, POLE2 FROM inserted
OPEN cs_update_zamowienie
FETCH NEXT FROM cs_update_zamowienie INTO @id_zamowienia, @typ, @trybrejestracji, @status_zam, @pole2

WHILE @@FETCH_STATUS = 0 BEGIN
--@trybrejestracji 0 -> glowny rejestr zam; @typ 1 -> ZO
IF (@typ = 1 AND @trybrejestracji = 0 and @status_zam = 'M' and @pole2 = '') BEGIN
UPDATE ZAMOWIENIE
SET POLE2 = 'R'
WHERE ID_ZAMOWIENIA = @id_zamowienia
END

FETCH NEXT FROM cs_update_zamowienie INTO @id_zamowienia, @typ, @trybrejestracji, @status_zam, @pole2
END
CLOSE cs_update_zamowienie
DEALLOCATE cs_update_zamowienie

END


Wszystko działa Ok w przypadku zmiany statusu per zamówienie. W przypadku grupowej zmiany statusów niestety nie. Czy ktoś ma może wiedzę odnośnie logiki grupowych updateów i dlaczego powyższe rozwiązanie nie działa? W związku z tym, że na tej tabeli istnieje już kilka napisanych przez wapro triggerów (zaszyfrowanych i nie da się ich podejrzeć) to czy powyższy trigger jest bezpieczny?

Z góry dziękuję za pomoc.

Pozdrawiam,
Jacek Michalski
Szymon M.

Szymon M. Kierownik działu IT

Temat: Trigger dbo.ZAMOWIENIE a grupowa zmiana statusów

Witam,

dla grupowego update-u trzeba zrobić "join" z tabelą dbo.ZAZNACZONE

Pozdrawiam

Jacek M.:
Witam,
napisałem trigger na tabeli ZAMOWIENIE, który po zmianie statusu na określony ma dodawać pewną wartość do POLE2


ALTER TRIGGER [dbo].[tm_status_helper]
ON [dbo].[ZAMOWIENIE]
AFTER UPDATE
AS
BEGIN

SET NOCOUNT ON;
DECLARE @id_zamowienia numeric(18, 0), @typ tinyint, @trybrejestracji tinyint, @status_zam varchar(1), @pole2 varchar(100)
DECLARE cs_update_zamowienie CURSOR FOR SELECT ID_ZAMOWIENIA, TYP, TRYBREJESTRACJI, STATUS_ZAM, POLE2 FROM inserted
OPEN cs_update_zamowienie
FETCH NEXT FROM cs_update_zamowienie INTO @id_zamowienia, @typ, @trybrejestracji, @status_zam, @pole2

WHILE @@FETCH_STATUS = 0 BEGIN
--@trybrejestracji 0 -> glowny rejestr zam; @typ 1 -> ZO
IF (@typ = 1 AND @trybrejestracji = 0 and @status_zam = 'M' and @pole2 = '') BEGIN
UPDATE ZAMOWIENIE
SET POLE2 = 'R'
WHERE ID_ZAMOWIENIA = @id_zamowienia
END

FETCH NEXT FROM cs_update_zamowienie INTO @id_zamowienia, @typ, @trybrejestracji, @status_zam, @pole2
END
CLOSE cs_update_zamowienie
DEALLOCATE cs_update_zamowienie
END


Wszystko działa Ok w przypadku zmiany statusu per zamówienie. W przypadku grupowej zmiany statusów niestety nie. Czy ktoś ma może wiedzę odnośnie logiki grupowych updateów i dlaczego powyższe rozwiązanie nie działa? W związku z tym, że na tej tabeli istnieje już kilka napisanych przez wapro triggerów (zaszyfrowanych i nie da się ich podejrzeć) to czy powyższy trigger jest bezpieczny?

Z góry dziękuję za pomoc.

Pozdrawiam,
Jacek Michalski
Paweł Parzych

Paweł Parzych Starszy Programista
Delphi/MSSQL

Temat: Trigger dbo.ZAMOWIENIE a grupowa zmiana statusów

Dość ryzykowne rozwiązanie, żeby trigger powodował modyfikację tabeli, z której został wywołany ale faktycznie to działa.

Osobiście sugerowałbym to obsłużyć gniazdami na zamówieniach.
Krzysztof Stachyra

Krzysztof Stachyra Szef Wydziału
Produkcji Systemów
Handlowo-Magazynowyc
h i ...

Temat: Trigger dbo.ZAMOWIENIE a grupowa zmiana statusów

i pytanie po co ten kursor w tym miejscu? nie można tego zrobić po bożemu jednym updatem - będzie wydajniej
Rafał M.

Rafał M. Dyrektor ds. Asseco
WAPRO ERP, Asseco
Business Solutions
...

Temat: Trigger dbo.ZAMOWIENIE a grupowa zmiana statusów

Proszę nie pisać własnych triggerów i to jeszcze w ten sposób bo to jest poważne psucie programu (już nie mówiąc o złamaniu licencji, która zabrania modyfikować kod programu poza przewidzianymi przez producenta miejscami). Potem sie dziwimy dlaczego niektóre błędy nie wychodzą w testach :). Trigger nie działa bo się zapętla. Nagłówek zamówienia aktualizowany jest za każdym razem poprzez ustawienie semfora - ten trigger wtedy też się wykona. Po to są gniazda rozszerzeń aby łatwiej i bezpieczniej można było zapanować nad modyfikacjami w programie.

W tej chwili ten trigger wykonuje się podczas:
1. Modyfikacji zamówienia przed otwarciem i po zatwierdzeniu
2. Realizacji zamówienia.
3. Zatwierdzaniu dokumentu handlowego/magazynowego utworzonego z zamówienia
4. Funkcjach kontrolnych
itd...
Pytanie - po co ?

Najważniejsza i podstawowa zasada - w triggerach należy minimalizować ilość zmienianych wierszy co związane jest m.in, z alokacją zasobów serwera do utrzymania blokad a w konsekwencji z szybkością i płynnością działania. Dlatego najważniejszy jest warunek na wstępie kiedy trigger ma prawo się wykonać.

Tak to trzeba zrobić:


IF UPDATE(STATUS_ZAM)
IF exists (SELECT 1 FROM INSERTED I inner join DELETED D on (I.ID_ZAMOWIENIA=D.ID_ZAMOWIENIA)
WHERE I.STATUS_ZAM<>D.STATUS_ZAM
and I.TYP=1
and I.TRYBREJESTRACJI=0
and isnull(I.POLE2,'')='')
BEGIN
UPDATE ZAM
SET POLE2 = 'R'
FROM ZAMOWIENIE ZAM inner join INSERTED I on (I.ID_ZAMWOIENIA=ZAM.ID_ZAMOWIENIA)
inner JOIN DELETED D on (D.ID_ZAMOWIENIA=I.ID_ZAMOWIENIA)
WHERE I.STATUS_ZAM<>D.STATUS_ZAM
and I.TYP=1
and I.TRYBREJESTRACJI=0
and isnull(I.POLE2,'')=''
END
RETURN


Proponuję jednak uruchomić własną procedurę w gniazdach po zmianie statusu w operacji dodatkowej oraz po zatwierdzeniu zamówienia, która zrobi to co trzeba.

Następna dyskusja:

grupowa zmiana kategorii wi...




Wyślij zaproszenie do