2017-03-13 7 views
0

カーソルで選択クエリのc_msisdn値を使用しようとしていますが、データが見つかりませんでしたが、WHERE MSISDN = '315XXX' WHERE 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; 

答えて

1

あなたsinglesubscriptionテーブルに存在しない、あなたのssm_smscdataテーブル内のMSISDN値を持っているので、あなたがNO_DATA_FOUND例外を取得している理由は、最も可能性の高い理由があります。

私があなただったら、ループのカーソルを使用しても構いません。代わりに、私はそうのように、単一の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表に表示される行の厄介な問題は回避されますが、単一サブスクリプションではないため、その行は戻されません。これらの行も返す必要がある場合は、上記クエリのINNER JOINOUTER JOINに変換する必要があります。

関連する問題