Oracle PL SQL过程don';t工作(可能是光标故障)

Oracle PL SQL过程don';t工作(可能是光标故障),oracle,stored-procedures,plsql,Oracle,Stored Procedures,Plsql,我从PL/SQL开始,这是我的第一个过程,我很难让它工作 我觉得光标有问题。如果你看我的代码有四条注释;我已经测试了这四个更新,但只有一个工作!我确信这两个SELECT是有效的,因为如果我在输入中发送了错误的参数,SELECT不会给出结果 在这四条评论中,我希望它能起作用: UPDATE partecipa SET punti= somma WHERE ( (nomesquadra= nomesquadr) AND (nometorneo= nometorn));

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

调用游标的
for
循环会为每个循环自动获取一次行。不允许在循环中添加
fetch

您没有看到
ORA-01001:invalid cursor
错误这一事实表明您从未到达循环的内部:
formazioni_di_giornata
光标不能返回任何行



另一方面,我强烈建议您不要使用
exception
子句。它所做的只是向错误消息中添加垃圾。

for循环调用游标,为每个循环自动获取一次行。不允许在循环中添加
fetch

您没有看到
ORA-01001:invalid cursor
错误这一事实表明您从未到达循环的内部:
formazioni_di_giornata
光标不能返回任何行



另一方面,我强烈建议您不要使用
exception
子句。它所做的只是将垃圾添加到错误消息中。

我建议您重写您的过程:

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_行就是为了演示这一点。如果您没有看到任何这些行打印,您可能需要考虑查看输入到该过程的值。


分享和享受。

我建议您重新编写您的程序:

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_行就是为了演示这一点。如果您没有看到任何这些行打印,您可能需要考虑查看输入到该过程的值。

分享和享受