如何在过程中使用 Select 查询中的当前游标值
How to use current cursor value in Select query with in procedure
我正在尝试使用游标中的 c_msisdn 值进行 select 查询,但它给出了未找到数据的错误,但是如果我自己提供值,例如 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;
您收到 NO_DATA_FOUND 异常的最可能原因是您的 ssm_smscdata table 中有 msisdn 值,而这些值在您的单一订阅中不存在 table.
如果我是你,我不会为循环使用游标而烦恼。相反,我会在单个 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 table 而不是单一订阅中的行的棘手问题,因为这些行不会被返回。如果您还需要返回这些行,则需要将上面查询中的 INNER JOIN
转换为 OUTER JOIN
.
我正在尝试使用游标中的 c_msisdn 值进行 select 查询,但它给出了未找到数据的错误,但是如果我自己提供值,例如 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;
您收到 NO_DATA_FOUND 异常的最可能原因是您的 ssm_smscdata table 中有 msisdn 值,而这些值在您的单一订阅中不存在 table.
如果我是你,我不会为循环使用游标而烦恼。相反,我会在单个 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 table 而不是单一订阅中的行的棘手问题,因为这些行不会被返回。如果您还需要返回这些行,则需要将上面查询中的 INNER JOIN
转换为 OUTER JOIN
.