orasql过程中的多个FORALL
我试图在一个过程中删除然后更新表中的一些数据。我的理解是,不能在同一个FORALL语句中同时执行这两个操作,我可以使用同一个游标执行多个FORALL。问题是,第二个FORALL似乎什么都没做。有什么我没有得到的吗?代码如下:orasql过程中的多个FORALL,sql,oracle,loops,procedure,forall,Sql,Oracle,Loops,Procedure,Forall,我试图在一个过程中删除然后更新表中的一些数据。我的理解是,不能在同一个FORALL语句中同时执行这两个操作,我可以使用同一个游标执行多个FORALL。问题是,第二个FORALL似乎什么都没做。有什么我没有得到的吗?代码如下: cursor cPARTY is SELECT /* +parallel(4) */ DISTINCT p.ID, CASE WHEN sf.PARTYID is null THEN 'delete' ELSE 'switch' END AS
cursor cPARTY is
SELECT /* +parallel(4) */ DISTINCT p.ID,
CASE WHEN sf.PARTYID is null THEN 'delete'
ELSE 'switch'
END AS action,
pa.SOURCESYSTEMLID as sources
FROM CV_CLAIMS_TRAVEL.EPUR_PARTY p
LEFT JOIN CV_CLAIMS_TRAVEL.STAR_FILE sf ON sf.PARTYID = p.ID
LEFT JOIN CV_CLAIMS_TRAVEL.PARTY pa ON pa.ID = p.ID;
type type_party is TABLE OF cPARTY%ROWTYPE INDEX BY PLS_INTEGER;
t_party type_party;
nLOT pls_integer := 1;
nbDeleted int :=0;
nbSwitched int := 0;
begin
p_tableName := 'PARTY(INDIVIDU)';
allBEGIN_TIMESTAMP := systimestamp;
open cPARTY;
loop
lotBEGIN_TIMESTAMP := systimestamp;
dbms_application_info.set_module('CV_CLAIMS_TRAVEL.PARTY',trim(to_char(nLOT * nLIMIT,'999G999G999')));
FETCH cPARTY BULK COLLECT
INTO t_party
limit nLIMIT;
exit when t_party.count = 0;
p_nbLinesTransfered :='Erreur: Suppression de données';
dbms_application_info.set_module('CV_CLAIMS_TRAVEL.PARTY - DELETING',trim(to_char(nLOT * nLIMIT,'999G999G999')));
FORALL i IN t_party.FIRST .. t_party.LAST
DELETE /*+parallel(4)*/ FROM CV_CLAIMS_TRAVEL.PARTY
WHERE ID = t_party(i).ID
AND t_party(i).action = 'delete';
nbDeleted := nbDeleted + sql%rowcount;
FORALL i IN t_party.FIRST .. t_party.LAST
UPDATE CV_CLAIMS_TRAVEL.PARTY
SET UPDATEDATE = sysdate, SOURCESYSTEMLID = 'SOURCE_SYSTEM:0000000000', UPDATEDBYUSERID = 'CV_CLAIM_INTEG'
WHERE ID = t_party(i).ID
AND t_party(i).sources='SOURCE_SYSTEM:0000000004'
AND t_party(i).action = 'switch';
nbSwitched := nbSwitched + sql%rowcount;
commit;
lotEND_TIMESTAMP :=systimestamp;
trc.trc_message('lotELAPSED '||to_char(nLOT * nLIMIT,'999G999G990')||' Rows. ELAPSED '|| replace(substr(to_char(lotEND_TIMESTAMP - lotBEGIN_TIMESTAMP, 'HH24:MI:SS.FF3'),1,20),'+000000 ','+'));
nLOT := nLOT + 1;
end loop;
close cPARTY;
commit;
gather_stats('CV_CLAIMS_TRAVEL', 'PARTY');
您应该从运行驱动光标的SQL开始,并查看是否确实有任何符合更新条件的记录。另外,您维护一些计数,但不使用它们(至少在您发布的代码片段中)。你应该将它们包含在跟踪输出消息中,这样你就可以看到发生了什么。我确实运行了游标的SQL,每个结果都是switch(我非常怀疑它应该是),但是只有删除部分发生,技术上不应该发生。更新包含以下条件:
和t_party(I)。sources='SOURCE\u SYSTEM:0000000004'
。但是在源代码查询中,您正在执行左联接,因此列pa.SOURCESYSTEMLID as sources
可能不同于此字符串“source\u SYSTEM:0000000004”
,也可能为空。在这种情况下,更新不会更新任何内容。这很好,因为如果pa.SOURCESYSTEMLID为null,那么我不想碰它。但我不明白的是,为什么我的行为总是切换?