在Oracle中编写复杂的行级触发器

问题描述 投票:0回答:2

我必须在一个名为Movies的表上创建一个行级触发器,它将从此Movies表中计算出五个最高的电影评分,并在这些电影中插入一个名为TopMovies的新表。每次我在“电影”表中添加新的评分时,都会触发该触发器。我真的很难理解该怎么做。

电影表具有以下属性(电影,导演,评分)顶级电影表将具有(评分)

到目前为止,我只有以下代码。我真的迷失了制作方法,因此,一旦我在Movies表中至少插入了5个评分,TopMovies表将删除评分最低的电影,并用新电影重新填充它。我不是要答案,而是要向正确的方向提供任何帮助

Create of replace Trigger top_trigger
After insert or update on Movies
For each row

Begin
   insert into TopMovies values (:new.rating),
End
oracle plsql sql-insert database-trigger
2个回答
0
投票

您可以使用以下triggers。但是请注意,使用触发器时,并发请求可能会更改预期的行为。

触发解决方案:

CREATE OR REPLACE TRIGGER TOP_TRIGGER AFTER
    INSERT OR UPDATE ON MOVIES
    FOR EACH ROW
DECLARE
    LV_CNT      NUMBER := 0;
    LV_RATING   TOPMOVIES.RATING%TYPE;
BEGIN
    SELECT COUNT(1), MIN(RATING)
      INTO LV_CNT, LV_RATING
      FROM TOPMOVIES;

    IF LV_CNT >= 5 AND :NEW.RATING > LV_RATING THEN
        DELETE FROM TOPMOVIES WHERE RATING = LV_RATING;
    END IF;

    IF LV_CNT < 5 OR ( LV_CNT >= 5 AND :NEW.RATING > LV_RATING ) THEN
        INSERT INTO TOPMOVIES VALUES ( :NEW.RATING );
    END IF;

END;
/

更好的解决方案是使用视图。

查看解决方案:

CREATE OR REPLACE VIEW TOPMOVIES_VW AS
    SELECT * FROM
        (
            SELECT T.*,
                   DENSE_RANK() OVER( ORDER BY RATING DESC) AS RANK#
              FROM MOVIES T
        )
    WHERE RANK# <= 5;

干杯!


0
投票

您可以尝试以下代码-

Create of replace Trigger top_trigger
After insert or update on Movies
Declare
    v_movie_count  number:= 0;
Begin
    select count(*)
    into v_movie_count
    from Movies;

    if v_movie_count >= 5 then

       delete from TopMovies;

       INSERT INTO TopMovies
       SELECT *
       FROM (SELECT Rating, ROWNUM RN
             FROM Movies
             ORDER BY Rating)
       WHERE RN <= 5;
       /* You can use below statement if you are using 12C or higher*/
       /*INSERT INTO TopMovies
         SELECT Rating, ROWNUM RN
         FROM Movies
         ORDER BY Rating DESC
         FETCH FIRST 5 ROWS ONLY;*/
    end if;
End
© www.soinside.com 2019 - 2024. All rights reserved.