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
- Documentação oficial da Oracle sobre o erro
- PL/SQL ORACLE ERROR : PLS-00225 in my Code – Códigos de exemplo