Как установить обновленное значение родительской таблицы в таблице материализованного представления с помощью триггера, если обновленное значение не было пустым или пустым - PullRequest
0 голосов
/ 30 апреля 2020

Я использую C#'s EF Core, и хорошим преимуществом этого является то, как я могу динамически обновлять любой атрибут в модели Users одним методом. Я хочу, чтобы триггер чувствовал, когда мой атрибут token в моей таблице Users обновляется. Это довольно просто, но, скажем, Users имеет два «подклассы / материализованные представления» Donators и Staffs. Я хочу, чтобы следующие симметричные атрибуты совпадали при обновлении через триггер.


CREATE TABLE [Users](
    email VARCHAR(320) NOT NULL,
    password_salt varbinary(max) NOT NULL,
    password_hash varbinary(max) NOT NULL,
    token VARCHAR(320),
    /*d=Donator | s=Staff*/
    roles VARCHAR (2) NOT NULL,
    /*For: Donator */
    amount_donated MONEY,
    /*For: Staff */
    title VARCHAR(128),
    PRIMARY KEY (email),
);
/***Role Based Sub-Class Tables***/
CREATE TABLE Donators(
    email VARCHAR(320) NOT NULL,
    password_salt varbinary(max) NOT NULL,
    password_hash varbinary(max) NOT NULL,
    token VARCHAR(320),
    roles VARCHAR (2) NOT NULL,
    amount_donated MONEY NOT NULL,
    PRIMARY KEY (email),
    FOREIGN KEY (email) REFERENCES [Users](email)
        ON DELETE CASCADE
        ON UPDATE CASCADE
);
CREATE TABLE Staffs(
    email VARCHAR(320) NOT NULL,
    password_salt varbinary(max) NOT NULL,
    password_hash varbinary(max) NOT NULL,
    token VARCHAR(320),
    roles VARCHAR (2) NOT NULL,
    title VARCHAR(128) NOT NULL,
    type VARCHAR(256),
    created DATETIME,
    PRIMARY KEY (email),
    FOREIGN KEY (email) REFERENCES [Users](email)
        ON DELETE CASCADE
        ON UPDATE CASCADE
);

Чтобы не загромождать этот раздел с вопросами, я не буду ставить свой триггер, поскольку в данный момент он не работает так, как я хочу, поскольку атрибут Donators token не совпадает при обновлении Users атрибут token.

Мой код, относящийся к этому вопросу, можно найти здесь (строки 248-366). Heads up У пользователей есть еще несколько подклассов. Но мне просто нужно понять и найти код, который позволяет token в Staffs и Donators.

1 Ответ

0 голосов
/ 30 апреля 2020

Хорошо, поэтому в статье Хищного Бабуина я нашел ответ на свой вопрос. Вот триггер того, как я собираюсь обновлять свое материализованное представление Donators. Следовать за любым наследством, я думаю, само собой разумеется. (Не стесняйтесь спрашивать, если запутался)

CREATE TRIGGER User_Updated_Check
ON [Users]
AFTER UPDATE
AS
BEGIN
    SET NOCOUNT ON

    DECLARE @email VARCHAR(320);
    DECLARE @old_roles VARCHAR (2);
    DECLARE @new_password_hash VARBINARY(max);
    DECLARE @new_password_salt VARBINARY(max);
    DECLARE @new_token VARCHAR(320);
    DECLARE @new_f_name VARCHAR(64);
    DECLARE @new_l_name VARCHAR(64);
    DECLARE @new_roles VARCHAR (2);
    DECLARE @new_amount_donated MONEY;
    DECLARE @new_title VARCHAR(128);
    DECLARE @new_type VARCHAR(256);
    DECLARE @new_created DATETIME;


    SET @email = (SELECT email FROM Inserted);
    SET @old_roles = (SELECT roles FROM Deleted);
    SET @new_password_hash = (SELECT  password_hash FROM Inserted);
    SET @new_password_salt = (SELECT  password_salt FROM Inserted);
    SET @new_token = (SELECT token FROM Inserted);
    SET @new_f_name = (SELECT f_name FROM Inserted);
    SET @new_l_name = (SELECT l_name FROM Inserted);
    SET @new_roles = (SELECT roles FROM Inserted);
    SET @new_amount_donated = (SELECT amount_donated FROM Inserted);
    SET @new_title = (SELECT title FROM Inserted);
    SET @new_type = (SELECT type FROM Inserted);
    SET @new_created = (SELECT created FROM Inserted);



    IF @old_roles != @new_roles
        BEGIN
            THROW 51000, 'The Roles need to match and cannot change', 1;
            ROLLBACK TRANSACTION
        END

    IF @new_roles != 'd' AND
       @new_roles != 's' AND
       @new_roles != 'e' AND
       @new_roles != 'a' AND
       @new_roles != 'sd' AND
       @new_roles != 'ed' AND
       @new_roles != 'ad'
        BEGIN
            THROW 51000, 'The Role entered does not exist', 1;
            ROLLBACK TRANSACTION
        END

    -- Donators
    IF @new_roles = 'd'  OR
       @new_roles = 'sd' OR
       @new_roles = 'ed' OR
       @new_roles = 'ad'
        IF UPDATE(token)
            UPDATE Donators
            SET token = @new_token
            WHERE email = @email;
        IF Update(password_salt)
            UPDATE Donators
            SET password_salt = @new_password_salt
            WHERE email = @email;
        IF Update(password_hash)
            UPDATE Donators
            SET password_hash = @new_password_hash
            WHERE email = @email;
        IF UPDATE(f_name)
            UPDATE Donators
            SET f_name = @new_f_name
            WHERE email = @email;
        IF Update(l_name)
            UPDATE Donators
            SET l_name = @new_l_name
            WHERE email = @email;
        IF Update(amount_donated)
            UPDATE Donators
            SET amount_donated = @new_amount_donated
            WHERE email = @email;

END

...