儲存過程游標迴圈賦值返回為NULL

2021-09-13 02:33:40 字數 4227 閱讀 7096

儲存過程的整體思路是查詢dwd_cms_c_cons,得到cons_no,再根據cons_no查詢dwd_cms_arc_e_cons_snap,得到calc_id結果集,迴圈calc_id結果集拼接成逗號隔開的字串,再用結果去查詢dwd_cms_arc_e_consprc_tactic_snap,同樣的方法處理結果集,再同樣去查 dwd_cms_arc_e_mp_para_snap

create  procedure `test1`(in time varchar(6))

begin

declare calc_ids varchar(64) default(0);

declare prc_tactic_snap_ids varchar(64) default(0);

declare mp_para_snap_ids varchar(64) default(0);

-- 定義乙個區域性變數接受客戶編號資料集

declare s_region varchar(16);

declare done int default(0);

-- 定義乙個動態游標

declare cur ref cursor;

declare continue handler for sqlstate '02000' set done = 1; -- 操作器

/**查詢客戶號**/

-- open cur for select distinct cons_no from dwd_cms_c_cons where volt_code in ('ac00101','ac01101','ac00201','ac02201', 'ac02751','ac03301','ac00351','ac05001','ac10001','ac07501')order by cons_no ;

open cur for select distinct cons_no from dwd_cms_c_cons where cons_no = '1500496788';

-- 迴圈

repeat

-- 拿到游標中的值

fetch cur into s_region;

-- 判斷游標是否迴圈是否結束

if not done then

-- 查詢中間表 dwd_cms_arc_e_cons_snap

begin

-- 定義乙個區域性變數接受返回資料集

declare s_region1 bigint(20);

declare done1 int default(0);

-- 定義乙個動態游標

declare cur1 ref cursor;

declare continue handler for sqlexception,sqlwarning, sqlstate '02000' set done1 = 1; -- 操作器

/**查詢 dwd_cms_arc_e_cons_snap**/

open cur1 for select t3.calc_id from dwd_cms_arc_e_cons_snap t3 where t3.cons_no = s_region and t3.ym=time;

repeat

fetch cur1 into s_region1;

if not done1 then

set calc_ids = concat(calc_ids,',',s_region1);

end if;

until done1 end repeat;

close cur1; -- 關閉游標

end;

select calc_ids 'calc_ids';

-- 查詢中間表 dwd_cms_arc_e_consprc_tactic_snap

begin

declare s_region2 bigint(20); -- 定義乙個區域性變數

declare done2 int default(0);

declare cur2 ref cursor; -- 定義乙個動態游標

declare continue handler for sqlwarning,sqlexception, sqlstate '02000' set done2 = 1; -- 操作器

/**查詢dwd_cms_arc_e_consprc_tactic_snap**/

open cur2 for select t2.prc_tactic_snap_id from dwd_cms_arc_e_consprc_tactic_snap t2 where find_in_set(t2.calc_id,calc_ids);

repeat

fetch cur2 into s_region2;

if not done2 then

set prc_tactic_snap_ids = concat(prc_tactic_snap_ids,',',s_region2);

end if;

until done2 end repeat;

close cur2; -- 關閉游標

end;

select prc_tactic_snap_ids 'prc_tactic_snap_ids';

-- 查詢中間表 dwd_cms_arc_e_mp_para_snap

begin

declare mp_para_region bigint(20); -- 定義乙個區域性變數

declare mp_para_done int default(0);

declare mp_para_cur ref cursor; -- 定義乙個動態游標

declare continue handler for sqlwarning,sqlexception, sqlstate '02000' set mp_para_done = 1; -- 操作器

/**查詢 e_mp_para_snap**/

open mp_para_cur for select t1.mp_para_snap_id from dwd_cms_arc_e_mp_para_snap t1 where find_in_set(t1.prc_tactic_snap_id,prc_tactic_snap_ids);

repeat

fetch mp_para_cur into mp_para_region;

if not mp_para_done then

select mp_para_snap_ids 'mp_para_snap_ids';

set mp_para_snap_ids = concat(mp_para_snap_ids,',',mp_para_region);

end if;

until mp_para_done end repeat;

close mp_para_cur; -- 關閉游標

end;

select mp_para_snap_ids 'mp_para_snap_ids';

end if;

until done end repeat;

close cur; -- 關閉游標

end

列印結果為

在游標內的列印是有結果的,但是結果返回的事null,

也不能是你定義游標時用過的別名(如本例中的count),只要乙個條件不符合,fetch into就把全部的變數賦null值

仔細檢查發現問題:

declare calc_ids varchar(64) default(0); 

declare prc_tactic_snap_ids varchar(64) default(0);

declare mp_para_snap_ids varchar(64) default(0);

游標記憶體拼接的字元創超過了變數宣告時指定的長度

declare calc_ids varchar(225) default(0); 

declare prc_tactic_snap_ids varchar(225) default(0);

declare mp_para_snap_ids varchar(225) default(0);

問題解決

參考:mysql游標迴圈取出空值的bug

Oracle儲存過程返回游標

oracle儲存過程返回游標 有倆種方法 一種是宣告系統游標,一種是宣告自定義游標,然後後面操作一樣,引數型別為 in out 或out 1 宣告個人系統游標.推薦 create or replace p temp procedure cur arg out sys refcursor 方法1 be...

oracle 儲存過程返回游標

示例,很多時候我們需要返回結果集,這個時候,我們就可以返回游標的方式給別人呼叫 create or replace procedure getprocontactinfowithpropid prop id in varchar2,outcursor out sys refcursor isbegi...

儲存過程 游標巢狀迴圈

alterprocedure dbo asdeclare startnum nvarchar 255 declare endnum nvarchar 255 declare insurancetype nvarchar 255 declare company id nvarchar 255 decl...