牛B的存儲過程

DROP PROCEDURE IF EXISTS `demo3`;

CREATE DEFINER = `root`@`localhost` PROCEDURE `demo3`(OUT `bilv` double)
BEGIN

DECLARE arg_id INT DEFAULT 49;
DECLARE start VARCHAR(30) DEFAULT '2012-06-29 00.00.00';
DECLARE end VARCHAR(30) DEFAULT '2012-07-20 23.59.59';
DECLARE f int DEFAULT -1;-- 不能刪除 與業務無關 操蛋之極
DECLARE x BIGINT;-- 轉換成long型 運算時間  這個時間是(秒)爲單位
DECLARE t VARCHAR(30);-- 時間
DECLARE d_id INT;-- 設備id
DECLARE id INT;--  這條數據  id
DECLARE state INT; -- 上下線狀態值
DECLARE ii BIGINT DEFAULT 0;
DECLARE i int;
DECLARE linshi BIGINT; --  臨時獲取 一次上線過後 最近的一次下線
DECLARE linshi2 BIGINT DEFAULT 0; --  該變量默認值爲0不能更改  在之後程序中有爲null 判斷參與業務判斷,此次變量定義 爲解決 當 循環查詢中 查詢出 null 數據時候 並不會賦值給 INTO linshi 所以無法判斷 是否已經循環到最後一條數據了 並且 最後一條數據還是 上線數據
DECLARE sums INT; -- 查出限定範圍內的上線次數
-- 查詢 限定返回內 不分 上線 下線 的 所有數據 日期最早的一條
DECLARE all_obj CURSOR for select d.id,d.device_at,d.device_id,d.device_state,UNIX_TIMESTAMP(d.device_at) from _device_action_logger d where 1=1 and d.device_at BETWEEN STR_TO_DATE(start,'%Y-%m-%d %k.%i.%s') and STR_TO_DATE(end,'%Y-%m-%d %k.%i.%s') and device_id=arg_id order by d.device_at asc limit 1;
-- 查詢 限定返回內 不分 上線 下線 的 所有數據 日期最晚 的一條
DECLARE all_obj1 CURSOR for select d.id,d.device_at,d.device_id,d.device_state,UNIX_TIMESTAMP(d.device_at) from _device_action_logger d where 1=1 and d.device_at BETWEEN STR_TO_DATE(start,'%Y-%m-%d %k.%i.%s') and STR_TO_DATE(end,'%Y-%m-%d %k.%i.%s') and device_id=arg_id order by d.device_at DESC limit 1;
-- 查詢 時間段內 所有 上線 數據
DECLARE obj CURSOR for  select UNIX_TIMESTAMP(device_at),device_at,device_id,d1.id from _device_action_logger d1 where 1=1 and d1.device_at BETWEEN STR_TO_DATE(start,'%Y-%m-%d %k.%i.%s') and STR_TO_DATE(end,'%Y-%m-%d %k.%i.%s') and device_state=0 and device_id=arg_id ORDER BY device_at ASC;
-- 查詢上線數據總數 用於 REPEAT 循環
DECLARE o CURSOR for select count(*) from _device_action_logger d1 where 1=1 and d1.device_at BETWEEN STR_TO_DATE(start,'%Y-%m-%d %k.%i.%s') and STR_TO_DATE(end,'%Y-%m-%d %k.%i.%s') and d1.device_state=0 and device_id=arg_id;
-- 還沒搞清楚 撒玩意 暫時不扔
DECLARE CONTINUE HANDLER for not found  set f=1;

-- 判斷 第一條 是否 下線數據
open all_obj;
FETCH all_obj into id,t,d_id,state,x;
CASE state
WHEN 1 then
-- 如果查詢時間段內 第一條記錄 是下線的 那麼這次 上線的時間長度 就以 開始時間作爲此次 上線的時間點 兩時間做運算
set ii=ii+x-UNIX_TIMESTAMP(start);
WHEN 0 THEN
set ii=ii;  -- 如果 第一條記錄 是上線 這不做操作 馬屁的 這一排 必須要做點操作 所以寫了 set ii=ii; 這步是廢材
ELSE
-- 如果 出現 查詢時間段內 沒有上線下線 那麼 查詢 start 之前 最近 一條記錄 是 上線 則判斷 爲 此次查詢時間段內 全部,在線 。反正 則 不存在,在線
select device_state INTO state from _device_action_logger d where 1=1 and device_at < STR_TO_DATE(start,'%Y-%m-%d %k.%i.%s') and device_id=arg_id ORDER BY device_at DESC LIMIT 1;
CASE state
when 0 THEN
set bilv=1;
when 1 THEN
set bilv=0;
ELSE
set bilv=1;
end CASE;
end CASE;
CLOSE all_obj;

-- 判斷 最後一條數據 是否 上線數據
OPEN all_obj1;
FETCH all_obj1 INTO id,t,d_id,state,x;
CASE state
WHEN 1 THEN
-- 最後一條記錄 是下線 不做操作  馬屁的 這一排 必須要做點操作 所以寫了 set ii=ii; 這步是廢材
set ii=ii;
WHEN 0 THEN
-- 最後一條操作 是上線  則這次上線的時間長度 等於  上線 時間 與 end 兩運算
set ii=ii+UNIX_TIMESTAMP(end)-x;
ELSE
-- 空操作
set ii=ii;
end CASE;
CLOSE all_obj1;

OPEN o;
FETCH o INTO sums;
CLOSE o;

-- 設定循環變量自增 數
set i=1;

if sums <>0 then
open obj;
REPEAT  
FETCH obj into x,t,d_id,id;
--  小問題  t 生成的時間 時分秒 是 :間隔  所以 後面 注意
select UNIX_TIMESTAMP(device_at) into linshi  from _device_action_logger d2 where 1=1 and device_at BETWEEN STR_TO_DATE(t,'%Y-%m-%d %k:%i:%s') and STR_TO_DATE(end,'%Y-%m-%d %k.%i.%s') and device_state=1 and device_id=arg_id ORDER BY  device_at  ASC LIMIT 1;
select i,linshi,linshi2;
if linshi <>linshi2 THEN
set ii=ii+linshi-x;
select i, ii;
ELSE
set ii=ii; -- 空操作
select '最後一次',ii;
 END IF;
set linshi2=linshi;
set i=i+1;
until i>sums
end REPEAT;
CLOSE obj;
ELSE
set sums=sums;
END IF;
-- 運算這段時間內在線比率
set bilv=ii/(UNIX_TIMESTAMP(end)-UNIX_TIMESTAMP(start));
select bilv ,ii ;
END;


發佈了38 篇原創文章 · 獲贊 1 · 訪問量 27萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章