【问题标题】:MYSQL - Stored Procedures guidanceMYSQL - 存储过程指南
【发布时间】:2012-11-20 07:08:10
【问题描述】:

我需要编写一个存储过程,我必须找到过去 6 个月内每个月在收音机上播放歌曲的总时间,因此 6 个输出,本月,上个月,依此类推,直到 6 个月前。为此,我必须使用 Track_no 的 start_airtime 和 finish_airtime。这些总和将为我提供总播出时间,并且必须按每个单独的月份分开,并且输出应包含两列,首先是月份名称,其次是已播出的总时间。

请注意,开始播放时间和结束播放时间是歌曲的长度,但我没有此信息可用于必须从这两个值中推导出它。

我的表设置如下:

track_no TINYINT(3) UNSIGNED
genre VARCHAR(60)
purchasedate DATE NOT NULL
start_airtime TIME NOT NULL
finish_airtime TIME
artist CHAR(9)

我对存储过程一无所知,所以任何信息都将不胜感激。非常感谢。

到目前为止,我的代码是:

DELIMITER //
DROP PROCEDURE IF EXISTS airtime_of_month//
CREATE PROCEDURE airtime_of_month(IN track_input TINYINT) 
BEGIN
        DECLARE x, track_num TINYINT;
        DECLARE totalTime VARCHAR(25);
        SET x = 7;
        SET track_num = track_input;
        WHILE x > 1 DO
                    SET x = x - 1;
                    SELECT track_no INTO track_num
                            FROM Radio
                            WHERE track_input = track_no;
                    IF (track_input IS NULL) THEN
                            SELECT CONCAT(track_input, ' Is Not                               
                                                           A Valid Track Number') as _;
                ELSE 
                       SELECT track_no,   
             CONCAT(FLOOR(HOUR(TIMEDIFF(finish_airtime,start_airtime)) / 24), ' days ',
                 MOD(HOUR(TIMEDIFF(finish_time,start_airtime)), 24), ' hrs ',                                
          MINUTE(TIMEDIFF(finish_airtime,start_airtime)), ' minutes ') AS total_AirTime
                FROM Radio
                WHERE DATE_SUB(MONTH(purchasedate), INTERVAL x   
                                                                               MONTH);
                END IF;
                SELECT track_num;
    END WHILE;
END //

CALL airtime_of_month (2)/ 
DELIMITER ;

但是,当我这样做时,它会编译但不会返回任何内容。有什么想法吗?

【问题讨论】:

    标签: mysql database stored-procedures


    【解决方案1】:

    首先,除非您绝对必须,否则不要使用存储过程(顺便说一句,这种情况很少)。

    请参阅this answer,了解为什么不应该使用存储过程的一些原因。

    这可以通过一个相当简单的查询来完成,如果您想要 SQL 代码的模块化,可以将其“打包”到一个视图中:

    create view track_airtime as
    select
        track_no, 
        extract(YEAR_MONTH from purchasedate) as year_month, 
        sum(minute(TIMEDIFF(finish_airtime, start_airtime))) as total_airtime
    from mytable
    where extract(YEAR_MONTH from purchasedate) >= 
          extract(YEAR_MONTH from subdate(now(), interval 6 month))
    and track_no = ?
    group by 1, 2
    order by 2 desc
    

    【讨论】:

    • 我需要使用存储过程,因为我需要将 Track_no 传递给过程
    • @user1854392 但您可以轻松地将曲目编号传递给查询
    • 我需要它对用户友好,所以我不希望他们自己浏览代码并编辑它,而只是有一个参数,他们可以在其中输入他们的哪个参数想找。
    • @user1854392 然后让它成为一个视图!视图是从应用程序代码中外部化 sql 代码的好方法,并且可以在不重新构建应用程序的情况下对其进行返工
    【解决方案2】:

    函数示例:

    DROP FUNCTION IF EXISTS test;
    
    DELIMITER $$
    CREATE FUNCTION test(in_number INT) RETURNS INT
        BEGIN
            DECLARE countTotal INT;
            SET countTotal = SELECT COUNT(*) FROM nGrams;
        RETURN countTotal + in_number;
    END $$
    DELIMITER ;
    

    程序示例:

    DROP PROCEDURE IF EXISTS cron_scrubber;
    
    DELIMITER $$
    CREATE PROCEDURE cron_scrubber()
    BEGIN
    
        INSERT INTO driver_car_ready_history (id_driver_car_ready, status, date_register, id_driver_car, id_job) 
        SELECT dcr.id_driver_car_ready, dcr.status, dcr.date_register, dcr.id_driver_car, dcr.id_job 
        FROM driver_car_ready dcr 
        ORDER BY dcr.id_driver_car_ready;
    
        TRUNCATE TABLE driver_car_ready;
    
    END $$
    DELIMITER ;
    

    希望对你有所帮助。

    【讨论】:

    猜你喜欢
    • 2011-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-01
    • 2017-04-26
    • 2011-03-09
    • 2011-03-31
    相关资源
    最近更新 更多