我是从PL / SQL开始的,这是我的第一个程序,让我无法工作。
我用光标问题(思考)。如果你看我的代码是四条评论;我已经测试了这四个更新,但只有一个工作!并且我确定两个SELECT工作,因为如果我在输入中发送了错误的参数,那么select就不会给出结果。
在这四条评论中,我希望它有用:UPDATE partecipa
SET punti= somma
WHERE ( (nomesquadra= nomesquadr) AND
(nometorneo= nometorn));
如果还有其他错误(也是合乎逻辑的)请告诉我。我想改进。
谢谢大家的答案
我的程序:
create or replace PROCEDURE calcola_giorn (giornata IN INTEGER) IS
-- si tenga presente che in realtà giornata=idPartita
somma NUMBER;
idcal NUMBER;
nometorn VARCHAR2(100);
idformaz NUMBER;
nomesquadr VARCHAR2(100);
CURSOR formazioni_di_giornata IS
SELECT id, nomesquadra FROM formazione where idpartita= giornata;
CURSOR giocatori_di_giornata IS
SELECT votogiocatore FROM schiera WHERE idformazione= idformaz;
Begin
SELECT idcalendario
INTO idcal
FROM partita
WHERE id= giornata;
SELECT nometorneo
INTO nometorn
FROM calendario
WHERE id= idcal;
FOR tupla_formazione IN formazioni_di_giornata LOOP
somma:=0;
FETCH formazioni_di_giornata INTO idformaz, nomesquadr;
FOR tupla_giocatore IN giocatori_di_giornata LOOP
somma:= somma + tupla_giocatore.votogiocatore;
/*DON'T WORK*/-- UPDATE partecipa SET punti= 123;
END LOOP;
/*WORK*/-- UPDATE partecipa SET punti= 12;
/*DON'T WORK*/-- UPDATE partecipa SET punti= 123 WHERE ( (nomesquadra= nomesquadr) AND (nometorneo= nometorn));
/*DON'T WORK*/-- UPDATE partecipa SET punti= somma WHERE ( (nomesquadra= nomesquadr) AND (nometorneo= nometorn));
END LOOP;
EXCEPTION
WHEN OTHERS THEN
raise_application_error(-20001, 'An error was encountered - ' ||
SQLCODE||' -ERROR- '||SQLERRM);
END;
答案 0 :(得分:2)
调用游标的for
循环会自动为每个循环提取一次行。您在循环中添加的fetch
是不允许的。
您没有看到ORA-01001: invalid cursor
错误这一事实表明您永远不会进入循环内部:formazioni_di_giornata
游标不得返回任何行。
顺便说一句,我强烈建议您删除您正在使用的exception
条款。它所做的只是在错误信息中添加垃圾。
答案 1 :(得分:2)
我建议你改写你的程序:
create or replace PROCEDURE calcola_giorn (giornata IN INTEGER) IS
-- si tenga presente che in realtà giornata=idPartita
somma NUMBER;
nometorn VARCHAR2(100);
nOuter_cursor_rows_fetched NUMBER := 0;
Begin
SELECT c.NOMETORNEO
INTO nometorn
FROM PARTITA p
INNER JOIN CALENDARIO c
ON c.ID = p.IDCALENDARIO
WHERE p.ID = giornata;
FOR tupla_formazione IN (SELECT id, nomesquadra
FROM formazione
where idpartita = giornata)
LOOP
DBMS_OUTPUT.PUT_LINE('Inside outer loop, FORMAZIONE.ID=' ||
tupla_formazione.ID);
nOuter_cursor_rows_fetched := nOuter_cursor_rows_fetched + 1;
somma := 0;
FOR tupla_giocatore IN (SELECT votogiocatore
FROM schiera
WHERE idformazione = tupla_formazione.nomesquadra)
LOOP
somma := somma + tupla_giocatore.votogiocatore;
-- The following statement will set PUNTI to 123 on every row in
-- PARTECIPA - are you sure this is what you wanted to do?
UPDATE partecipa SET punti= 123;
END LOOP;
-- The following statement will set PUNTI to 12 on every row in
-- PARTECIPA - are you sure this is what you wanted to do?
UPDATE partecipa SET punti= 12;
UPDATE partecipa
SET punti = 123
WHERE nomesquadra= tuplafomazione.nomesquadra AND
nometorneo = nometorn;
UPDATE partecipa
SET punti = somma
WHERE nomesquadra = tupla_formazione.nomesquadr AND
nometorneo = nometorn;
END LOOP;
DBMS_OUTPUT.PUT_LINE('# rows fetched by outer cursor=' ||
nOuter_cursor_rows_fetched);
EXCEPTION
WHEN OTHERS THEN
raise_application_error(-20001, 'Error: SQLCODE=' ||
SQLCODE||' SQLERRM='''||SQLERRM || '''');
ROLLBACK;
RAISE;
END calcola_giorn;
我相信@Allan必须是正确的,并且永远不会输入外部循环(tupla_formazione
)。此循环顶部的DBMS_OUTPUT.PUT_LINE用于演示此操作。如果您没有看到任何这些行打印,您可能需要考虑查看输入到该过程的值。
分享并享受。