Oracle11g 如何在过程中的Select查询中使用当前光标值

Oracle11g 如何在过程中的Select查询中使用当前光标值,oracle11g,cursor,Oracle11g,Cursor,我试图在游标中使用c_msisdn值进行select查询,但它给出了找不到数据的错误,然而,如果我自己提供值,比如msisdn='315XXX',而不是返回msisdn=c_msisdn结果。如何在select中使用光标值 DECLARE c_msisdn SSM_SMSCDATA.MSISDN%type; c_status SSM_SMSCDATA.STATUS%type; c_promo_id SSM_SMSCDATA.PROMO_ID%type; view_all_status char(

我试图在游标中使用c_msisdn值进行select查询,但它给出了找不到数据的错误,然而,如果我自己提供值,比如msisdn='315XXX',而不是返回msisdn=c_msisdn结果。如何在select中使用光标值

DECLARE
c_msisdn SSM_SMSCDATA.MSISDN%type;
c_status SSM_SMSCDATA.STATUS%type;
c_promo_id SSM_SMSCDATA.PROMO_ID%type;
view_all_status char(50) := '';
unsub_all_status char(50) := '';
services_subscribed char(400) := '';
CURSOR c_smscdata is SELECT MSISDN, STATUS, PROMO_ID FROM SSM_SMSCDATA; 

BEGIN 
OPEN c_smscdata; 
LOOP 
FETCH c_smscdata into c_msisdn, c_status, c_promo_id;

SELECT SUBSCRIPTION_ID into services_subscribed FROM (SELECT LISTAGG(SUBSCRIPTION_ID, '-') WITHIN GROUP (ORDER BY MSISDN) AS SUBSCRIPTION_ID
FROM   SINGLESUBSCRIPTION
WHERE MSISDN = c_msisdn
GROUP BY MSISDN);

IF c_promo_id = '2' THEN 
  view_all_status := 'View All';
   ELSE view_all_status := 'Unsub All';
END IF;

IF c_status = 3 THEN 
  unsub_all_status := 'View Successful';
   ELSE unsub_all_status := 'Unsuccessful';
END IF;


INSERT INTO SSM_DAILY_REPORT (msisdn,view_all,unsub_all,SERVICES)
VALUES (c_msisdn,view_all_status,unsub_all_status,services_subscribed);

--dbms_output.put_line(c_msisdn || ' ' || c_status || ' ' || c_promo_id); 

EXIT 
WHEN c_smscdata%notfound; 
END LOOP; 
CLOSE c_smscdata; 

END;

获取“未找到数据”异常的最可能原因是,ssm\U smscdata表中的msisdn值不在singlesubscription表中

如果我是你的话,我就不会麻烦使用游标进行循环了。相反,我会在一个INSERT语句中完成这一切,如下所示:

INSERT INTO ssm_daily_report (msisdn, view_all, unsub_all, services)
SELECT scs.msisdn,
       CASE WHEN scs.promo_id = '2' THEN 'View All';
            ELSE 'Unsub All'
       END view_all_status,
       CASE WHEN scs.status = 3 THEN 'View Successful';
            ELSE 'Unsuccessful'
       END unsub_all_status,
       sss.services_subscribed
FROM   ssmsmscdata scs 
       INNER JOIN (SELECT msisdn,
                          LISTAGG(subscription_id, '-') WITHIN GROUP (ORDER BY msisdn) AS services_subscribed
                   FROM   singlesubscription
                   GROUP BY msisdn) sss ON sss.msisdn = scs.msisdn;
这样,就可以避免重新创建嵌套循环联接(让Oracle自由选择它认为最好使用的联接类型,它可能是嵌套循环,也可能不是嵌套循环)。您还可以避免光标循环涉及的所有上下文切换和逐行处理,让Oracle一次性完成所有工作

另外,通过执行内部联接,您可以避免出现在ssm_smscdata表中但不在singlesubscription中的行的棘手问题,因为这些行不会返回。如果还需要返回这些行,则需要将上面查询中的
内部联接
转换为
外部联接