關於資料庫查詢優化的乙個例子(責任中心例子)

2021-05-24 09:00:51 字數 4978 閱讀 9547

create or replace function "get_empcenter"(pi_empoid     number,

pi_group      number,

pi_unitid     number,

ps_year       varchar2,

ps_month      varchar2,

ps_delivernum number)

--返回交流、掛職類人員所對應的成本部門(不一定是責任中心)

return number is

li_unit1         number := 0;

ls_date1         char(6);

ls_month1        char(3);

li_count1        number;

ls_date          char(6);

ls_month         char(3);

li_count         number;

li_dutycenter    number := 0; --財務責任中心

li_orgunit       number := 0; --財務機構

li_id            number;

li_pid           number;

li_parentorgunit number := 0; --機構oid

begin

-- 先判斷發放記錄表中是否已經插入過本發放月的本員工 如果以後反映效率低,此處,以及以後的count(*)都可以改為使用游標代替,可以減少一半的查詢量

select count(*)

into li_count1

from tb_cnb_dutycenterjudge pay

where pay.c_month = ps_month

and pay.c_year = ps_year

and pay.c_unitid = pi_unitid

and pay.c_groupid = pi_group

and pay.c_empoid = pi_empoid

and pay.c_delivernum = ps_delivernum;

if li_count1 > 0 then

select pay.c_payunitid

into li_dutycenter

from tb_cnb_dutycenterjudge pay

where pay.c_month = ps_month

and pay.c_year = ps_year

and pay.c_unitid = pi_unitid

and pay.c_groupid = pi_group

and pay.c_empoid = pi_empoid

and pay.c_delivernum = ps_delivernum

and rownum = 1;

return li_dutycenter;

end if;

ls_month1 := '0' || ps_month;

ls_date1  := ps_year || substr(ls_month1, length(ls_month1) - 1);

--判斷是否在個人責任中心中維護,如未維護則直接返回員工所在部門

select count(*)

into li_count1

from tb_cnb_empduty

where c_empid = pi_empoid

and c_groupid = pi_group

and c_efectivetime <= ls_date1;

if li_count1 = 0 then

li_unit1 := pi_unitid;

end if;

if li_count1 > 0 then

--如責任中心中維護個人資訊,則取生效時間之前最近生效的一條記錄

select c_dutycentreid

into li_unit1

from (select *

from tb_cnb_empduty

where c_empid = pi_empoid

and c_groupid = pi_group

and c_efectivetime <= ls_date1

order by c_efectivetime desc) a

where rownum = 1;

end if;

--以上獲取了員工的成本部門資訊li_unit1,接下來要用員工的成本部門去獲取員工所在的成本中心

ls_month := '0' || ps_month;

ls_date  := ps_year || substr(ls_month, length(ls_month) - 1);

li_id := li_unit1;

----如果是責任中心,直接返回

select count(*)

into li_count

from tb_cnb_dutycenter d

where d.c_unitid = li_id

and d.c_efectivetime <= ls_date;

if li_count > 0 then

select a.c_unitid, a.c_compid

into li_dutycenter, li_orgunit

from (select *

from tb_cnb_dutycenter dc

where dc.c_unitid = li_id

and c_efectivetime <= ls_date

order by c_efectivetime desc) a

where rownum = 1;

insert into tb_cnb_dutycenterjudge

values

(pi_empoid,

pi_group,

pi_unitid,

ps_year,

ps_month,

li_dutycenter,

ps_delivernum);

return li_dutycenter;

end if;

--先根據員工oid查出其對應的機構,放入li_parentorgunit中作為待查條件

select c_orgid

into li_parentorgunit

from tb_inf_employee emp

where emp.c_oid = pi_empoid;

if li_parentorgunit <> pi_unitid then

loop

select count(*)

into li_count1

from tb_org_unitrelation

where c_orgunitid = li_id

and c_hiberarchyid = 1

and c_status = 1;

if li_count1 = 0 then

insert into tb_cnb_dutycenterjudge

values

(pi_empoid,

pi_group,

pi_unitid,

ps_year,

ps_month,

pi_unitid,

ps_delivernum);

return pi_unitid;

end if;

select c_parentunitid

into li_pid

from tb_org_unitrelation

where c_orgunitid = li_id

and c_hiberarchyid = 1

and c_status = 1;

exit when li_pid = li_parentorgunit;

--如果不是責任中心,迴圈查詢直到找到責任中心

--先判斷是否是責任中心

select count(*)

into li_count

from tb_cnb_dutycenter d

where d.c_unitid = li_pid

and d.c_efectivetime <= ls_date;

if li_count > 0 then

select a.c_unitid, a.c_compid

into li_dutycenter, li_orgunit

from (select *

from tb_cnb_dutycenter dc

where dc.c_unitid = li_pid

and c_efectivetime <= ls_date

order by c_efectivetime desc) a

where rownum = 1;

exit;

else

li_id := li_pid;

end if;

end loop;

end if;

-- 如果最終沒有得出責任中心的值,則把員工所在組織機構賦值給責任中心

if li_dutycenter = 0 then

li_dutycenter := pi_unitid;

end if;

insert into tb_cnb_dutycenterjudge

values

(pi_empoid,

pi_group,

pi_unitid,

ps_year,

ps_month,

li_dutycenter,

ps_delivernum);

return li_dutycenter;

end get_empcenter;

mysql 關於子查詢的乙個例子

假設表my tbl包含三個欄位a,b,c 現在需要查詢表中列a的每個不同值下的列b為最小值的記錄量。比如表記錄為 a b c 1 3 cd 2 3 nhd 1 5 bg 2 6 cds 1 7 kiy 3 7 vsd 3 8 ndf 希望得到結果為 a b c 1 3 cd 2 3 nhd 3 7 ...

mysql 關於子查詢的乙個例子

假設表my tbl包含三個欄位a,b,c 現在需要查詢表中列a的每個不同值下的列b為最小值的記錄量。比如表記錄為 a b c 1 3 cd 2 3 nhd 1 5 bg 2 6 cds 1 7 kiy 3 7 vsd 3 8 ndf 希望得到結果為 a b c 1 3 cd 2 3 nhd 3 7 ...

關於陣列的乙個例子

慶祝活動,現在a b c三條 要同時開始鳴放禮炮各21響。已知a艦每隔5秒鳴放一次,b艦每隔6秒鳴放一次,c艦每隔7秒鳴放一次。假設炮手對時間掌握的都很準,那麼總共聽到多少聲炮響?對於這個問題,可以使用陣列來解決。首先使用三個陣列分別存放a,b,c艦21響禮炮的鳴放時間點,這裡可以使用乙個for迴圈...