Удалить последние N записей из базы данных по полю X, используя триггер - PullRequest
0 голосов
/ 07 февраля 2020

У меня есть таблица на SQL Сервере, который хранит историю паролей пользователей, чтобы пользователь не мог повторно использовать ранее использованный пароль.

CREATE TABLE user_password_histories 
(
    id BIGINT IDENTITY CONSTRAINT user_password_histories_pk PRIMARY KEY NONCLUSTERED
    ,password VARCHAR(128) NOT NULL
    ,user_id BIGINT NOT NULL
    ,created_at DATETIME DEFAULT GETUTCDATE() NOT NULL
    ,updated_at DATETIME
)

Однако я хочу поддерживать только список из 10 историй паролей для пользователя. Итак, я думаю использовать триггер, чтобы сохранить только 10 историй для каждого пользователя во время вставки.

Частичное решение, которое я придумал, это

CREATE TRIGGER trg_user_password_histories  
ON user_password_histories
AFTER INSERT
AS
    DELETE FROM user_password_histories
    WHERE user_password_histories.user_id = Inserted.user_id // This will not work
      AND user_password_histories.id NOT IN (SELECT t2.id
                                             FROM user_password_histories t2
                                             WHERE t2.id = user_password_histories.id
                                             ORDER BY t2.created_at DESC 
                                                 OFFSET 10 ROWS)
GO

Но проблема здесь что Inserted может иметь несколько записей. Поэтому я не уверен, как решить эту проблему или как решить ее.

1 Ответ

1 голос
/ 10 февраля 2020

Хорошо, наконец, я думаю, что нашел решение для этого. Я проверил это с пакетной вставкой и одной вставкой, и это работает !!! Я должен был использовать cursor, чтобы решить это. Я публикую здесь свое решение, чтобы другие могли извлечь из него пользу.

CREATE TRIGGER trg_user_password_histories_insert ON user_password_histories
    AFTER INSERT
    AS
    DELETE uph FROM user_password_histories uph
    WHERE uph.user_id IN (SELECT user_id FROM Inserted)
    AND uph.id NOT IN (
        SELECT id FROM (
            SELECT user_password_histories.id, ROW_NUMBER() OVER(PARTITION BY user_password_histories.user_id ORDER BY user_password_histories.created_at DESC) AS rn
            FROM user_password_histories
            WHERE user_password_histories.user_id IN (SELECT user_id FROM Inserted)
        ) t
        WHERE t.rn <= 10
    )
go

Возможно, это решение не подходит для всех сценариев ios, но в этом случае оно прекрасно работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...