MySQLストアド・プロシージャ--製造日時の偽データを一括作成(メモ)

4339 ワード

select database();
DROP PROCEDURE IF EXISTS updateTitleTime;
DELIMITER $$
USE photographic $$
CREATE PROCEDURE updateTitleTime (IN sourceStartDate VARCHAR(20), IN sourceEndDate VARCHAR(20), IN targetStartDate VARCHAR(20), IN targetEndDate VARCHAR(20))
BEGIN
	DECLARE s_startDate DATETIME;
	DECLARE s_endDate DATETIME;
	DECLARE t_startDate DATETIME;
	DECLARE t_endDate DATETIME;
	DECLARE t_titleId VARCHAR(30);
	DECLARE t_sortId VARCHAR(30);
	DECLARE t_sortDetailId VARCHAR(30);
	DECLARE t_titleStartTime DATETIME;
	DECLARE t_replyTime DATETIME;
	DECLARE totalDays INT;
	DECLARE indexDay INT;
	DECLARE t_date VARCHAR(10);
	DECLARE t_time VARCHAR(8);
	DECLARE n_titleStartTime DATETIME;
	DECLARE title_done INT DEFAULT 0;
	DECLARE titleCursor CURSOR FOR select titleId,sortId,sortDetailId,titleStartTime from ebbbstitle where titleStartTime>=s_startDate and titleStartTime<=s_endDate;
	DECLARE CONTINUE HANDLER FOR NOT FOUND SET title_done=1;
	SELECT str_to_date(sourceStartDate,'%Y-%m-%d %H:%i:%s') into s_startDate;
	SELECT str_to_date(sourceEndDate,'%Y-%m-%d %H:%i:%s') into s_endDate;
	SELECT str_to_date(targetStartDate,'%Y-%m-%d %H:%i:%s') into t_startDate;
	SELECT str_to_date(targetEndDate,'%Y-%m-%d %H:%i:%s') into t_endDate;
	select to_days(t_endDate)-to_days(t_startDate) into totalDays;
	OPEN titleCursor;
	REPEAT
        FETCH titleCursor INTO t_titleId,t_sortId,t_sortDetailId,t_titleStartTime;
        IF NOT title_done THEN
       		SELECT FLOOR(0 + RAND() * totalDays) into indexDay;
        	select DATE_FORMAT(DATE_ADD(t_startDate,INTERVAL indexDay DAY), '%Y-%m-%d') into t_date;
        	select DATE_FORMAT(t_titleStartTime,'%H:%i:%s') into t_time;
        	select STR_TO_DATE(CONCAT(t_date,' ',t_time), '%Y-%m-%d %H:%i:%s') into n_titleStartTime;
        	update ebbbstitle set titleStartTime=n_titleStartTime where titleId=t_titleId and sortId=t_sortId and sortDetailId=t_sortDetailId;
        	BEGIN
	        DECLARE r_replyNo VARCHAR(30);
	        DECLARE r_titleId VARCHAR(30);
	        DECLARE r_replyTime DATETIME;
	        DECLARE n_replyTime DATETIME;
	        DECLARE r_time VARCHAR(8);
	        DECLARE totalSeconds INT;
	        DECLARE indexSecond INT DEFAULT 1;
	        DECLARE reply_done INT DEFAULT 0;
        	DECLARE replyCursor CURSOR FOR select replyNo,titleId,replyTime from ebbbsreply where titleId=t_titleId;
			DECLARE CONTINUE HANDLER FOR NOT FOUND SET reply_done=1;
			SELECT TIMESTAMPDIFF(SECOND,n_titleStartTime,t_endDate) INTO totalSeconds;
        	OPEN replyCursor;
				REPEAT
					FETCH replyCursor INTO r_replyNo,r_titleId,r_replyTime;
					IF NOT reply_done THEN
						SELECT FLOOR(1 + RAND() * (totalSeconds-2)) into indexSecond;
						SELECT DATE_ADD(n_titleStartTime, INTERVAL indexSecond SECOND) INTO n_replyTime;
						update ebbbsreply set replyTime=n_replyTime where replyNo=r_replyNo and titleId=r_titleId;
					END IF;
				UNTIL reply_done END REPEAT;
			CLOSE replyCursor;
	        END;
	        BEGIN
		    DECLARE t_lastReplyTime DATETIME;
		    DECLARE reply_done INT DEFAULT 0;
			DECLARE replyCursor CURSOR FOR select replyTime from ebbbsreply where titleId=t_titleId order by replyTime desc limit 0,1;
			DECLARE CONTINUE HANDLER FOR NOT FOUND SET reply_done=1; 
			OPEN replyCursor;
				REPEAT
					FETCH replyCursor INTO t_lastReplyTime;
					IF NOT reply_done THEN
        				update ebbbstitle set lastReplyTime=t_lastReplyTime where titleId=t_titleId and sortId=t_sortId and sortDetailId=t_sortDetailId;
					END IF;
				UNTIL reply_done END REPEAT;
			CLOSE replyCursor;
		    END;
        END IF;
    UNTIL title_done END REPEAT;
	CLOSE titleCursor;
	COMMIT;
END $$
DELIMITER ;

このストレージ・プロシージャは、データベース初心者にとって次のような知識点に関連しています.
乱数(foolr()、rand()、計算2つの日付間の日数to_days(endDate)-to_days(startDate)、ストレージ時の値付け方法(select into)、カーソル遍歴クエリ結果、宣言変数DECLARE、日付関数(str_to_date、date_format、date_add、timestampdiff)
カーソルは次の文を繰り返します.
DECLARE CONTINUE HANDLER FOR NOT FOUND SET title_done=1;

カーソル変数を宣言するときのwhere条件の値は、先に値を割り当てる必要はありませんが、カーソルを開く前に値を割り当てる必要があります.
DECLARE titleCursor CURSOR FOR select titleId,sortId,sortDetailId,titleStartTime from ebbbstitle where titleStartTime>=s_startDate and titleStartTime<=s_endDate;