Oracle Paquete PL/SQL: tipo, especificación, cuerpo [Ejemplo]

¿Qué es el paquete? Oracle?

Un paquete PL/SQL es una agrupación lógica de un subprograma relacionado (procedimiento/función) en un único elemento. Un paquete se compila y se almacena como un objeto de base de datos que se puede utilizar más adelante.

Componentes de paquetes

El paquete PL/SQL tiene dos componentes.

  • Especificación del paquete
  • Cuerpo del paquete

Especificación del paquete

La especificación del paquete consiste en una declaración de todo el público. las variables, cursores, objetos, procedimientos, funciones y excepciones.

A continuación se presentan algunas características de la especificación del paquete.

  • Se puede acceder a todos los elementos declarados en la especificación desde fuera del paquete. Estos elementos se conocen como elemento público.
  • La especificación del paquete es un elemento independiente, lo que significa que puede existir por sí solo sin el cuerpo del paquete.
  • Cada vez que un paquete ha hecho referencia, se crea una instancia del paquete para esa sesión en particular.
  • Una vez creada la instancia para una sesión, todos los elementos del paquete que se inician en esa instancia son válidos hasta el final de la sesión.

Sintaxis

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

La sintaxis anterior muestra la creación de la especificación del paquete.

Cuerpo del paquete

Consiste en la definición de todos los elementos que están presentes en la especificación del paquete. También puede tener una definición de elementos que no están declarados en la especificación; estos elementos se denominan elementos privados y solo pueden llamarse desde dentro del paquete.

A continuación se muestran las características del cuerpo de un paquete.

  • Debe contener definiciones para todos los subprogramas/cursores que han sido declarados en la especificación.
  • También puede tener más subprogramas u otros elementos que no estén declarados en la especificación. Estos se llaman elementos privados.
  • Es un objeto confiable y depende de la especificación del paquete.
  • El estado del cuerpo del paquete pasa a ser "No válido" cada vez que se compila la especificación. Por lo tanto, es necesario volver a compilarlo cada vez que se compila la especificación.
  • Los elementos privados deben definirse primero antes de usarse en el cuerpo del paquete.
  • La primera parte del paquete es la parte de declaración global. Esto incluye variables, cursores y elementos privados (declaración directa) que son visibles para todo el paquete.
  • La última parte del paquete es la parte de inicialización del paquete que se ejecuta una vez cada vez que se hace referencia a un paquete por primera vez en la sesión.

Sintaxis:

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>
  • La sintaxis anterior muestra la creación del cuerpo del paquete.

Ahora vamos a ver cómo hacer referencia a elementos del paquete en el programa.

Elementos del paquete de referencia

Una vez que los elementos están declarados y definidos en el paquete, debemos hacer referencia a los elementos para usarlos.

Se puede hacer referencia a todos los elementos públicos del paquete llamando al nombre del paquete seguido del nombre del elemento separado por un punto, es decir, '.'.

La variable pública del paquete también se puede utilizar de la misma manera para asignar y recuperar valores de ellos, es decir, '.'.

Crear paquete en PL/SQL

En PL/SQL, cada vez que se hace referencia/llama a un paquete en una sesión, se creará una nueva instancia para ese paquete.

Oracle proporciona una función para inicializar elementos del paquete o realizar cualquier actividad en el momento de la creación de esta instancia a través de la 'Inicialización del paquete'.

Esto no es más que un bloque de ejecución que se escribe en el cuerpo del paquete después de definir todos los elementos del paquete. Este bloque se ejecutará cada vez que se haga referencia a un paquete por primera vez en la sesión.

Sintaxis

Crear paquete en PL/SQL

CREATE [OR REPLACE] PACKAGE BODY <package_name>
IS
<Private element definition>
<sub_program and public element definition>
.
BEGINE
<Package Initialization> 
END <package_name>
  • La sintaxis anterior muestra la definición de inicialización del paquete en el cuerpo del paquete.

Declaraciones futuras

La declaración/referencia hacia adelante en el paquete no es más que declarar los elementos privados por separado y definirlos en la parte posterior del cuerpo del paquete.

Solo se puede hacer referencia a elementos privados si ya están declarados en el cuerpo del paquete. Por este motivo se utiliza la declaración directa. Pero su uso es bastante inusual porque la mayoría de las veces los elementos privados se declaran y definen en la primera parte del cuerpo del paquete.

La declaración anticipada es una opción proporcionada por Oracle, no es obligatorio y su uso y no uso depende de los requisitos del programador.

Declaraciones futuras

Sintaxis:

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>

La sintaxis anterior muestra una declaración adelantada. Los elementos privados se declaran por separado en la parte adelantada del paquete y se han definido en la parte posterior.

Uso de cursores en el paquete

A diferencia de otros elementos, hay que tener cuidado al utilizar cursores dentro del paquete.

Si el cursor está definido en la especificación del paquete o en la parte global del cuerpo del paquete, una vez abierto, el cursor persistirá hasta el final de la sesión.

Por lo tanto, siempre se deben usar los atributos del cursor '%ISOPEN' para verificar el estado del cursor antes de consultarlo.

Sobrecarga

La sobrecarga es el concepto de tener muchos subprogramas con el mismo nombre. Estos subprogramas se diferenciarán entre sí por una cantidad de parámetros o tipos de parámetros o tipo de retorno, es decir, un subprograma con el mismo nombre pero con diferente número de parámetros, diferentes tipos de parámetros o diferentes retipos se consideran sobrecarga.

Esto es útil cuando muchos subprogramas necesitan realizar la misma tarea, pero la forma de llamar a cada uno de ellos debe ser diferente. En este caso, el nombre del subprograma se mantendrá igual para todos y los parámetros se cambiarán según la declaración de llamada.

Ejemplo : En este ejemplo, vamos a crear un paquete para obtener y establecer los valores de la información de los empleados en la tabla 'emp'. La función get_record devolverá la salida del tipo de registro para el número de empleado dado, y el procedimiento set_record insertará el registro del tipo de registro en la tabla emp.

Paso 1) Creación de especificaciones de paquete

Sobrecarga

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:
/

Salida:

Package created

Explicación del código

  • Línea de código 1-5: Crear la especificación del paquete para guru99_get_set con un procedimiento y una función. Estos dos son ahora elementos públicos de este paquete.

Paso 2) El paquete contiene el cuerpo del paquete, donde se definirán todos los procedimientos y funciones reales. En este paso, se crea el cuerpo del paquete.

Sobrecarga

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;
BEGUN	
dbms_output.put_line(‘Control is now executing the package initialization part');
END guru99_get_set:
/

Salida:

Package body created

Explicación del código

  • Línea de código 7: Creando el cuerpo del paquete.
  • Línea de código 9-16: Definiendo el elemento 'set_record' que se declara en la especificación. Esto es lo mismo que definir el procedimiento independiente en PL/SQL.
  • Línea de código 17-24: Definiendo el elemento 'get_record'. Es lo mismo que definir la función independiente.
  • Línea de código 25-26: Definiendo la parte de inicialización del paquete.

Paso 3) Crear un bloque anónimo para insertar y mostrar los registros haciendo referencia al paquete creado anteriormente.

Sobrecarga

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:=l004;
l_emp_rec.emp_name:='CCC';
l_emp_rec.salary~20000;
l_emp_rec.manager:=’BBB’;
guru99_get_set.set_record(1_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:‘||1_get_rec.manager);		
END:
/

Salida:

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

Explicación del código:

  • Línea de código 34-37: Completar los datos para la variable de tipo de registro en un bloque anónimo para llamar al elemento 'set_record' del paquete.
  • Línea de código 38: Se realizó una llamada a 'set_record' del paquete guru99_get_set. Ahora se crea una instancia del paquete y persistirá hasta el final de la sesión.
  • La parte de inicialización del paquete se ejecuta ya que esta es la primera llamada al paquete.
  • El registro insertado por el elemento 'set_record' en la tabla.
  • Línea de código 41: Llamar al elemento 'get_record' para mostrar los detalles del empleado insertado.
  • El paquete se remite por segunda vez durante la llamada 'get_record' al paquete. Pero la parte de inicialización no se ejecuta esta vez porque el paquete ya se inicializó en esta sesión.
  • Línea de código 42-45: Impresión de los detalles del empleado.

Dependencia en paquetes

Dado que el paquete es una agrupación lógica de elementos relacionados, tiene algunas dependencias. A continuación se indican las dependencias que se deben tener en cuenta.

  • Una especificación es un objeto independiente.
  • El cuerpo del paquete depende de la especificación.
  • El cuerpo del paquete se puede compilar por separado. Siempre que se compila una especificación, es necesario volver a compilar el cuerpo, ya que dejará de ser válido.
  • El subprograma en el cuerpo del paquete que depende de un elemento privado debe definirse sólo después de la declaración del elemento privado.
  • Los objetos de la base de datos a los que se hace referencia en la especificación y el cuerpo deben tener un estado válido en el momento de la compilación del paquete.

Información del paquete

Una vez que se crea la información del paquete, la información del paquete, como la fuente del paquete, los detalles del subprograma y los detalles de sobrecarga, están disponibles en el Oracle tablas de definición de datos.

La siguiente tabla proporciona la tabla de definición de datos y la información del paquete que está disponible en la tabla.

Nombre de la tabla Descripciones Consulta
TODO_OBJETO Proporciona los detalles del paquete como object_id, creation_date, last_ddl_time, etc. Contendrá los objetos creados por todos los usuarios. SELECCIONAR * DE todos_objetos donde nombre_objeto =''
USUARIO_OBJECT Proporciona los detalles del paquete como object_id, creation_date, last_ddl_time, etc. Contendrá los objetos creados por el usuario actual. SELECCIONAR * DE objetos_usuario donde nombre_objeto =''
TODO_FUENTE Proporciona el origen de los objetos creados por todos los usuarios. SELECCIONAR * DE all_source donde nombre = ''
FUENTE_USUARIO Proporciona el origen de los objetos creados por el usuario actual. SELECCIONAR * DE fuente_usuario donde nombre = ''
TODOS_PROCEDIMIENTOS Proporciona detalles del subprograma como object_id, detalles de sobrecarga, etc. creados por todos los usuarios. SELECCIONAR * DE todos_procedimientos
Donde nombre_objeto='’
USUARIO_PROCEDIMIENTOS Proporciona detalles del subprograma como object_id, detalles de sobrecarga, etc. creado por el usuario actual. SELECCIONAR * DE procedimientos_usuario
Donde nombre_objeto='’

ARCHIVO UTL: descripción general

El archivo UTL es el paquete de utilidades independiente proporcionado por Oracle para realizar tareas especiales. Esto se utiliza principalmente para leer y escribir archivos del sistema operativo desde paquetes o subprogramas PL/SQL. Obtuvo funciones separadas para colocar la información y obtener la información de los archivos. También permite leer/escribir en el juego de caracteres nativo.

El programador puede utilizar esto para escribir archivos del sistema operativo de cualquier tipo y el archivo se escribirá directamente en el servidor de base de datos. El nombre y la ruta del directorio se mencionarán al momento de escribir.

Resumen

Ahora hemos aprendido los paquetes en PL / SQL, y ahora deberías poder trabajar en lo siguiente.

  • Paquetes PL/SQL y sus componentes
  • Características de los paquetes.
  • Referenciar y sobrecargar elementos del paquete.
  • Gestionar dependencias en paquetes.
  • Visualización de la información del paquete
  • ¿Qué es el archivo UTL?