今天來講下mysql儲存過程中的游標和事務。游標和事務的解釋,這裡就不再說了。直接上例子。下面的儲存過程是在我工作中寫的用來同步資料的乙個案例,我稍作簡化,刪除了大部分和業務相關的sql,保留和突出了游標和事務的相關sql,並且在重要的地方寫上了注釋,方便理解。
同步業務簡單說一下:
1、取dump庫中前一天的資料,放入游標下面就是例子了(p≧w≦q)2、online庫和dump庫前一天的資料(第一步取出的資料)對比,online庫里沒有的,插入online庫;online庫里有的,更新online庫里對應的資料。
3、更新online庫已發布的既存的資料。(此處不理解可忽略,業務相關)
4、將此次同步資料的儲存過程記錄日誌表。方便檢視每次同步的耗時、更新及插入條數等。
create
definer
=`root`
@`%`
procedure
`sync_to_online`()
begin
declare item_id bigint(20
);# 資產編號 - 業務相關判斷
declare asset_state int(1
);# 資產狀態 - 業務相關判斷
declare start_time datetime
default
now();
# 儲存過程開始時間
declare end_time datetime
;# 儲存過程結束時間
declare insert_count int(15
)default0;
# 儲存過程插入的資料條數
declare update_count int(15
)default0;
# 儲存過程更新的資料條數
declare result tinyint(1
);# 儲存過程執行結果(0:失敗,1:成功)
declare exist int(15
);# 是否存在 - 業務相關判斷
declare pre_asset_state int(1
);# 前狀態 - 業務相關判斷
declare done int
default0;
declare t_error integer
default0;
declare cur cursor
for# 將select查詢結果放入游標
# 1.此處同步業務邏輯為:將topdb_dump.topnpl_asset_tb_detail表中昨天的資料取出來,放入cur中
select
*from
topdb_dump.topnpl_asset_tb_detail devtb
where
date_format(devtb.update_time,
'%y-%m-%d'
)= date_format(date_sub(
now(),
interval
1day),
'%y-%m-%d');
declare
continue
handler
for sqlstate '02000'
set done =1;
# 迴圈結束標識
declare
continue
handler
for sqlexception set t_error =1;
# 事務執行失敗標識
start
transaction
;# 開啟事務
open cur;
# 開啟游標
fetch cur into
# 獲取游標中的值
item_id,
asset_state;
while done <>1do
# 開始迴圈
# 2.此處同步業務邏輯為:比較topnpl_dump庫中昨天的資料,topdb_online.topnpl_asset_tb_detail表中不存在的插入,存在的更新,並記錄插入或更新條數
select
count
(onlinetb.id)
, onlinetb.asset_state into exist, pre_asset_state
from
topdb_online.topnpl_asset_tb_detail onlinetb
where
onlinetb.item_id=item_id;
if exist =
0and
(asset_state =
5or asset_state =6)
then
insert
into topdb_online.topnpl_asset_tb_detail values
(item_id,asset_state)
;set insert_count = insert_count +1;
else
update topdb_online.topnpl_asset_tb_detail onlinetb set onlinetb.asset_state = asset_state
where onlinetb.item_id=item_id;
set update_count = update_count +1;
endif
;fetch cur into
item_id,
asset_state;
endwhile
;# 結束迴圈
close cur;
# 關閉游標
# 3.此處同步業務邏輯為:更新已發布的資產資料
update
topdb_online.topnpl_asset_detail_basic basic
inner
join
topdb_online.topnpl_asset_tb_detail tb on tb.id = basic.tb_detail_id
set basic.startday = tb.startday,
basic.endday = tb.endday;
if t_error =
1then
# 事務回滾
rollback
;set result =0;
# 執行結果:失敗
set end_time =
now();
else
# 事務提交
commit
;set result =1;
# 執行結果:成功
set end_time =
now();
endif
;# 4.將此次同步資料的儲存過程記錄日誌表(記錄內容:事件名,開始時間,結束時間,耗時,插入個數,更新個數,變更總數,結果,日誌插入者,日誌插入時間)
insert
into topdb_online.topnpl_event_logs
(event_name, start_time, end_time, duration, insert_count, update_count, total, result, create_id, create_time)
values
('sync_to_online_event'
, start_time, end_time, timestampdiff(
second
, start_time, end_time)
, insert_count,
update_count,
(insert_count + update_count)
, result,0,
now())
;end
MySQL 游標和儲存過程
我們有時候會遇到需要對 從a表查詢的結果集s s 的記錄 進行遍歷並做一些操作 如插入 且這些操作需要的資料或許部分來自s s集合 臨時儲存過程,沒辦法,不能直接在查詢視窗做這些事。drop procedure ifexists proc tmp create procedure proc tmp ...
mysql 游標 儲存過程
1.首先需要注意的是mysql中游標必須要建立在儲存過程中 2.直接上sql 查詢當天資料 select in flow out flow from water meter data where 1 1 and date sys read time curdate 1 order by in flo...
MySQL 儲存過程 游標
儲存過程 本儲存過程有特殊執行迴圈數量的要求,是對security market history表進行修正 判斷儲存過程是否存在 drop procedure if exists proc security market history update create procedure proc se...