Pular para o conteúdo

Erro PLS-00225: Uma Comédia de Erros

Erro PLS-00225: Uma Comédia de Erros

Imagine que você está escrevendo um script PL/SQL e de repente, bam!, você se depara com o erro PLS-00225. O Oracle, com seu senso de humor peculiar, diz: “subprograma ou cursor ‘string’ referência está fora do escopo”. Mas o que isso realmente significa?

Bem, é como se você estivesse tentando chamar seu amigo que está em outra cidade sem usar um telefone. Não vai funcionar, certo? No PL/SQL, isso acontece quando você tenta acessar algo que não está ao seu alcance, ou melhor, fora do escopo do seu bloco de código atual.

Causa do Erro

O erro PLS-00225 ocorre quando você usa um nome qualificado cujo prefixo é um subprograma ou cursor que não está em um escopo envolvente. Em outras palavras, você está tentando acessar uma entidade dentro de um subprograma ou cursor que simplesmente não está disponível onde você está tentando acessá-lo.

Exemplos Práticos

Vamos ver um exemplo do que não fazer:

declare
  x number;
  type t1 is record (a number);
  function f return t1 is
  begin
    -- Alguma lógica aqui...
  end;
begin
  x := f.a; -- Uso ilegal da função 'f' como qualificador de escopo
end;

E agora, o jeito correto de fazer:

declare
  x number;
  type t1 is record (a number);
  function f return t1 is
  begin
    -- Alguma lógica aqui...
  end;
begin
  x := f().a; -- Referência legal ao componente 'a' do registro retornado
end;
Outro Exemplo Prático: O Caso do Cursor Curioso

Vamos imaginar que você está criando uma stored procedure e decide usar um cursor para processar algumas linhas. Mas, oh não! Você se depara com o erro PLS-00225. É como se o Oracle estivesse dizendo: “Ei, você não pode usar isso aqui!”.

Aqui está o que você não deve fazer:

CREATE OR REPLACE PROCEDURE pr_MigrateSubOrders AS
  CURSOR BCM_cursor IS SELECT * FROM XXBCM_ORDER_MGT WHERE ORDER_REF LIKE '%-%';
  v_current_max NUMBER;
  r_current_row XXBCM_ORDER_MGT%ROWTYPE;
BEGIN
  OPEN BCM_cursor;
  FETCH BCM_cursor INTO r_current_row;
  WHILE BCM_cursor%NOTFOUND != FALSE LOOP
    SELECT MAX(TO_NUMBER(regexp_replace(IDSUBORDER, '.*- (.*)','\\1')))
    INTO v_current_max
    FROM SUBORDERS
    WHERE IDSUBORDER LIKE regexp_replace(BCM_cursor.ORDER_REF, ' (.*)-.*','\\1') || '%';
    -- Oops! O erro PLS-00225 aparece aqui porque BCM_cursor.ORDER_REF está fora do escopo.
    IF v_current_max IS NULL THEN
      v_current_max := 1;
    ELSE
      v_current_max := v_current_max + 1;
    END IF;
    DBMS_OUTPUT.PUT_LINE(v_current_max);
    FETCH BCM_cursor INTO r_current_row;
  END LOOP;
  CLOSE BCM_cursor;
END;

Resultado

SQL> SET SERVEROUTPUT ON;
SQL> EXEC pr_MigrateSubOrders;
Erro na linha 1:
ORA-06550: linha 7, coluna 5:
PLS-00225: subprograma ou cursor 'string' referência está fora do escopo
ORA-06550: linha 7, coluna 5:
PL/SQL: Statement ignored

E agora, a maneira correta de fazer isso:

CREATE OR REPLACE PROCEDURE pr_MigrateSubOrders AS
  CURSOR BCM_cursor IS SELECT * FROM XXBCM_ORDER_MGT WHERE ORDER_REF LIKE '%-%';
  v_current_max NUMBER;
  r_current_row XXBCM_ORDER_MGT%ROWTYPE;
BEGIN
  OPEN BCM_cursor;
  LOOP
    FETCH BCM_cursor INTO r_current_row;
    EXIT WHEN BCM_cursor%NOTFOUND;
    SELECT MAX(TO_NUMBER(regexp_replace(IDSUBORDER, '.*- (.*)','\\1')))
    INTO v_current_max
    FROM SUBORDERS
    WHERE IDSUBORDER LIKE regexp_replace(r_current_row.ORDER_REF, ' (.*)-.*','\\1') || '%';
    -- Agora está correto! Usamos r_current_row.ORDER_REF, que está no escopo.
    v_current_max := NVL(v_current_max, 0) + 1;
    DBMS_OUTPUT.PUT_LINE(v_current_max);
  END LOOP;
  CLOSE BCM_cursor;
END;

Resultado

SQL> SET SERVEROUTPUT ON;
SQL> EXEC pr_MigrateSubOrders;

2
3
4
5
6
7
8
9
10
11
12

PL/SQL procedure successfully completed.

SQL>

Neste exemplo, corrigimos o erro PLS-00225 ao garantir que a referência ao campo ORDER_REF estava dentro do escopo correto, ou seja, dentro do loop onde o cursor BCM_cursor foi realmente buscado.

Conclusão

Lidar com erros pode ser frustrante, mas com uma pitada de humor e compreensão do que está acontecendo nos bastidores, você pode transformar esses momentos em oportunidades de aprendizado. E lembre-se, quando o Oracle falar que algo está fora do escopo, não leve para o lado pessoal, ele só está tentando ajudar!

Referências

Natanael Freitas

Natanael Freitas

E aí, pessoal! Sou o Natanael Freitas, o cara que curte desbravar o mundo do PL/SQL. Não sou nenhum expert, mas me viro bem nas linhas de código desse universo. A verdade é que sou mais íntimo de bancos de dados do que de muitas pessoas por aí – sério! Quando não tô quebrando a cabeça com triggers e stored procedures, tô por aí fuçando a web em busca de tudo que é novidade nesse mundão tech. Às vezes, me pego dando uma aula rápida sobre PL/SQL pros colegas, na tentativa de descomplicar essa coisa toda. Meu dia a dia é basicamente sorrisos, café (sim, sou desses que não larga a caneca!) e resolvendo problemas nos códigos. Não sou nenhum Picasso, mas acho que consigo fazer umas artes por aí. Então, se precisar de ajuda com PL/SQL ou só quiser bater um papo sobre o assunto, tamo aí!

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

plugins premium WordPress