Как обновить определенные кортежи после удаления в таблице - PullRequest
0 голосов
/ 26 мая 2019

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

Вот пример таблицы списка воспроизведения (извините за португальские имена. IdMusica = идентификатор песни; posicao = позиция песни в списке воспроизведения)

Playlists

Для дальнейшего объяснения того, что я хочу, вот пример: если я удалю песню 6 из списка воспроизведения 1, позиция песни 11 станет 3.

Ответы [ 2 ]

1 голос
/ 26 мая 2019

Я верю, что следующее будет делать, как вы хотите: -

CREATE TRIGGER IF NOT EXISTS playlistreorder 
    AFTER DELETE ON playlist
    BEGIN
        UPDATE playlist SET posicao = posicao -1 WHERE posicao > old.posicao AND idPlayList = old.idPlayList;
    END
;
  • Обратите внимание, что имена таблиц считаются списком воспроизведения

Пример

Рассмотрим следующий тест: -

DROP TABLE IF EXISTS playlist;
CREATE TABLE IF NOT EXISTS playlist (idMusica INTEGER, idPlayList INTEGER, posicao INTEGER);
INSERT INTO playlist (idMusica,idPlayList, posicao) VALUES
    (12,1,1),(5,1,2),(6,1,3),(11,1,4),
    (1,2,1),(2,2,2),(3,2,2),(4,2,4),(9,2,5)
;

CREATE TRIGGER IF NOT EXISTS playlistreorder 
    AFTER DELETE ON playlist
    BEGIN
        UPDATE playlist SET posicao = posicao -1 WHERE posicao > old.posicao AND idPlayList = old.idPlayList;
    END
;
SELECT * FROM playlist;
DELETE FROM playlist WHERE posicao = 3 AND idplayList = 1;
SELECT * FROM playlist;

Пример результатов

Перед повторным заказом (1-й запрос): -

enter image description here

После повторного заказа (2-й запрос): -

enter image description here

0 голосов
/ 26 мая 2019

Я бы сказал, что этот подход в корне неверен и чрезмерно хрупок. Вместо отслеживания позиции absolute в списке воспроизведения, отслеживайте позицию относительно . Таким образом, вам не нужно обновлять позиции при вставке или удалении песен:

Если первые три песни имеют значения posicao 1,2,3, и вы хотите добавить песню в позицию 2, вместо обновления текущих 2 на 3, текущих 3 на 4 и т. Д., Используйте новое значение на полпути между текущими 1 и 2 позициями posicao 's: 1,5 в этом случае.

При удалении не беспокойтесь о заполнении пробела; posicao по обе стороны от удаленной песни все еще находятся в правильном порядке.

Если вам по какой-то причине нужна абсолютная позиция, вы можете рассчитать ее в SELECT на лету с современными версиями sqlite (3.25 или новее) с чем-то вроде

SELECT idMusica, row_number() OVER (ORDER BY posicao) AS pos
FROM playlist_songs
WHERE idPlaylist = :playlistid
ORDER BY posicao

или просто увеличивая счетчик в вашей программе каждый раз, когда вы выбираете строку из заданного списка воспроизведения, если он упорядочен по posicao.

Запросы на основе оконных функций для вставки в середину списка воспроизведения и удаления с учетом абсолютной позиции (хотя для удаления, если ваша соединительная таблица не является WITHOUT ROWID, легче отследить rowid песен в свою программу и удалите, используя ту, что для выбранной песни):

INSERT INTO playlist_songs(idMusica, idPlaylist, posicao)
VALUES(:songid, :playlistid
     , (SELECT (pos + prev_pos) / 2.0
        FROM (SELECT posicao AS pos
                   , lag(posicao, 1, 0.0) OVER (ORDER BY posicao) AS prev_pos
                   , row_number() OVER (ORDER BY posicao) AS rn
              FROM playlist_songs WHERE idPlaylist = :playlistid)
        WHERE rn = :position));

DELETE FROM playlist_songs
WHERE rowid = (SELECT rowid
               FROM (SELECT rowid, row_number() OVER (ORDER BY posicao) AS rn
                     FROM playlist_songs WHERE idPlaylist = :playlistid)
               WHERE rn = :position);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...