środa, 27 października 2010

Trigger dla kopiowania wartości atrybutów w zależności od innego atrybutu.

W nawiązaniu do tematu http://cdn.3lance.pl/viewtopic.php?f=13&t=1428 zamieszczam przykładowe rozwiązanie, wraz z opisem.

CREATE TRIGGER [CDN].[_Kopiowanie_z_wysylki]
   ON  [CDN].[Atrybuty]
   FOR INSERT, UPDATE
AS
BEGIN
    SET NOCOUNT ON;

-- Dla zmiany wartości atrybutu
    IF UPDATE (Atr_Wartosc)
    BEGIN
-- Jeżeli ID klasy atrybutu jest równe X (u mnie 79 - atrybut na dokumentach PKA/WKA z numerem wysyłki)
-- i numer wysyłki jest na parametrze ustalony:
        IF EXISTS (SELECT inserted.Atr_ID FROM inserted WHERE inserted.Atr_Atkid = 79 AND inserted.Atr_Wartosc <> '' AND inserted.Atr_Wartosc <> '<Brak>')
            BEGIN
                DECLARE @GIDWysylka INT            -- GID numer wysyłki
                DECLARE @ObiNumer INT            -- GID obiektu dla którego uruchamiany jest wyzwalacz
                DECLARE @ObiTyp INT                -- GID Typ obiektu dla którego uruchamiany jest wyzwalacz
                DECLARE @Wysylka VARCHAR(30)    -- Wartość atrybutu z numerem wysyłki
                DECLARE @param1 VARCHAR(100)    -- Wartość parametru pierwszego
                DECLARE @param2 VARCHAR(100)    -- Wartość parametru drugiego
                DECLARE @param3 VARCHAR(100)    -- Wartość parametru trzeciego

-- Pobranie wartości atrybutu z numerem wysyłki
                SET @Wysylka = (SELECT Atr_wartosc FROM inserted)

-- Pobranie GID-u obiektu (w tym przypadku PKA/WKA) dla którego zmieniana jest wartość atrybutu.
                SET @ObiNumer = (SELECT Atr_ObiNumer FROM inserted)

-- Pobranie GID typ-u obiektu (w tym przypadku PKA/WKA) dla którego zmieniana jest wartość atrybutu.
                SET @ObiTyp = (SELECT Atr_ObiTyp FROM inserted)

-- Pobranie GID-u wysyłki o określonym numerze (w moim przypadku seria jest pusta więc ją pomijam).
-- Generalnie jest to zależne od tego w jaki sposób uzupełniamy wartość atrybutu z numerem wysyłki.
-- Dla mnie seria zawsze jest pusta, a więc nie biorę jej pod uwagę - numer wysyłki na atrybucie określam poprzez wybór z listy za pomocą zapytania:
-- SELECT     cast(Wys_numer as varchar(5)) + '/' +  cast(Wys_rok as varchar(4)) as Numer FROM CDN.Wysylki
-- Stąd też wyjściowy sposób zwrócenia GID-u dla moich wysyłek:

                SET @GIDWysylka = (SELECT isnull(WYS_GIDNumer,0) FROM CDN.Wysylki
                                   WHERE WYS_GIDTyp = 337
                                   AND WYS_Numer = cast(substring(@Wysylka,1,charindex('/',@Wysylka)-1) as int)
                                   AND WYS_Rok = cast(substring(@Wysylka,charindex('/',@Wysylka)+1,4) as int))
               
-- Pobranie wartości pierwszego parametru z wysyłki, który będziemy kopiować
                SET @param1 = (SELECT isnull(Atr_Wartosc,'') FROM CDN.Atrybuty
                               WHERE Atr_ObiTyp = 337 AND Atr_ObiNumer = @GIDWysylka AND Atr_AtkID = 80) 

-- Pobranie wartości drugiego parametru z wysyłki, który będziemy kopiować
                SET @param2 = (SELECT isnull(Atr_Wartosc,'') FROM CDN.Atrybuty
                               WHERE Atr_ObiTyp = 337 AND Atr_ObiNumer = @GIDWysylka AND Atr_AtkID = 81)

-- Pobranie wartości trzeciego parametru z wysyłki, który będziemy kopiować
                SET @param3 = (SELECT isnull(Atr_Wartosc,'') FROM CDN.Atrybuty
                               WHERE Atr_ObiTyp = 337 AND Atr_ObiNumer = @GIDWysylka AND Atr_AtkID = 82)
               
-- Skopiowanie wartości pierwszego parametru na obiekt docelowy
                UPDATE CDN.Atrybuty
                SET Atr_Wartosc = @param1
                WHERE Atr_ObiTyp = @ObiTyp AND CDN.Atrybuty.Atr_ObiNumer = @ObiNumer AND Atr_AtkID = 80

-- Skopiowanie wartości drugiego parametru na obiekt docelowy
                UPDATE CDN.Atrybuty
                SET Atr_Wartosc = @param2
                WHERE Atr_ObiTyp = @ObiTyp AND CDN.Atrybuty.Atr_ObiNumer = @ObiNumer AND Atr_AtkID = 81

-- Skopiowanie wartości trzeciego parametru na obiekt docelowy
                UPDATE CDN.Atrybuty
                SET Atr_Wartosc = @param3
                WHERE Atr_ObiTyp = @ObiTyp AND CDN.Atrybuty.Atr_ObiNumer = @ObiNumer AND Atr_AtkID = 82
   
            END
    END
   
END


Zaznaczam, iż wyzwalacz ma charakter edukacyjny i z tym wiąże się deklarowanie tylu zmiennych oraz jego dość rozbudowana forma. To samo można osiągnąć przy użyciu jednego UPDATE FROM SELECT, aczkolwiek uznałem, że nie dla wszystkich byłoby to czytelne.

Pole Atr_AtkID to oczywiście ID atrybutów które nas interesują - w moim przypadku są to ID ze zbioru {79,80,81,82} - w waszym zapewne będą inne i wymaga to sprawdzenia. Wyzwalacz skopiuje wartość danego atrybutu tylko w przypadku gdy ten atrybut będzie istniał na docelowym elemencie.

Jak na razie to pierwszy trigger jaki tu zamieszczam, aczkolwiek zapewne nie ostatni, jako iż jest to ciekawa funkcja SQL Server, która daje administratorowi dużo możliwości.

Brak komentarzy:

Prześlij komentarz