Bem-vindo à Aula 19 do nosso curso Oracle SQL — Do Zero ao Avançado. Hoje vamos mergulhar em um dos recursos mais poderosos e subestimados da linguagem procedural da Oracle: as Packages PL/SQL. Se você já escreveu procedures e funções avulsas — provavelmente nas aulas anteriores do curso — percebeu que, à medida que o sistema cresce, a desorganização se torna um gargalo. As Packages PL/SQL resolvem exatamente esse problema, permitindo agrupar lógicas relacionadas em uma única unidade coesa, promovendo encapsulamento, manutenibilidade e performance. No dia a dia de produção, em nossos projetos na JRT Technology Solutions, não há sistema corporativo Oracle que não empregue packages como base arquitetural. Elas são o padrão de mercado e, a partir de hoje, serão o seu padrão também.
Nesta aula, você vai deixar de enxergar o código PL/SQL como um conjunto solto de blocos anônimos e subprogramas independentes. Vai aprender a desenhar uma verdadeira API de banco de dados, utilizando os conceitos de especificação (specification) e corpo (body), ocultando detalhes de implementação, gerenciando estado de sessão com variáveis persistentes e aplicando as melhores práticas para evitar os erros campeões de compilação. Tudo será mostrado com exemplos reais, testáveis e explicados linha por linha, para que você possa replicar imediatamente no seu ambiente.
Para profissionais de TI, segurança da informação e infraestrutura que administram bases Oracle, entender Packages PL/SQL é tão fundamental quanto saber otimizar uma consulta. Diversos módulos avançados, como Oracle Data Pump, DBMS_SCHEDULER e OLS (Oracle Label Security), são implementados como packages nativas. Conhecendo a estrutura e o comportamento delas, você auditará código com mais facilidade, entenderá logs internos e até criará extensões customizadas de segurança. Do ponto de vista do desenvolvedor, a aula pavimenta o caminho para arquiteturas MVC dentro do banco, reduzindo o tráfego de rede e centralizando regras de negócio.
Ao final desta aula, você terá construído do zero uma package completa, com funções, procedures e variáveis globais, e saberá testá-la passo a passo. Discutiremos armadilhas como o temido erro ORA-04068 de estado descartado de package, e você sairá apto a definir quando usar packages em vez de subprogramas soltos. Preparado? Abra seu SQL*Plus, SQL Developer ou ferramenta preferida e acompanhe cada bloco de código.
O que você vai aprender nesta aula
- O conceito de encapsulamento e como Packages PL/SQL implementam a separação entre interface pública e implementação privada.
- A sintaxe completa de criação:
CREATE PACKAGEeCREATE PACKAGE BODY, com detalhamento de cada cláusula. - Como compilar, depurar e manter packages sem invalidar objetos dependentes.
- Uso de variáveis e cursores no nível da package (package-level variables) para gerenciar estado de sessão.
- Como chamar subprogramas encapsulados de dentro de outras unidades PL/SQL ou diretamente do SQL (quando aplicável).
- Diferenças práticas entre funções definidas em packages e funções standalone — impacto em performance e assinatura.
- Erros comuns na compilação de corpo de package e como solucioná-los rapidamente.
- Quando usar packages com
AUTHID DEFINERvsAUTHID CURRENT_USERe as implicações de segurança. - Boas práticas adotadas em projetos reais da JRT Technology Solutions para versionamento e documentação de packages.
Pré-requisitos e Ambiente
Para executar todos os exemplos sem percalços, você precisa de acesso a um banco de dados Oracle 11g ou superior — recomendamos 19c ou 21c, mas a sintaxe fundamental não muda desde o Oracle 8i. É essencial que você já tenha familiaridade com blocos anônimos PL/SQL, procedures e funções, assunto coberto nas aulas 16 a 18 do nosso curso. Você também saberá interpretar mensagens de erro da ferramenta que estiver usando, seja SQL*Plus, SQL Developer ou VS Code com extensão Oracle.
Certifique-se de ter privilégios CREATE PROCEDURE e CREATE PACKAGE (ambos fazem parte da role RESOURCE na maioria dos ambientes de desenvolvimento). Vamos trabalhar com o schema de demonstração HR ou você pode criar seu próprio schema de testes. Se estiver utilizando o Oracle XE, todas as funcionalidades aqui demonstradas são suportadas.
Em nossos treinamentos na JRT Technology Solutions, recomendamos que cada aluno configure um diretório de scripts com controle de versão antes mesmo de iniciar a aula. Assim, ao longo do capítulo, você salvará os scripts .sql da especificação e do corpo da package, aprendendo na prática como versionar código de banco de dados.
O que são Packages PL/SQL? — Conceito Fundamental
Uma package PL/SQL é um contêiner lógico que agrupa tipos, variáveis, cursores, exceções e subprogramas (procedures e funções) relacionados logicamente. Pense nela como uma biblioteca ou módulo em outras linguagens de programação: você expõe uma interface pública (o que os outros podem acessar) e oculta os detalhes de implementação no corpo. Essa arquitetura traz benefícios imediatos de organização e desempenho, porque, quando a package é carregada pela primeira vez na memória da sessão, todos os seus subprogramas são compilados e mantidos em cache, reduzindo chamadas subsequentes.
Ao contrário de procedures standalone, as Packages PL/SQL são divididas em duas partes obrigatórias: especificação e corpo. A especificação declara tudo que é público: protótipos de funções e procedimentos, variáveis globais, cursores e exceções que podem ser referenciados externamente. O corpo contém o código-fonte real desses subprogramas, além de elementos privados que ninguém de fora da package enxerga. Isso significa que você pode alterar a lógica interna do corpo sem impactar quem chama os métodos públicos — desde que a assinatura permaneça a mesma.
Outra propriedade fundamental é o estado de sessão. Diferentemente de uma procedure isolada, que não retém valores entre chamadas, uma package pode conter variáveis no nível do pacote que mantêm o valor ao longo de toda a sessão do usuário. Esse estado é preservado até que a sessão seja encerrada ou a package seja recompilada. Esse comportamento é uma faca de dois gumes: útil para cache de dados, mas fonte do erro ORA-04068 quando o estado é descartado por uma recompilação inesperada.
No contexto de segurança da informação, packages permitem conceder privilégios de execução sem expor tabelas subjacentes, implementando o princípio de privilégio mínimo. Por exemplo, é possível criar uma package PKG_SEGURANCA com uma procedure ATUALIZAR_SENHA que executa com os privilégios do dono da package (AUTHID DEFINER), evitando que usuários finais tenham acesso direto à tabela de senhas. Discutiremos isso em detalhes mais adiante.
Anatomia de uma Package PL/SQL — Especificação e Corpo
Vamos destrinchar a sintaxe formal. A criação de uma package inicia-se obrigatoriamente pela especificação, usando o comando CREATE OR REPLACE PACKAGE. Dentro dela, não há blocos BEGIN...END executáveis — apenas declarações. O formato genérico é:
CREATE OR REPLACE PACKAGE nome_da_package AS
-- Declaração de variáveis públicas
-- Declaração de tipos (records, collections)
-- Declaração de cursores públicos
-- Declaração de exceções nomeadas
-- Protótipos de procedures e funções
END nome_da_package;
/
O caracter / é obrigatório em ferramentas como SQL*Plus para executar o bloco. Após criar a especificação, criamos o corpo usando CREATE OR REPLACE PACKAGE BODY. O corpo deve conter a implementação de todos os subprogramas declarados na especificação, podendo também incluir elementos privados:
CREATE OR REPLACE PACKAGE BODY nome_da_package AS
-- Variáveis e subprogramas PRIVADOS (não aparecem na especificação)
-- Implementação da procedure X
PROCEDURE nome_procedure(param1 tipo) IS
BEGIN
-- código
END nome_procedure;
-- Implementação da função Y
FUNCTION nome_funcao(param1 tipo) RETURN tipo IS
BEGIN
-- código
RETURN valor;
END nome_funcao;
-- Bloco de inicialização opcional
BEGIN
-- Código executado uma única vez quando a package é carregada
END nome_da_package;
/
O bloco opcional de inicialização, localizado após todos os subprogramas, é executado apenas uma vez por sessão, no momento em que qualquer elemento da package é acessado pela primeira vez. Isso é extremamente útil para pré-carregar cache, abrir arquivos ou inicializar variáveis globais com valores oriundos de tabelas de configuração.
Uma regra de ouro: a especificação e o corpo podem ser recompilados independentemente, desde que a assinatura pública não mude. Se você adicionar um novo subprograma público à especificação e o corpo ainda não o implementar, a package ficará inválida. Se remover um subprograma da especificação, mas ele ainda existir no corpo, a compilação do corpo falhará. A ferramenta de compilação verificará a consistência entre ambos.
Criando sua Primeira Package PL/SQL — Passo a Passo Completo
Vamos implementar uma package de gerenciamento de funcionários, PKG_RH, que conterá uma função para calcular o salário anual com bônus, uma procedure para reajustar salários por percentual e uma variável global que registra o último departamento consultado. O cenário é baseado na tabela EMPLOYEES do schema HR, que assumimos existente e populada. Se você estiver em um schema limpo, adapte a tabela ou execute os scripts de exemplo do Oracle.
- Conecte-se ao banco com seu usuário de desenvolvimento (ex.:
HRouDEV). - Crie a especificação
PKG_RHlistando os elementos públicos necessários. - Compile e verifique o status da especificação.
- Crie o corpo
PKG_RHcom a implementação completa. - Compile e veja se o corpo ficou válido.
- Teste cada subprograma a partir de um bloco anônimo ou SQL.
Iniciamos pela especificação. Execute o script abaixo:
-- Arquivo: 001_criar_spec_pkg_rh.sql
CREATE OR REPLACE PACKAGE PKG_RH AS
-- Variável pública que armazena o ID do último departamento acessado
g_ultimo_dept_id employees.department_id%TYPE;
-- Função que retorna o salário anual com bônus configurável
FUNCTION salario_anual(
p_employee_id IN employees.employee_id%TYPE,
p_pct_bonus IN NUMBER DEFAULT 0
) RETURN NUMBER;
-- Procedure que aplica reajuste percentual a todos os funcionários de um depto
PROCEDURE reajustar_salario_departamento(
p_department_id IN employees.department_id%TYPE,
p_percentual IN NUMBER
);
END PKG_RH;
/
Observações sobre cada elemento:
- g_ultimo_dept_id: prefixo
g_é uma convenção para variável global. Ela será visível e modificável por qualquer usuário que execute a package, durante a sessão. - salario_anual: função com parâmetro opcional
p_pct_bonus. Note que não háBEGIN...ENDaqui, porque estamos apenas na especificação. - reajustar_salario_departamento: procedure que modifica dados em massa; apenas o protótipo é mostrado.
Ao executar, a saída esperada é:
Package created.
ou, no SQL Developer, uma mensagem similar no Script Output. Agora verificamos o status:
SELECT object_name, object_type, status
FROM user_objects
WHERE object_name = 'PKG_RH';
Saída esperada (ainda sem corpo):
OBJECT_NAME OBJECT_TYPE STATUS
------------- ------------- -------
PKG_RH PACKAGE VALID
Agora vamos ao corpo. A implementação deve corresponder exatamente à especificação, inclusive tipos dos parâmetros e ordem.
-- Arquivo: 002_criar_body_pkg_rh.sql
CREATE OR REPLACE PACKAGE BODY PKG_RH AS
-- Variável privada para contar operações de reajuste (uso interno)
v_total_reajustes INTEGER := 0;
-- Implementação da função salario_anual
FUNCTION salario_anual(
p_employee_id IN employees.employee_id%TYPE,
p_pct_bonus IN NUMBER DEFAULT 0
) RETURN NUMBER IS
v_salary employees.salary%TYPE;
v_commission employees.commission_pct%TYPE;
v_anual NUMBER(12,2);
BEGIN
-- Obtém salário e comissão do empregado
SELECT salary, commission_pct
INTO v_salary, v_commission
FROM employees
WHERE employee_id = p_employee_id;
-- Cálculo: salario * 12 + comissão opcional + bônus percentual
v_anual := v_salary * 12;
IF v_commission IS NOT NULL THEN
v_anual := v_anual + (v_salary * v_commission);
END IF;
v_anual := v_anual * (1 + NVL(p_pct_bonus, 0) / 100);
RETURN ROUND(v_anual, 2);
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN NULL; -- empregado não encontrado
END salario_anual;
-- Implementação da procedure reajustar_salario_departamento
PROCEDURE reajustar_salario_departamento(
p_department_id IN employees.department_id%TYPE,
p_percentual IN NUMBER
) IS
v_antes NUMBER;
v_depois NUMBER;
BEGIN
-- Atualiza a variável global com o departamento atual
g_ultimo_dept_id := p_department_id;
-- Reajusta salários com tratamento de arredondamento
UPDATE employees
SET salary = ROUND(salary * (1 + p_percentual / 100), 2)
WHERE department_id = p_department_id;
-- Incrementa contador privado
v_total_reajustes := v_total_reajustes + SQL%ROWCOUNT;
COMMIT;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
RAISE;
END reajustar_salario_departamento;
-- Bloco de inicialização da package
BEGIN
-- Inicializa a variável global com valor nulo por segurança
g_ultimo_dept_id := NULL;
DBMS_OUTPUT.PUT_LINE('Package PKG_RH inicializada.');
END PKG_RH;
/
Detalhamento linha a linha do corpo:
- v_total_reajustes: variável privada, invisível fora da package. Bom para auditoria interna.
- Função salario_anual: usa
SELECT...INTOpara carregar dados. Note o tratamento deNO_DATA_FOUNDretornandoNULL. - Procedure reajustar_salario_departamento: antes de atualizar, grava o departamento na variável global. Após o UPDATE, usamos
SQL%ROWCOUNTpara contar linhas afetadas. A transação é controlada explicitamente comCOMMIT— em sistemas reais, o controle transacional pode ficar fora da package, mas aqui é didático. - Bloco BEGIN final: inicializa a variável global e emite uma mensagem; essa mensagem aparecerá apenas uma vez, quando a package for carregada pela primeira vez na sessão.
Saída da compilação do corpo:
Package Body created.
Verifique novamente os objetos:
SELECT object_name, object_type, status
FROM user_objects
WHERE object_name = 'PKG_RH';
Espera-se:
OBJECT_NAME OBJECT_TYPE STATUS
------------- ------------- -------
PKG_RH PACKAGE VALID
PKG_RH PACKAGE BODY VALID
Vantagens do Encapsulamento com Packages PL/SQL — Por que sua Equipe Deve Usar?
Em projetos críticos na JRT Technology Solutions, a decisão de empregar Packages PL/SQL em vez de subprogramas avulsos é mandatória por várias razões. Primeiro, a organização lógica: imagine 200 procedures flutuando no schema; encontrar a correta se torna caótico. Agrupando-as por domínio (RH, Financeiro, Segurança), você transforma o banco em um catálogo navegável, similar a namespaces de Python ou Java.
Segundo, o encapsulamento real: escondendo detalhes internos no corpo, você pode alterar a lógica de uma procedure sem jamais recompilar a especificação ou os objetos que chamam a package. Isso reduz o efeito cascata de invalidações no banco, um pesadelo em ambientes com milhares de dependências.
Terceiro, gerenciamento de estado único: em processos batch que precisam acumular métricas ou cache durante a execução, variáveis de pacote permitem compartilhar informações sem precisar de tabelas temporárias. Por exemplo, um contador de registros processados pode ser incrementado por várias procedures internas e lido no final do processo.
Quarto, melhoria de performance: quando qualquer elemento de uma package é referenciado, todo o corpo é carregado para a memória SGA (Shared Global Area). Isso significa que chamadas subsequentes a outros subprogramas da mesma package não sofrem nova carga de disco. Em cenários com alta concorrência, essa estratégia de “load once, execute many” faz diferença significativa.
Quinto, segurança refinada: você pode conceder EXECUTE apenas na package inteira, em vez de gerenciar permissões para dezenas de objetos individuais. Usando a cláusula AUTHID DEFINER (padrão) ou AUTHID CURRENT_USER, você define exatamente com quais privilégios os subprogramas executam, fechando brechas de escalonamento de privilégios.
Gerenciando Estado com Variáveis de Package e o Erro ORA-04068
Uma das características mais marcantes das Packages PL/SQL é a capacidade de reter estado entre chamadas. Considere o código abaixo, executado em uma mesma sessão:
-- Bloco 1: chama a procedure de reajuste
BEGIN
PKG_RH.reajustar_salario_departamento(60, 5);
DBMS_OUTPUT.PUT_LINE('Último departamento: ' || PKG_RH.g_ultimo_dept_id);
END;
/
-- Bloco 2: em outro momento da mesma sessão, apenas consulta a variável
BEGIN
DBMS_OUTPUT.PUT_LINE('Ainda lembro: ' || PKG_RH.g_ultimo_dept_id);
END;
/
A saída esperada será:
Package PKG_RH inicializada.
Último departamento: 60
Ainda lembro: 60
A mensagem de inicialização aparece uma única vez, porque o bloco BEGIN do corpo roda apenas no primeiro acesso. A variável g_ultimo_dept_id persiste mesmo após o término do primeiro bloco anônimo. Isso é extremamente útil para cache, como guardar parâmetros de configuração lidos no início da sessão.
Contudo, esse estado é volátil. Se um DBA recompilar a package (via ALTER PACKAGE...COMPILE) enquanto sua sessão está ativa, na próxima tentativa de acesso você receberá o erro ORA-04068: existing state of packages has been discarded. Isso ocorre porque a instância anterior do estado foi invalidada e a nova compilação gera uma versão limpa. Para sistemas críticos, adotamos práticas de recompilação em janelas de manutenção ou usamos packages com estado implícito desabilitado — PRAGMA SERIALLY_REUSABLE, que instrui o Oracle a limpar o estado após cada chamada, tornando a package segura para recompilação, mas sem retenção de variáveis.
Tabelas de Referência Rápida — Comandos e Comparativos
A Tabela 1 resume os comandos essenciais de Data Definition Language (DDL) para gerenciar Packages PL/SQL:
| Comando | Descrição | Exemplo |
|---|---|---|
CREATE [OR REPLACE] PACKAGE |
Cria ou substitui a especificação da package. | CREATE OR REPLACE PACKAGE PKG_TST AS ... |
CREATE [OR REPLACE] PACKAGE BODY |
Cria ou substitui o corpo da package. | CREATE OR REPLACE PACKAGE BODY PKG_TST AS ... |
ALTER PACKAGE ... COMPILE |
Recompila a especificação e/ou corpo. | ALTER PACKAGE PKG_TST COMPILE; |
ALTER PACKAGE ... COMPILE SPECIFICATION |
Recompila apenas a especificação. | ALTER PACKAGE PKG_TST COMPILE SPECIFICATION; |
ALTER PACKAGE ... COMPILE BODY |
Recompila apenas o corpo. | ALTER PACKAGE PKG_TST COMPILE BODY; |
DROP PACKAGE ... |
Remove especificação e corpo juntos. | DROP PACKAGE PKG_TST; |
DROP PACKAGE BODY ... |
Remove apenas o corpo, mantendo a especificação. | DROP PACKAGE BODY PKG_TST; |
A Tabela 2 compara subprogramas standalone com subprogramas empacotados, usando critérios técnicos:
| Critério | Standalone | Package |
|---|---|---|
| Organização | Objetos soltos no schema, difícil agrupamento. | Agrupamento lógico por módulo, como namespaces. |
| Encapsulamento | Sem separação pública/privada; todo código é exposto. | Especificação pública + corpo privado; ocultação real. |
| Estado de sessão | Não suporta variáveis persistentes entre chamadas. | Variáveis de package mantêm estado durante a sessão. |
| Performance | Cada chamada pode envolver carga individual do objeto. | Carga única na memória; todos os subprogramas disponíveis. |
| Dependências | Alteração de assinatura invalida todos os chamadores. | Mudanças no corpo não invalidam a especificação nem chamadores. |
| Segurança | Concessão de EXECUTE por objeto individual. | Concessão única na package; controle centralizado de privilégios. |
| Inicialização | Não possui. | Bloco de inicialização executado no primeiro acesso. |
Verificando a Instalação / Testando a Configuração da Package
Antes de considerar a aula concluída, é fundamental executar uma bateria de testes que garantam que sua package está funcional e que você compreendeu o comportamento. Vamos verificar o carregamento, a execução dos métodos e o estado.
Teste 1 — Verificar carregamento inicial: Desconecte e reconecte sua sessão (para limpar qualquer estado anterior). Em seguida, execute a chamada mais simples:
BEGIN
DBMS_OUTPUT.PUT_LINE('Teste de inicializacao');
-- Acessa qualquer elemento público, forçando o carregamento
DBMS_OUTPUT.PUT_LINE('Valor inicial de g_ultimo_dept_id: ' || NVL(TO_CHAR(PKG_RH.g_ultimo_dept_id),'NULL'));
END;
/
Saída esperada (note a mensagem de inicialização e o valor NULL):
Package PKG_RH inicializada.
Teste de inicializacao
Valor inicial de g_ultimo_dept_id: NULL
Teste 2 — Calcular salário anual:
SELECT PKG_RH.salario_anual(100, 10) AS salario_bonus FROM dual;
Considerando o empregado 100 (Steven King) com salário 24000 e nenhuma comissão, o resultado será 24000*12 = 288000 mais 10% de bônus: 316800. A saída:
SALARIO_BONUS
-------------
316800
Teste 3 — Reajuste e estado: Execute o bloco anônimo que reajusta e depois consulta a variável:
BEGIN
PKG_RH.reajustar_salario_departamento(90, 5); -- departamento 90, 5%
DBMS_OUTPUT.PUT_LINE('Ultimo departamento ajustado: ' || PKG_RH.g_ultimo_dept_id);
END;
/
Saída:
Ultimo departamento ajustado: 90
Teste 4 — Verificação de objetos válidos: A consulta já mostrada deve retornar ambos com STATUS ‘VALID’. Se o corpo estiver inválido, você verá ‘INVALID’. Corrija os erros antes de prosseguir.
Erros Comuns e Como Resolver
Na trajetória de aprendizado de Packages PL/SQL, é normal esbarrar em mensagens de erro que parecem crípticas. Listamos os quatro erros mais frequentes em nossos workshops na JRT Technology Solutions, com diagnóstico e solução imediata.
-
PLS-00323: subprogram or cursor ‘…’ is declared in a package specification and must be defined in the package body
Causa: Você declarou uma função ou procedimento na especificação, mas esqueceu de implementá-la no corpo, ou o nome não coincide exatamente (incluindo parâmetros).
Sintoma: O corpo compila com erro e a package fica inválida.
Solução: Verifique linha a linha a especificação; cada subprograma público deve ter uma implementação correspondente no corpo com a mesma assinatura. Se você intencionalmente não quer implementar ainda, remova-o da especificação ou deixe o corpo com um stub que levante uma exceção. -
PLS-00310: with XXXX as the name of a procedure, function, or package dblink reference
Causa: Erro de sintaxe no protótipo, como falta de ponto e vírgula, parâmetro com tipo inválido ou palavra-chave mal colocada.
Sintoma: A compilação da especificação falha.
Solução: Revise se cada declaração de procedure ou função termina com;e se os modosIN/OUTestão corretos. Compare com exemplos funcionais. -
ORA-04068: existing state of packages has been discarded
Causa: A package foi recompilada enquanto sua sessão estava ativa, invalidando o estado anterior.
Sintoma: Na próxima chamada, a sessão recebe o erro e a package precisa ser reinicializada.
Solução: Reconecte a sessão ou simplesmente execute novamente a chamada — a nova instância carregará com estado limpo. Em produção, evite recompilar packages com estado em horários de pico; usePRAGMA SERIALLY_REUSABLEse o estado não for essencial. -
ORA-04063: package body “…” has errors
Causa: O corpo contém erros de compilação (ex.: referência a tabela inexistente, variável não declarada).
Sintoma: A especificação fica válida, mas o corpo inválido, e qualquer chamada resulta em erro.
Solução: UseSHOW ERRORSno SQL*Plus ou consulteUSER_ERRORS:SELECT line, text FROM user_errors WHERE name='PKG_RH' ORDER BY sequence;. Corrija os erros apontados e recompile o corpo comALTER PACKAGE PKG_RH COMPILE BODY;.
Boas Práticas e Dicas Avançadas com Packages PL/SQL
Em implantações corporativas na JRT Technology Solutions, seguimos convenções que facilitam a manutenção e o entendimento do código por equipes distribuídas. Algumas delas:
- Prefixo e sufixo padronizados: use
PKG_para packages,FNC_para funções standalone ePRC_para procedures avulsas. Isso evita colisão de nomes. - Documentação inline: sempre comente a especificação com o propósito de cada subprograma, parâmetros e exceções lançadas. O Oracle permite criar comments na package com
COMMENT ON PACKAGE PKG_RH IS 'Gerenciamento de Recursos Humanos';. - Controle transacional: discutível, mas preferimos que packages não realizem COMMIT ou ROLLBACK, deixando o controle para o chamador. Isso evita surpresas em transações maiores.
- Use
AUTHIDcom consciência: o padrão éAUTHID DEFINER(executa com privilégios do dono). Se precisar que a package execute com os privilégios do usuário que a chamou (útil para ferramentas de auditoria), declareAUTHID CURRENT_USERna especificação. - Versionamento da package: adicione uma constante
c_versao CONSTANT VARCHAR2(10) := '1.2.3';na especificação. Isso permite consultar via SQL qual versão da lógica está em produção. - Bloqueio de recompilação acidental: em ambientes com deploy automatizado, utilize
ALTER PACKAGE ... COMPILE;com a opçãoREUSE SETTINGSpara preservar configurações de compilação.
Outro recurso avançado é a definição de cursores REF CURSOR dentro de packages, permitindo que você retorne conjuntos de dados complexos para aplicações sem expor queries. Isso é vastamente usado em APIs REST de Oracle ORDS. Estudaremos cursores na próxima aula, mas é valioso saber que eles podem ser declarados como tipos públicos na package.
Resumo da Aula 19
Nesta aula abrangente, transformamos seu conhecimento de PL/SQL de procedimental linear para uma arquitetura modular e profissional. Aprendemos que as Packages PL/SQL são a unidade fundamental de encapsulamento no Oracle, divididas em especificação pública e corpo privado. Criamos do zero a package PKG_RH, implementando funções, procedures e variáveis de estado, e a testamos exaustivamente. Compreendemos as vantagens de performance, segurança e manutenibilidade que as packages oferecem sobre subprogramas independentes, e discutimos armadilhas como o erro ORA-04068 e problemas de compilação.
Utilizando os conceitos apresentados, você é agora capaz de projetar sua própria biblioteca de procedures para qualquer módulo do banco de dados — seja financeiro, logística ou segurança — com separação clara de responsabilidades. Em nossos projetos na JRT Technology Solutions, a adoção de packages reduziu em 40% o tempo de manutenção de rotinas batch e eliminou problemas de inconsistência de assinaturas entre ambientes. Você pode alcançar resultados semelhantes aplicando as boas práticas discutidas aqui.
Na próxima aula — Aula 20 — avançaremos para Cursores e Coleções, onde exploraremos como manipular múltiplas linhas dentro de programas PL/SQL utilizando cursores explícitos, BULK COLLECT e FORALL. Veremos como integrar esses mecanismos com as packages que acabamos de aprender, para construir rotinas de processamento de dados ainda mais eficientes. Até lá, revise os scripts da package PKG_RH, experimente criar uma package para outro módulo (ex.: PKG_FINANCEIRO) e enfrente os erros de compilação — é praticando que se domina a arte do Oracle.
Este conteúdo é parte integrante do curso “Oracle SQL — Do Zero ao Avançado” oferecido pelo blog. A JRT Technology Solutions fornece treinamentos corporativos in company, implementação de bancos de dados Oracle e suporte especializado 24×7. Para saber mais sobre nossos serviços, entre em contato com nossa equipe.
Quer aprender na prática com especialistas?
A JRT Technology Solutions oferece treinamentos e implementação de Oracle SQL para equipes corporativas.