Próbuję wykonać następujące czynności za pomocą wyzwalacza SQL Server: Po włożeniu nowego wiersza do stołu, chciałbym zaktualizować kolumnę w innej tabeli.

Na przykład: Mam tablicę Users i tabeli o nazwie Activity. Za każdym razem, gdy klient łączy się z serwerem, włożono wiersz do tabeli Activity; Po włożeniu wiersza (który zawiera user_id), chciałbym zaktualizować kolumnę w tabeli Users, która przechowuje datę i godzinę ostatniej aktywności.

UPDATE Users
SET Last_Activity_TimeStamp = GETDATE()
WHERE Users.User_ID = Activity.User_ID

Ale SSM rzuca błąd mówiąc:

Identyfikator wieloczęściowy "DBO.CAITY.USER_ID" nie mógł być związany

Jeśli zmienię powyższe oświadczenie o aktualizacji:

UPDATE Users
SET Last_Activity_TimeStamp = GETDATE()
WHERE Users.User_ID = User_ID

Wszystkie wiersze w tabeli użytkowników są aktualizowane.

Rozumiem, że istnieje tabela Inserted i że rzędy są tam dodawane, zanim zostaną włożone do głównej tabeli {X1}}, jednak mamy potencjalnie wielu użytkowników podłączonych, a włożyły się wiele wierszy Tabela Activity. Potencjalnie 1000 na sekundę. Chciałbym wiedzieć, jak uzyskać user_id wiersza wstawionego do Activity i zaktualizuj Last_Activity_TimeStamp w tabeli Users.

Edytuj: Chyba, gdzie brakuje mi wiedzy, że nie wiem, ile wierszy może być w stole Inserted w dowolnym momencie, biorąc pod uwagę, że w moim projekcie pojedyncza transakcja wstawia tylko jeden wiersz. Czy możliwe jest, że w tabeli {X1}} z innych aktywnych transakcji, ponieważ istnieje wiele użytkowników łączących i odłączyć?

Każda pomoc będzie bardzo doceniana!

Dziękuję Ci

2
awdBoy 2 czerwiec 2018, 11:05

3 odpowiedzi

Najlepsza odpowiedź

Innymi odpowiedziami oboje nie uwzględniają pod uwagę, że tabela pseudo Inserted w wyzwalaniu będzie zawierać wiele wierszy Czasami - jeden powinien nigdy nigdy Wybierz jedną wartość - To będzie nie działa , zgodnie z oczekiwaniami, jeśli włożono wiele wierszy.

Wyzwalacz musi być napisany w sposób oparty na stronie , aby obsłużyć tę sytuację - co jest naprawdę całkiem łatwe - spróbuj czegoś takiego:

CREATE TRIGGER trgActivityInsert
ON [dbo].[Activity]
FOR INSERT
AS
BEGIN
    UPDATE u
    SET Last_Activity_TimeStamp = GETDATE()
    FROM dbo.Users u
    INNER JOIN Inserted i ON u.User_Id = i.User_Id
END

Dzięki temu twój wyzwalacz będzie działał w porządku, czy wstawisz jedną, dziesięć lub sto rzędów naraz, a wszystkie odpowiednie wpisy w tabeli dbo.User zostaną prawidłowo aktualizowane.

4
marc_s 2 czerwiec 2018, 09:41

Tylko jeden wiersz trzyma wstawiony stół do pojedynczej transakcji. Za każdym razem, gdy wkładanie danych w tabeli aktywności, wyzwalacz wykonuje dla każdej pojedynczej wkładki.

Więc możesz spróbować tego .....

Create Trigger Trigger_UpdateUsers
    ON Activity 
    For INSERT
As
Begin

    Declare @user_id varchar(10)

    SELECT  @user_id = user_id from INSERTED

    UPDATE  Users set Last_Activity_TimeStamp=GETDATE() 
    WHERE   Users.User_ID =@user_id

End
GO
-1
sydur.rahman21 2 czerwiec 2018, 09:11

Nie można odnieść się dziedzinach tabeli takich jak DBO.CAITY.USER_ID . Zmień Ci kod wyzwalający taki jak ten ..

CREATE TRIGGER Trk_Test 
    ON [dbo].[Activity]
    FOR INSERT
AS
BEGIN
    DECLARE @Id INT = 0

    SELECT @ID = [User_Id] FROM inserted

    UPDATE Users 
    SET Last_Activity_TimeStamp = GETDATE()
    WHERE [User_Id] = @Id

END

włożone i usunięte tabele Włożony / usunięty to stół wirtualny, który ma zakres tylko do wyzwalacza. Nie można odnieść się poza spustem. Niezależnie od tego, jak wielu użytkowników jest połączonych na raz, włożone i usunięte stoły nigdy nie są konfliktowe.

-1
halfer 8 czerwiec 2018, 11:29