MySQL – Tworzenie kursora

Jeśli potrzebujesz w funkcji lub procedurze przelecieć po określonych rekordach w bazie danych to kursor okaże się najlepszym rozwiązaniem, przynajmniej jeśli chodzi o bazy MySQL. Postgre okazuje się tutaj być potęgą. W postgresie wystarczy zadeklarować w zmiennej listę interesujących nas rekordów i w zwykłej pętli wiersz po wierszu możemy przejść po wszystkich rekordach.
Przykładowy kursor MySQL poniżej, opisy w kodzie.

— DROP PROCEDURE IF EXISTS MOVE_OLD_AUTOMAILER_RECORDS;

-- DROP PROCEDURE IF EXISTS MOVE_OLD_AUTOMAILER_RECORDS;

DELIMITER //
CREATE PROCEDURE MOVE_OLD_AUTOMAILER_RECORDS ()
    BEGIN
        DECLARE koniec, is_failed_, is_sending_, is_sent_, is_html_ SMALLINT;
        DECLARE id_ INTEGER;
        DECLARE from_email_, from_name_, to_email_ VARCHAR(255);
        DECLARE subject_, body_, alt_body_, swift_message_ LONGTEXT;
        DECLARE created_at_, sent_at_, started_sending_at_ DATETIME;
   
    /* Deklaracja kursora */
    /* Zapytanie sql */
    DECLARE k1 CURSOR FOR SELECT id, from_email, from_name, to_email, subject, body, alt_body, swift_message, created_at, sent_at, is_html, is_sending, is_sent, is_failed, started_sending_at FROM automailer as a WHERE sent_at < = (SELECT NOW() - INTERVAL 1 MONTH) ORDER BY id;
    
    /* Co zrobić gdy dojdziemy do ostatniego wiersza */
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET koniec = 1;
   
    /* Zakładamy tabele tymczasową */
    
    DROP TEMPORARY TABLE IF EXISTS automailer_tmp;
    CREATE TEMPORARY TABLE automailer_tmp(
        id int,
        from_email varchar(255),
        from_name varchar(255),
        to_email varchar(255),
        subject longtext CHARSET utf8,
        body longtext CHARSET utf8,
        alt_body longtext CHARSET utf8,
        swift_message longtext,
        created_at datetime,
        sent_at datetime,
        is_html tinyint(1),
        is_sending tinyint(1),
        is_sent tinyint(1),
        is_failed tinyint(1),
        started_sending_at datetime
    );
    
    /* Otwieramy kursor */
    OPEN k1;
    
    SET koniec=0;
        
    /* Pętla wiersz po wierszu */
    petla: LOOP    
        /* Pobranie danych z kursora */
        FETCH k1 INTO id_, from_email_, from_name_, to_email_, subject_, body_, alt_body_, swift_message_, created_at_, sent_at_, is_html_, is_sending_, is_sent_, is_failed_, started_sending_at_;
        /* Wyjdź jeśli juz skończyły się wiersze */
        
        IF koniec = 1 then
            LEAVE petla;
        END IF;
        /* Oblicz... wstaw dane do tabeli tymczasowej */
        INSERT INTO automailer_old VALUES (id_, from_email_, from_name_, to_email_, subject_, body_, alt_body_, swift_message_, created_at_, sent_at_, is_html_, is_sending_, is_sent_, is_failed_, started_sending_at_);
        DELETE FROM automailer WHERE id = id_;
    END LOOP;
    /* Koniec pętli po wierszach */
    CLOSE k1;
END; //
DELIMITER ;

Leave a Reply