英文:
Using cursor for loop to get data
问题
我想选择即将到期的所有员工合同,
然后如果我获得一个或多个员工,我想通过电子邮件、短信、ESS或移动电话发送通知给他们的经理,之前要检查它们的值并且必须等于是,然后我调用发送函数
我尝试使用游标循环来做到这一点,但是出现了多个错误
有人可以帮我吗?
create or replace function NOTIFICATION_SENDING(P_NOTIF_ID NUMBER) return NUMBER
IS
V_EMP NUMBER;
V_USER NUMBER;
V_EMAIL VARCHAR2(1);
V_SMS VARCHAR2(1);
V_ESS VARCHAR2(1);
V_MOBILE VARCHAR2(1);
CURSOR C1 IS
SELECT EMP_ID FROM HR_EMP_CONTRACT_HEADER
where months_between(EDATE,sysdate) >= 1
and months_between(EDATE,sysdate) <= 3;
CURSOR C2 IS
SELECT USER_ID from NL_NOTIF_EMP_HEADER
where NOTIF_ID = P_NOTIF_ID;
BEGIN
for i in C1 LOOP
V_EMP := i.EMP_ID;
END LOOP;
IF V_EMP is not null THEN
for i in C2 LOOP
V_USER := i.USER_ID;
END LOOP;
IF V_USER IS NOT NULL THEN
SELECT EMAIL, SMS, ESS, MOBILE
INTO V_EMAIL, V_SMS, V_ESS, V_MOBILE
from NL_NOTIF_EMP_HEADER
where NOTIF_ID = P_NOTIF_ID;
IF V_EMAIL = 'Y' THEN
NOTIF_EMAIL_SENDING(P_NOTIF_ID, V_USER);
END IF;
IF V_SMS = 'Y' THEN
NOTIF_SMS_SENDING(P_NOTIF_ID, V_USER);
END IF;
IF V_ESS = 'Y' THEN
NOTIF_ESS_SENDING(P_NOTIF_ID, V_USER);
END IF;
IF V_MOBILE = 'Y' THEN
NOTIF_MOBILE_SENDING(P_NOTIF_ID, V_USER);
END IF;
END IF;
END IF;
END NOTIFICATION_SENDING;
这是我使用的代码。
英文:
I want to select all employees that the contract is about to expire
then if I get one employee or more then I want to send notification to their managers using email , SMS ,ESS or mobile after checking the value of them and must equal yes then I call the sending function
I tried to do that using cursor for loop but I got more than one error
can anyone help me?
create or replace function NOTIFICATION_SENDING(P_NOTIF_ID NUMBER) return NUMBER
IS
V_EMP NUMBER;
V_USER NUMBER;
V_EMAIL VARCHAR2(1);
V_SMS VARCHAR2(1);
V_ESS VARCHAR2(1);
V_MOBILE VARCHAR2(1);
CURSOR C1 IS
SELECT EMP_ID FROM HR_EMP_CONTRACT_HEADER
where months_between(EDATE,sysdate) >=1
and months_between(EDATE,sysdate) <= 3;
CURSOR C2 IS
SELECT USER_ID from NL_NOTIF_EMP_HEADER
where NOTIF_ID = P_NOTIF_ID;
BEGIN
for i in C1 LOOP
V_EMP := i.EMP_ID;
END LOOP;
IF V_EMP is not null THEN
for i in C2 LOOP
V_USER := i.USER_ID;
END LOOP;
IF V_USER IS NOT NULL THEN
SELECT EMAIL , SMS , ESS , MOBILE
INTO V_EMAIL , V_SMS , V_ESS , V_MOBILE
from NL_NOTIF_EMP_HEADER
where NOTIF_ID = P_NOTIF_ID;
IF V_EMAIL = 'Y' THEN
NOTIF_EMAIL_SENDING(P_NOTIF_ID ,V_USER );
END IF;
IF V_SMS = 'Y' THEN
NOTIF_SMS_SENDING(P_NOTIF_ID ,V_USER );
END IF;
IF V_ESS = 'Y' THEN
NOTIF_ESS_SENDING(P_NOTIF_ID ,V_USER );
END IF;
IF V_MOBILE = 'Y' THEN
NOTIF_MOBILE_SENDING(P_NOTIF_ID ,V_USER );
END IF;
END IF;
END IF;
END NOTIFICATION_SENDING;
This the code I used
答案1
得分: 1
根据你的代码:
- 你在使用游标循环的方式上存在问题,因为你的代码只影响了一个(最后一个)由两个游标检索到的值
- 我不知道为什么你选择在游标中获取
user_id
,而在独立的select
语句中获取所有其他值;似乎是不必要的
- 我不知道为什么你选择在游标中获取
- 这是一个函数,你没有返回任何东西,所以Oracle可能会抱怨
- 分开的
if
语句表明经理希望以多种可能的方式(并且将会)被通知。如果这不是你想要的,请考虑使用IF-ELSIF来代替
对我来说,不清楚nl_notif_emp_header
包含什么,以及p_notif_id
参数代表什么。我认为它只包含每个p_notif_id
值的一行,表示由user_id
标识的经理希望通过任何(可以是零个、一个或四个)可用的方式接收通知。
由于你没有返回任何东西,我认为使用存储过程更合适。
在我的示例中,我:
- 不必要地使用游标(
cur_n
)遍历nl_notif_emp_header
,只是为了避免声明5个本地变量并使用游标变量代替 - 遍历(
cur_e
)满足条件的员工,并根据所有通知方式将通知发送给经理- 不清楚
notif_xxx_sending
过程做什么。我期望它们接受经理(谁将被通知)和员工信息(以便经理知道是哪个员工),而你传递了p_notif_id
参数值(?!为什么?)和经理ID(这是正确的)。因此,在我的示例中,我添加了另一个参数;无法确定是否合适
- 不清楚
所以:
create or replace procedure NOTIFICATION_SENDING (P_NOTIF_ID in number)
is
begin
-- CUR_N只返回一行,但是,我使用一次性游标循环,而不是声明一堆本地变量
for cur_n in (select user_id, email, sms, ess, mobile
from nl_notif_emp_header
where notif_id = p_notif_id
)
loop
-- 满足条件的员工
for cur_e in (select emp_id
from hr_emp_contract_header
where months_between(edate, sysdate) between 1 and 3
)
loop
if cur_n.email = 'Y' then
notif_email_sending (p_notif_id, cur_n.user_id, cur_e.emp_id);
end if;
if cur_n.sms = 'Y' then
notif_sms_sending (p_notif_id, cur_n.user_id, cur_e.emp_id);
end if;
-- 等等,对于所有通知方式
end loop;
end loop;
end;
/
英文:
As of your code:
- you use cursor loops in a wrong manner, as your code affects only one (the last) value retrieved by both cursors
- I don't know why you chose to fetch
user_id
in cursor and all other values in standaloneselect
statement; seems to be unnecessary
- I don't know why you chose to fetch
- that's a function, and you aren't returning anything so Oracle must be complaining about it
- separate
if
s suggest that manager wants to be (and will be) notified in many possible ways. If that's not what you wanted, consider using IF-ELSIF instead
To me, it is unclear what nl_notif_emp_header
contains nor what p_notif_id
parameter represents. I think that it contains only one row for each p_notif_id
value, saying that manager identified by user_id
wants to get notification by ANY (can be none, one, or all four) way available.
As you aren't returning anything, I'd say that procedure suits better.
In my example, I'm
- looping (unnecessary) (
cur_n
) throughnl_notif_emp_header
, just to avoid declaration of 5 local variables and use cursor variable instead - looping (
cur_e
) through employees that satisfy condition and - depending on all ways of notification - sending it to manager- it is unclear what
notif_xxx_sending
procedures do. I'd expect them to accept manager (who is to be notified) and employee info (so that manager knows which employee it is about), while you're passingp_notif_id
parameter value (?!? Why?) and manager ID (that's OK). Therefore, I added yet another parameter in my example; can't tell whether that's OK or not
- it is unclear what
So:
create or replace procedure NOTIFICATION_SENDING (P_NOTIF_ID in number)
is
begin
-- CUR_N returns only one row, but - instead of declaring bunch of local
-- variables, I'm using a one-time cursor loop
for cur_n in (select user_id, email, sms, ess, mobile
from nl_notif_emp_header
where notif_id = p_notif_id
)
loop
-- employees that satisfy condition
for cur_e in (select emp_id
from hr_emp_contract_header
where months_between(edate, sysdate) between 1 and 3
)
loop
if cur_n.email = 'Y' then
notif_email_sending (p_notif_id, cur_n.user_id, cur_e.emp_id);
end if;
if cur_n.sms = 'Y' then
notif_sms_sending (p_notif_id, cur_n.user_id, cur_e.emp_id);
end if;
-- etc., for all ways of notification
end loop;
end loop;
end;
/
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论