PL SQL程序不起作用(可能是游标错误)

时间:2014-06-06 19:38:57

标签: oracle stored-procedures plsql

我是从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;

2 个答案:

答案 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用于演示此操作。如果您没有看到任何这些行打印,您可能需要考虑查看输入到该过程的值。

分享并享受。