Oracle Pacote PL/SQL: Tipo, Especificação, Corpo [Exemplo]

⚔ Resumo Inteligente

Os pacotes PL/SQL agrupam procedimentos, funções, variÔveis, cursores e exceções relacionados em um único objeto de esquema com uma especificação e um corpo. A especificação declara a interface pública, enquanto o corpo contém a implementação privada, melhorando a modularidade e o desempenho.

  • šŸ“¦ Definição do pacote: Um pacote Ć© um grupo lógicoping de subprogramas e objetos relacionados, compilados e armazenados como um Ćŗnico objeto de banco de dados.
  • šŸ“‹ EspecificaƧƵes da embalagem: Declara as variĆ”veis ​​pĆŗblicas, cursores, tipos, exceƧƵes, procedimentos e funƧƵes acessĆ­veis de fora do pacote.
  • 🧱 Corpo da embalagem: Define todos os elementos declarados na especificação, alĆ©m de elementos privados que podem ser chamados apenas de dentro do pacote.
  • šŸ” Sobrecarregando: VĆ”rios subprogramas podem compartilhar o mesmo nome quando o nĆŗmero de parĆ¢metros, os tipos de parĆ¢metros ou o tipo de retorno forem diferentes.
  • šŸ”— ReferĆŖncia e DependĆŖncia: Os elementos pĆŗblicos sĆ£o chamados de nome_do_pacote.nome_do_elemento, e o corpo permanece dependente da especificação.
  • šŸ¤– AssistĆŖncia de IA: Assistentes de IA, como o GitHub Copilot, elaboram especificaƧƵes de pacotes, corpos e subprogramas sobrecarregados a partir de um comentĆ”rio.

Oracle Visão geral da especificação e estrutura do corpo do pacote PL/SQL

O que Ć© o pacote Oracle?

Oracle PL/SQL pacote é um grupo lógicoping de relacionado subprogramas (procedimento/função) em um único elemento. Um pacote é compilado e armazenado como um objeto de banco de dados que pode ser reutilizado posteriormente.

Componentes de Pacotes

Um pacote PL/SQL possui dois componentes.

  • Especificação do Pacote
  • Corpo do pacote

Especificação do Pacote

A especificação do pacote consiste em uma declaração de todos os públicos variÔveis, cursores, objetos, procedimentos, funções e exceções.

A seguir, apresentamos algumas características da especificação do pacote.

  • Os elementos declarados na especificação podem ser acessados ​​de fora do pacote. Esses elementos sĆ£o conhecidos como elementos pĆŗblicos.
  • A especificação do pacote Ć© um elemento independente, o que significa que pode existir sozinha, sem um corpo de pacote.
  • Sempre que um pacote Ć© referenciado, uma instĆ¢ncia do pacote Ć© criada para aquela sessĆ£o especĆ­fica.
  • Depois que a instĆ¢ncia for criada para uma sessĆ£o, todos os elementos do pacote iniciados nessa instĆ¢ncia serĆ£o vĆ”lidos atĆ© o final da sessĆ£o.

Sintaxe

CREATE [OR REPLACE] PACKAGE <package_name> 
IS
<sub_program and public element declaration>
.
.
END <package name>

A sintaxe acima mostra a criação da especificação do pacote.

Corpo do pacote

O corpo do pacote consiste na definição de todos os elementos presentes na especificação do pacote. Ele tambĆ©m pode conter definiƧƵes de elementos que nĆ£o foram declarados na especificação; esses elementos sĆ£o chamados de elementos privados e só podem ser acessados ​​de dentro do pacote.

A seguir estão as características de um corpo de embalagem.

  • Deve conter as definiƧƵes de todos os subprogramas/cursores que foram declarados na especificação.
  • TambĆ©m pode conter mais subprogramas ou outros elementos que nĆ£o estĆ£o declarados na especificação. Esses sĆ£o chamados de elementos privados.
  • Ɖ um objeto dependente e depende da especificação do pacote.
  • O estado do corpo do pacote torna-se 'InvĆ”lido' sempre que a especificação Ć© compilada. Portanto, ele precisa ser recompilado a cada vez após a compilação da especificação.
  • Os elementos privados devem ser definidos primeiro, antes de serem usados ​​no corpo do pacote.
  • A primeira parte do corpo do pacote Ć© a parte de declaração global. Isso inclui variĆ”veis, cursores e elementos privados (declaração antecipada) que sĆ£o visĆ­veis para todo o pacote.
  • A Ćŗltima parte do pacote Ć© a parte de inicialização do pacote, que Ć© executada uma Ćŗnica vez sempre que um pacote Ć© referenciado pela primeira vez na sessĆ£o.

Sintaxe:

CREATE [OR REPLACE] PACKAGE BODY <package_name>
IS
<global_declaration part>
<Private element definition>
<sub_program and public element definition>
.
<Package Initialization> 
END <package_name>

A sintaxe acima mostra a criação do corpo do pacote.

Agora vamos ver como fazer referĆŖncia a elementos de pacote no programa.

Referindo Elementos do Pacote

Uma vez que os elementos são declarados e definidos no pacote, precisamos nos referir a eles para utilizÔ-los.

Todos os elementos pĆŗblicos do pacote podem ser referenciados chamando o nome do pacote seguido pelo nome do elemento, separados por um ponto, ou seja, ' . '.

As variĆ”veis ​​pĆŗblicas do pacote tambĆ©m podem ser usadas da mesma forma para atribuir e obter valores delas, ou seja, ' . '.

Criar pacote em PL/SQL

Em PL/SQL, sempre que um pacote é referenciado ou chamado em uma sessão, uma nova instância é criada para esse pacote.

Oracle fornece um recurso para inicializar elementos do pacote ou realizar qualquer atividade no momento da criação desta instância por meio de 'Inicialização do pacote'.

Trata-se simplesmente de um bloco de execução escrito no corpo do pacote após a definição de todos os seus elementos. Esse bloco serÔ executado sempre que um pacote for referenciado pela primeira vez na sessão.

A captura de tela abaixo mostra como o bloco de inicialização do pacote é colocado dentro do corpo do pacote ao criar um pacote.

Criando um pacote PL/SQL com um bloco de inicialização de pacote no corpo do pacote.

Sintaxe

CREATE [OR REPLACE] PACKAGE BODY <package_name>
IS
<Private element definition>
<sub_program and public element definition>
.
BEGIN
<Package Initialization> 
END <package_name>

A sintaxe acima mostra a definição de inicialização do pacote no corpo do pacote.

DeclaraƧƵes para a frente

A declaração ou referência antecipada em um pacote nada mais é do que declarar os elementos privados separadamente e defini-los posteriormente no corpo do pacote.

Elementos privados só podem ser referenciados se jÔ estiverem declarados no corpo do pacote. Por esse motivo, utiliza-se a declaração antecipada. No entanto, seu uso é incomum, pois na maioria das vezes os elementos privados são declarados e definidos na primeira parte do corpo do pacote.

A declaração futura é uma opção fornecida por OracleNão é obrigatório, e o seu uso ou não fica a critério do programador.

A captura de tela abaixo mostra como um elemento privado Ć© declarado antecipadamente e posteriormente definido no corpo do pacote.

Declaração antecipada de um elemento privado em um Oracle Corpo do pacote PL/SQL

Sintaxe:

CREATE [OR REPLACE] PACKAGE BODY <package_name>
IS
<Private element declaration>
.
.
.
<Public element definition that refer the above private element>
.
.
<Private element definition> 
.
BEGIN
<package_initialization code>; 
END <package_name>

A sintaxe acima mostra a declaração direta. Os elementos privados são declarados separadamente na parte anterior do pacote e foram definidos na parte posterior.

Uso de cursores no pacote

Diferentemente de outros elementos, Ć© preciso ter cuidado ao usar cursores dentro do pacote.

Se o cursor estiver definido na especificação do pacote ou na parte global do corpo do pacote, então, uma vez aberto, o cursor permanecerÔ visível até o final da sessão.

Portanto, deve-se sempre usar o atributo do cursor '%ISOPEN' para verificar o estado do cursor antes de se referir a ele.

Sobrecarregando

Sobrecarga é o conceito de ter vÔrios subprogramas com o mesmo nome. Esses subprogramas diferem entre si pelo número de parâmetros, pelos tipos de parâmetros ou pelo tipo de retorno. Em outras palavras, subprogramas com o mesmo nome, mas com número diferente de parâmetros, tipos diferentes de parâmetros ou tipos de retorno diferentes, são considerados sobrecarga.

Isso é útil quando vÔrias sub-rotinas precisam executar a mesma tarefa, mas a forma de chamar cada uma delas deve ser diferente. Nesse caso, o nome da sub-rotina permanece o mesmo para todas, e os parâmetros são alterados de acordo com a instrução de chamada.

1 exemplo: Neste exemplo, vamos criar um pacote para obter e definir os valores das informações de um funcionÔrio na tabela 'emp'. A função `get_record` retornarÔ o tipo de registro correspondente ao número do funcionÔrio fornecido, e o procedimento `set_record` inserirÔ o registro correspondente na tabela 'emp'.

Etapa 1) Criação da especificação do pacote

A captura de tela abaixo mostra a especificação do pacote guru99_get_set sendo criada em Oracle.

Criando a especificação do pacote guru99_get_set com set_record e get_record em Oracle

CREATE OR REPLACE PACKAGE guru99_get_set
IS
PROCEDURE set_record (p_emp_rec IN emp%ROWTYPE);
FUNCTION get_record (p_emp_no IN NUMBER) RETURN emp%ROWTYPE;
END guru99_get_set;
/

SaĆ­da:

Package created

Code Explicação

  • Code linhas 1-5: Criando a especificação do pacote para guru99_get_set com um procedimento e uma função. Estes dois agora sĆ£o elementos pĆŗblicos deste pacote.

Passo 2) O pacote contém um corpo de pacote, onde são definidas as definições reais de todos os procedimentos e funções. Nesta etapa, o corpo do pacote é criado.

A captura de tela abaixo mostra a definição do corpo do pacote guru99_get_set em Oracle.

Definindo o corpo do pacote guru99_get_set com set_record, get_record e o bloco de inicialização.

CREATE OR REPLACE PACKAGE BODY guru99_get_set
IS
PROCEDURE set_record(p_emp_rec IN emp%ROWTYPE)
IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
INSERT INTO emp
VALUES(p_emp_rec.emp_name,p_emp_rec.emp_no, p_emp_rec.salary,p_emp_rec.manager);
COMMIT;
END set_record;
FUNCTION get_record(p_emp_no IN NUMBER)
RETURN emp%ROWTYPE
IS
l_emp_rec emp%ROWTYPE;
BEGIN
SELECT * INTO l_emp_rec FROM emp where emp_no=p_emp_no;
RETURN l_emp_rec;
END get_record;
BEGIN
dbms_output.put_line('Control is now executing the package initialization part');
END guru99_get_set;
/

SaĆ­da:

Package body created

Code Explicação

  • Code linha 7: Criando o corpo do pacote.
  • Code linhas 9-16: Definir o elemento 'set_record' que Ć© declarado na especificação. Isso Ć© o mesmo que definir um procedimento independente em PL/SQL.
  • Code linhas 17-24: Definir o elemento 'get_record' Ć© o mesmo que definir uma função independente.
  • Code linhas 25-26: Definindo a parte de inicialização do pacote.

Passo 3) Criando um bloco anÓnimo para inserir e exibir os registros, fazendo referência ao pacote criado anteriormente.

A captura de tela abaixo mostra o bloco anƓnimo que chama o pacote, juntamente com sua saƭda em Oracle.

Bloco anƓnimo chamando guru99_get_set para inserir e exibir um registro de funcionƔrio com saƭda

DECLARE
l_emp_rec emp%ROWTYPE;
l_get_rec emp%ROWTYPE;
BEGIN
dbms_output.put_line('Insert new record for employee 1004');
l_emp_rec.emp_no:=1004;
l_emp_rec.emp_name:='CCC';
l_emp_rec.salary:=20000;
l_emp_rec.manager:='BBB';
guru99_get_set.set_record(l_emp_rec);
dbms_output.put_line('Record inserted');
dbms_output.put_line('Calling get function to display the inserted record');
l_get_rec:=guru99_get_set.get_record(1004);
dbms_output.put_line('Employee name: '||l_get_rec.emp_name);
dbms_output.put_line('Employee number:'||l_get_rec.emp_no);
dbms_output.put_line('Employee salary:'||l_get_rec.salary);
dbms_output.put_line('Employee manager:'||l_get_rec.manager);
END;
/

SaĆ­da:

Insert new record for employee 1004
Control is now executing the package initialization part
Record inserted
Calling get function to display the inserted record
Employee name: CCC
Employee number: 1004
Employee salary: 20000
Employee manager: BBB

Code Explicação:

  • Code linhas 34-37: Preencher os dados da variĆ”vel de tipo de registro em um bloco anĆ“nimo para chamar o elemento 'set_record' do pacote.
  • Code linha 38: Foi feita uma chamada para 'set_record' do pacote guru99_get_set. Agora o pacote estĆ” instanciado e persistirĆ” atĆ© o final da sessĆ£o. A parte de inicialização do pacote Ć© executada, pois esta Ć© a primeira chamada ao pacote, e o registro Ć© inserido na tabela pelo elemento 'set_record'.
  • Code linha 41: Chamando o elemento 'get_record' para exibir os detalhes do funcionĆ”rio inserido. O pacote Ć© referenciado pela segunda vez durante esta chamada, mas a parte de inicialização nĆ£o Ć© executada novamente, pois o pacote jĆ” estĆ” inicializado nesta sessĆ£o.
  • Code linhas 42-45: Imprimindo os dados do funcionĆ”rio.

DependĆŖncia em Pacotes

Como o pacote é um grupo lógicoping Dentre os itens relacionados, existem algumas dependências. A seguir, estão as dependências que devem ser consideradas.

  • Uma especificação Ć© um objeto independente.
  • O conteĆŗdo da embalagem depende da especificação.
  • O corpo do pacote pode ser compilado separadamente. Sempre que a especificação for compilada, o corpo precisarĆ” ser recompilado, pois se tornarĆ” invĆ”lido.
  • O subprograma no corpo do pacote que depende de um elemento privado deve ser definido somente após a declaração do elemento privado.
  • Os objetos de banco de dados mencionados na especificação e no corpo do pacote precisam estar em um estado vĆ”lido no momento da compilação.

InformaƧƵes do pacote

Após a criação do pacote, as informações do pacote, como a origem do pacote, detalhes do subprograma e detalhes de sobrecarga, ficam disponíveis no Oracle Tabelas do dicionÔrio de dados.

A tabela abaixo apresenta a tabela do dicionƔrio de dados e as informaƧƵes do pacote disponƭveis em cada tabela.

Nome da tabela Descrição pergunta
TODOS OS OBJETOS Fornece detalhes do pacote, como object_id, creation_date, last_ddl_time, etc. ContƩm os objetos criados por todos os usuƔrios. SELECT * FROM all_objects onde object_name =' '
OBJETOS_DO_USUƁRIO Fornece detalhes do pacote, como object_id, creation_date, last_ddl_time, etc. ContƩm os objetos criados pelo usuƔrio atual. SELECT * FROM user_objects onde object_name =' '
ALL_SOURCE Fornece a origem dos objetos criados por todos os usuƔrios. SELECIONE * FROM all_source onde nome=' '
USER_SOURCE Fornece a origem dos objetos criados pelo usuƔrio atual. SELECIONE * FROM user_source onde nome=' '
TODOS_PROCEDIMENTOS Fornece detalhes do subprograma, como object_id, detalhes de sobrecarga, etc., criados por todos os usuƔrios. SELECT * FROM all_procedures WHERE object_name=' '
USER_PROCEDURES Fornece detalhes do subprograma como object_id, detalhes de sobrecarga, etc. criados pelo usuƔrio atual. SELECT * FROM user_procedures WHERE object_name=' '

UTL_FILE – Uma VisĆ£o Geral

UTL_FILE Ć© um pacote de utilitĆ”rios separado fornecido por Oracle Para executar tarefas especiais. Ɖ usado principalmente para ler e gravar arquivos do sistema operacional a partir de pacotes ou subprogramas PL/SQL. Possui funƧƵes separadas para inserir e obter informaƧƵes de arquivos. TambĆ©m permite leitura e gravação no conjunto de caracteres nativo.

O programador pode usar isso para escrever arquivos do sistema operacional de qualquer tipo, e o arquivo serÔ gravado diretamente no servidor de banco de dados. O nome e o caminho do diretório são mencionados no momento da gravação.

Perguntas Frequentes

Os pacotes proporcionam modularidade, ocultação de informações e facilitam o design de aplicações. A especificação expõe uma interface pública, enquanto o corpo oculta a implementação. Oracle Carrega um pacote na memória na primeira chamada, de modo que as chamadas subsequentes do subprograma evitam a entrada/saída de disco e são executadas mais rapidamente.

Um pacote agrupa muitos itens relacionados. subprogramas e objetos compartilhados sob um único nome, separando uma especificação pública de um corpo privado. Um procedimento ou função independente é um objeto de esquema único e independente, sem essa divisão entre interface e implementação.

Sim, se a especificação declarar apenas variÔveis, constantes, tipos ou exceções. Um corpo torna-se obrigatório assim que a especificação declarar qualquer procedimento, função ou cursor, pois o corpo deve fornecer a implementação desses elementos. Caso contrÔrio, a especificação pode ser independente.

Use DROP PACKAGE para remover tanto a especificação quanto o corpo do pacote, ou DROP PACKAGE BODY para remover apenas o corpo. Recompile um pacote invÔlido com ALTER PACKAGE nome_do_pacote COMPILE, ou COMPILE BODY para reconstruir apenas o corpo após as alterações.

O atributo %ROWTYPE declara um registro cujos campos correspondem às colunas da tabela emp. O uso de emp%ROWTYPE mantém os parâmetros get_record e set_record alinhados com a estrutura da tabela, de modo que as alterações de coluna exigem menos edições de código.

Sim. Cada sessão que referencia um pacote obtém sua própria instanciação e estado do pacote, que persiste durante toda a duração da sessão. Recompilar o corpo da função descarta o estado e gera o erro ORA-04068 na próxima chamada.

Sim. Travas deslizantes portÔteis Copiloto do GitHub Elabora especificações de pacotes, corpos correspondentes e subprogramas sobrecarregados a partir de um comentÔrio e sugere parâmetros %ROWTYPE. RevVisualize os limites gerados, o bloco de inicialização e o tratamento de exceções antes de implantar.

Assistentes de IA examinam um pacote em busca de estados invÔlidos, definições de corpo ausentes e cadeias de dependência que se quebram quando a especificação muda. Essa revisão por aprendizado de mÔquina sinaliza subprogramas sobrecarregados ambíguos e riscos de recompilação antes que o pacote chegue à produção.

Resuma esta postagem com: