使用游标循环来获取数据

huangapple go评论58阅读模式
英文:

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) &gt;=1
        and months_between(EDATE,sysdate)  &lt;= 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 = &#39;Y&#39;  THEN
                NOTIF_EMAIL_SENDING(P_NOTIF_ID ,V_USER );
            END IF;
        
            IF  V_SMS = &#39;Y&#39; THEN
                NOTIF_SMS_SENDING(P_NOTIF_ID ,V_USER );
            END IF;
            
            IF  V_ESS = &#39;Y&#39; THEN
                NOTIF_ESS_SENDING(P_NOTIF_ID ,V_USER );
            END IF;
               
            IF  V_MOBILE = &#39;Y&#39; 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 standalone select statement; seems to be unnecessary
  • that's a function, and you aren't returning anything so Oracle must be complaining about it
  • separate ifs 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) through nl_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 passing p_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

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&#39;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 = &#39;Y&#39; then 
         notif_email_sending (p_notif_id, cur_n.user_id, cur_e.emp_id);
      end if;
      
      if cur_n.sms = &#39;Y&#39; 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;
/

huangapple
  • 本文由 发表于 2023年7月12日 21:05:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/76670903.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定