lunes, 22 de mayo de 2017

Produciendo Triggers en Oracle Forms

Objetivos:
 Describir las Herramientas del Editor PL/SQL.
 Codificar Triggers.
 Explicar el uso de subprogramas incorporados (Built-in Subprograms) en aplicaciones Forms.
 Describir el Trigger When-Button-Pressed.
 Describir el Trigger When-Window-Closed.

NOTA: Usamos como ejemplo la Base de Datos: ORCL, la cual viene por defecto en cualquier versión de ORACLE.
______________________________________________________________________________________
Definiendo Triggers en Forms Builder.
Usando Triggers Inteligentes (Smart Triggers).
Cuando hace clic con el botón derecho en un objeto en el Navegador de Objetos o en el Editor de Diseño, se muestra un menú emergente que incluye la opción Smart Triggers. El elemento Smart Triggers expande una lista de Triggers comunes que son apropiados para el objeto seleccionado. Al hacer clic en uno de estos Triggers, Forms Builder lo crea.

Cómo crear un Trigger.
Pasos:
Paso Uno: Seleccionar el alcance (Trigger Scope).
En el Navegador de Objetos, seleccione el nodo Triggers de Form, Bloque o Item que poseerá dicho Trigger. Como alternativa, puede seleccionar un Item del Editor de Diseño si está definiendo un Trigger a nivel de Item.

A menudo, desarrolladores sin mucha experiencia definen Triggers con un alcance incorrecto. Por ejemplo, si desea mostrar un mensaje cuando el cursor se enfoca en un Item especifico, debe codificar un Trigger When-New-Item-Instance en el nivel Item para el Item en cuestión. Si por error coloca el Trigger en el nivel Bloque o Form, se disparará siempre que el operador navegue a cualquier Item del Bloque o Form.
Segundo Paso: invocar la lista de Triggers.
Una vez seleccionado el alcance, hay varias maneras de invocar la lista de Triggers:
 Smart Triggers: haga clic con el botón derecho del ratón para mostrar el menú emergente. Seleccione Smart Triggers. Esto muestra una lista de Triggers comunes para el objeto seleccionado. Si no ve el Trigger deseado, seleccione Other para que aparezca una lista completa.
 Create: Si está en el Navegador de objetos con un nodo Triggers seleccionado, en el menú seleccione Edit>Create o haga clic en Create en la barra de herramientas.
 PL/SQL Editor: Haga clic con el botón derecho para mostrar el menú emergente. Seleccione PL/SQL Editor.
---Si no hay ningún Trigger definido para el objeto, la lista de Trigger aparece.
---Si ya hay Triggers definidos para el objeto, el editor se cargara con el primer Trigger en la lista de triggers definidos para dicho objeto. Para definir uno adicional, con el nodo trigger seleccionado, haga clic en Crear en la barra de herramientas del Navegador de objetos.
Una vez invocada la lista de Triggers, seleccione el que cumpla con su requerimiento.
Paso Tres: Utilice el Editor PL/SQL para definir la lógica del Trigger.
Una vez creado el Trigger es hora de darle la funcionalidad deseada de acuerdo a los requerimientos del negocio o aplicación. Para ello usamos el Editor PL/SQL.
Algunos Elementos del Editor PL/SQL.
 Name: Nombre del Trigger; Se trata de una lista que permite cambiar rapidamente entre los triggers creados en todo el Módulo.
 Type: Cuando definimos un Trigger el tipo es: Trigger. (Los otros tipos son Program Unit y Menu Item Code, pero éstos no son válidos para los Triggers).
 Object: Permite establecer el ámbito en Nivel de formulario o en un bloque específico
 Item: Permite cambiar entre los Items existentes (a nivel de Item) para acceder a otros Triggers. Tenga en cuenta que dicho elemento (Item) no tiene una etiqueta que lo identifique.
 Source Pane: Es donde se introduce o modifica el código.
 Toolbar: Botones para compilar, revertir, deshacer, rehacer o sangrar/indentar el código.
Paso Cuatro: Compilar.
Haga clic en el icono Compile en el Editor PL/SQL para compilar el Trigger. Esto muestra una retroalimentación inmediata en forma de mensajes de error de compilación, que puede corregir. Si el disparador se compila correctamente, aparece un mensaje en la esquina inferior derecha del editor.
______________________________________________________________________________________
Las Propiedades del Trigger.
Puede configurar las siguientes propiedades del Trigger para alterar su comportamiento.
General.
 Name: Especifica el nombre interno del Trigger.
Functional.
 Fire in Enter Query Mode: Especifica si el Trigger puede dispararse cuando se produce un evento en el modo de consulta de entrada así como en el modo normal.
 Execution Hierarchy: Se utiliza para cambiar el orden predeterminado de activación del Trigger cuando se definen varios disparadores del mismo nombre en diferentes niveles.
Help (estas propiedades sólo son válidas para los Triggers de Tecla o Key Triggers).
 Display in “Keyboard Help": Especifica si desea que el nombre o la descripción aparezcan en la ventana Show Keys.
 “Keyboard Help” Text: Descripción que reemplaza la predeterminada de la Tecla.
______________________________________________________________________________________
Funciones del Editor PL/SQL.
El Editor PL/SQL ofrece las siguientes funciones:
 Automáticamente formatea, indenta  y da color al código PL/SQL.
 Permite arrastrar, cortar y pegar código.
 Permite Deshacer/Rehacer.
 Permite varias vistas divididas.
Puede crear hasta cuatro vistas separadas del Editor PL/SQL utilizando barras divididas. Para lograrlo, coloque el cursor sobre la barra de división; El cursor cambia a una flecha de doble punta. Haga clic izquierdo y arrastre la barra de división a la ubicación deseada. Para eliminar la división, arrástrela de nuevo a su ubicación original.

Componentes del Editor PL/SQL.
1. Type: Establecido en Trigger.
2. Object: Le permite establecer el alcance a nivel de Form o Bloque.
3. Item: Permite cambiar entre los Items (a nivel de Item) para acceder a otros Triggers.
4. Name: Nombre del Trigger; Le permite cambiar a otro Triggers existentes.
5. Source Pane: Es donde se introduce o modifica el código.

Mas funciones del Editor PL/SQL.
 Paleta de Sintaxis (Syntax Palette): Le permite mostrar y copiar las construcciones de elementos del lenguaje PL/SQL y crear paquetes en un editor. Para invocar la paleta de sintaxis, seleccione  del menú: Tools>Syntax Palette.
 Búsqueda y Sustitución: Permite buscar texto entre varias unidades de programa sin abrir instancias individuales del Editor. Sustituye cada ocurrencia de la cadena de búsqueda o de las ocurrencias seleccionadas.
Invoque el cuadro de diálogo Buscar y Reemplazar (Find and Replace) en las unidades de programa seleccionando Edit>Find and Replace PL/SQL o presionando las teclas Ctrl+F.

Cosas que recordar acerca del Editor PL/SQL.
 Cualquier texto nuevo o modificado permanece sin compilar hasta que haga clic en Compilar.
 La compilación de Triggers que contienen SQL requiere conexión a la base de datos.
 Al compilar el módulo Form también se compilan todos los Triggers no compilados.
 Las listas Block y Item no cambian el ámbito del disparador actual. Solo le permiten cambiar a otro Trigger.

El Editor de Triggers de Base de Datos.
El agrupamiento lógico de elementos dentro del Editor de Triggers de Base de Datos permite a los desarrolladores crear Triggers de fila y sentencia fácilmente. Un cuadro de mensaje muestra un error cuando intenta recuperar, almacenar o eliminar un Trigger no válido. Para crear un Trigger de Base de Datos utilizando el Editor de Triggers de Base de Datos, realice los pasos siguientes:

1. En el Navegador de Objetos, expanda el nodo Database Objects para mostrar los nodos de esquema.
2. Expanda un nodo de esquema para mostrar los objetos de la base de datos.
3. Expanda el nodo Tablas para mostrar las tablas de la base de datos del esquema.
4. Seleccione y expanda la tabla deseada.
5. Seleccione el nodo Triggers y elija Edit>Create o haga clic en Create en la barra de herramientas. Aparece el Editor de Triggers de Base de Datos.
6. En el Editor, haga clic en New.
7. Defina y guarde las unidades de programa deseadas.
______________________________________________________________________________________
Escribiendo/Redactando el Código del Trigger.
El código de un Trigger de Forms Builder es un bloque PL/SQL que consta de tres secciones:
 Una sección de declaración para variables, constantes y excepciones (opcional).
 Una sección de sentencias ejecutables (obligatoria).
 Una sección de manejadores de excepciones (opcional).
Si el código del Trigger no requiere variables definidas, no es necesario incluir las palabras clave BEGIN y END; Se añaden implícitamente.

Ejemplos:
1. Si el Trigger no requiere sentencias declarativas, las palabras clave BEGIN END son opcionales.
Trigger When-Validate-Item:
IF :ORDER_ITEMS.unit_price IS NULL THEN
:ORDER_ITEMS.unit_price := :PRODUCTS.list_price;
END IF;
calculate_total; -- User-named procedure
---
2. Si el activador requiere declaraciones, las palabras clave BEGIN END son obligatorias.
Trigger When-Button-Pressed:
DECLARE
vn_discount NUMBER;
BEGIN
vn_discount := calculate_discount(:ORDER_ITEMS.product_id,:ORDER_ITEMS.quantity);
MESSAGE('Discount: '||TO_CHAR(vn_discount));
END;
---
3.  Para manejar Excepciones, se debe incluir la sección EXCEPTION.
Trigger Post-Insert:
BEGIN
INSERT INTO LOG_TAB(LOG_VAL, LOG_USER)
VALUES(:DEPARTMENTS.department_id,:GLOBAL.username);

EXCEPTION
WHEN OTHERS THEN
MESSAGE('Error! ',||SQLERRM);
END;
---
Uso de variables en Triggers.
En los Triggers y subprogramas, Forms Builder generalmente acepta dos tipos de variables para almacenar valores:
 Variables de PL/SQL: Deben declararse en una sección DECLARE, permanecen disponibles hasta el final del bloque de declaración. No tienen prefijo de dos puntos. Si se declara en un paquete PL/SQL, una variable es accesible a través de todos los Triggers que acceden a este paquete.
 Variables de Forms Builder: Tipos de variables mantenidas por Forms Builder. Estos son vistas por PL/SQL como variables externas, y requieren un prefijo de dos puntos (:) para distinguirlos de los objetos PL/SQL (excepto cuando su nombre se pasa como una cadena de caracteres a un subprograma). Las variables de Forms Builder no se declaran formalmente en una sección DECLARE y pueden existir fuera del ámbito de un bloque PL/SQL.

Las Variables de Form Builder.
Tipo
Propósito
Sintaxis
ITems
Presentación y Interacción con el Usuario.
:block_name.item_name
Variables Globales
Variable tipo carácter la cual permanece durante toda la sección.
:GLOBAl.variable_name
Variables del Sistema
Contienen informaciones del Estatus, Estado y Control del Form.
:SYSTEM.variable_name
Parámetros
Sirven para pasar/recibir valores a/desde otros Módulos Forms.
:PARAMETER.name
 Ámbito o Alcance (Scope).
Tipos
Alcance
Uso
Items (text, list, check box, y demás)
Módulo Form y Menú Actual.
Presentación e Interacción con el Usuario.
Variables Globales
Todos los módulos Forms de una sección.
Almacenar valores tipo carácter durante toda la sección.
Variables del Sistema
Módulo Form y Menú Actual.
Informaciones del Estatus, Estado y Control del Form.

Note: El contenido de las variables del sistema están en MAYÚSCULAS (UPPERCASE).

Parámetros
Módulo Form Actual.
Pasar/Recibir valores a/desde otros Módulos Forms.
En cada uno de los siguientes ejemplos, observe que las variables de Forms Builder son precedidas por dos puntos (:) y los componentes de su nombre son separados por un punto (.). Cada ejemplo es tan solo un segmento de un Trigger.
Ejemplos.
1. Al referirnos a un Item debemos hacerlo con el nombre de su bloque como prefijo, esto evita ambigüedad cuando Items con el mismo nombre existen en bloques diferentes. También resulta más eficiente referirnos a una Item con el uso de su bloque como prefijo que hacerlo solo con el nombre del Item:
:BLOCK3.product_id := :BLOCK2.product_id;
2. Las referencias a variables globales deben ser prefijadas por la palabra GLOBAL. Estas variables pueden ser creadas como resultado de una asignación:
:GLOBAL.customer_id := :BLOCK1.id;
3. Las referencias a las variables del sistema deben ser prefijadas por la palabra SYSTEM y el contenido debe estar en mayúsculas ('NORMAL', no 'normal'):
IF :SYSTEM.MODE = 'NORMAL' THEN
ok_to_leave_block := TRUE;
END IF;
4. Los parámetros definidos en tiempo de diseño tienen el prefijo PARAMETER:
IF :PARAMETER.starting_point = THEN
GO_BLOCK('BLOCK2');  -- built-in procedure
END IF;
Inicializar variables globales con un valor predeterminado(Default Value).
Puede utilizar la función DEFAULT_VALUE para asignar un valor a una variable global. Forms Builder crea la variable global si no existe. Si el valor de la variable indicada no es NULLDEFAULT_VALUE no hace nada. El ejemplo siguiente crea una variable global denominada country y la inicializa con el valor TURKEY:
Default_Value('TURKEY', 'GLOBAL.country');
Eliminación de variables globales.
Puede utilizar ERASE para eliminar una variable global. Los globales requieren 255 bytes de almacenamiento. Para garantizar que el rendimiento no se vea afectado más de lo necesario, borre siempre cualquier variable global cuando ya no sea necesaria.
Ejemplo:
ERASE('GLOBAL.variable_name');
______________________________________________________________________________________
Agregando Funcionalidad con Subprogramas Incorporados (Built-In).
Forms Builder proporciona un conjunto de subprogramas predefinidos como parte del producto. Estos subprogramas se definen en paquetes integrados como un procedimiento o una función.
Los subprogramas integrados de Forms Builder pertenecen a uno de los siguientes:
Paquete Estándar de Extensiones (Standard Extensions Package): Estos Built-In están integrados en el conjunto de comandos PL/SQL Estándar de Forms Builder. Pueden ser llamados directamente, sin ningún prefijo de paquete. Usted puede utilizar más de cien built-ins estándar.
Ejemplo: EXECUTE_QUERY;
Otros Paquetes de Forms Builder: Los subprogramas de otros paquetes integrados proporcionan funcionalidad relacionada con una característica soportada en particular. Estos requieren el nombre del paquete como un prefijo cuando se llama.
Ejemplo: ORA_JAVA.CLEAR_EXCEPTION;
Todos los subprogramas incorporados utilizados en esta publicación forman parte del paquete de extensiones estándar

Además de las extensiones estándar, Forms Builder proporciona los siguientes paquetes:
Paquete
Descripción
DDE
Proporciona soporte para intercambio dinámico de datos (Dynamic Data Exchange).
DEBUG
Proporciona built-ins para Depurar (Debugging) Unidades de Programas de PL/SQL.
EXEC_SQL
Proporciona built-ins  para ejecutar SQL Dinámico dentro de procedimientos de PL/SQL.
FBEAN
Proporciona built-ins para interactuar con los Java Beans del lado del cliente.
FTREE
Proporciona built-ins para manipular Items de Arboles Jerárquicos.
OLE2
Proporciona un API PL/SQL que permite crear, manipular y acceder a atributos de objetos de automatización OLE2.
ORA_FFI
Proporciona built-ins que permiten llamar funciones externas (en C) desde PL/SQL.
ORA_JAVA
Permite llamar procedimientos de Java desde PL/SQL.
ORA_NLS
Permite extraer informaciones de alto nivel acerca del lenguaje/idioma actual de su entorno.
ORA_PROF
Proporciona built-ins para afinar (tuning) Unidades de Programas de PL/SQL.
TEXT_IO
Proporciona built-ins que permiten leer y escribir informaciones en archivos del disco duro.
TOOL_ENV
Permite interacturar con variables de entorno de Oracle.
TOOL_ERR
Permite acceder y manipular pilas de errores (error stack) generados por otros paquetes como Debug.
TOOL_RES
Proporciona built-ins para manipular archivos de recursos.
WEB
Proporciona built-ins para el Entorno Web.
Nota: Algunos de estos paquetes, como OLE2, ORA_FFI y TEXT_IO, funcionan en el lado del servidor de aplicaciones, no en el lado del cliente. Por ejemplo, TOOL_ENV le permite obtener y establecer variables de entorno en el servidor de aplicaciones. Para interactuar con el cliente, necesitará proporcionar una funcionalidad similar en un JavaBean.
______________________________________________________________________________________
Límites/Restricciones de Uso.
Puede llamar built-ins en cualquier Trigger o Subprograma en cual utilice PL/SQL. Sin embargo, algunos built-ins proporcionan funcionalidad que no está permitida en ciertos tipos de Triggers. Es por esto que los built-ins se dividen en dos grupos:
 Sin Restricciones (Unrestricted built-ins): Estos no afectan a la navegación lógica o física y se pueden llamar desde cualquier Trigger o Subprograma.
 Con Restricciones (Restricted built-ins): Estos afectan a la navegación en el Form, ya sea por navegación por pantalla externa o navegación interna. Puede llamarlos sólo desde Triggers mientras no se está produciendo ninguna navegación interna. La Ayuda en línea especifica qué grupos de built-ins pueden utilizarse en cada Trigger .
Llamar a un Restricted built-ins desde un Trigger de navegación compila correctamente pero provoca un error en tiempo de ejecución. Por ejemplo, puede compilar un Trigger Pre-Text-Item que llama GO_ITEM, pero cuando el Trigger se activa en tiempo de ejecución produce el error FRM-40737.

Uso de definiciones built-ins.
Cuando está codificando un Trigger o una unidad de programa, Forms Builder le permite buscar definiciones built-ins y, opcionalmente, copiar sus nombres y prototipos de argumentos en su código.
1. Coloque el cursor en el punto de su código PL/SQL (en el Editor PL/SQL) donde se va a llamar un subprograma built-ins.
2. Expanda el nodo Built-in Packages en el Navegador y seleccione el procedimiento o la función que necesita usar (normalmente de Extensiones Estándar).
3. Si desea copiar los argumentos o el nombre del prototipo built-ins, o ambos; del menú seleccione Edit>Paste Name o Edit>Paste Arguments (Pegar argumentos incluye tanto el nombre built-ins como sus argumentos).
4. La definición del built-in se copia en la posición del cursor en el Editor PL/SQL, donde puede insertar sus propios valores para los argumentos, según sea necesario.

Nota: Un subprograma puede ser un procedimiento o una función. Por lo tanto, los subprogramas built-ins se llaman de dos maneras distintas:
 Procedimientos built-ins: Son llamados como una sentencia completa en un Trigger o Unidad de Programa con sus argumentos obligatorios.
 Funciones built-ins: Son llamados como parte de una sentencia, de modo que el valor que retornan sea asignado a alguna variable. A su vez debe incluir cualquier argumento obligatorio.
Ejemplo:
SHOW_LOV es una función (built-ins) que devuelve un valor booleano (el cual indica si el usuario ha elegido un valor del LOV). Puede ser llamado como parte de una asignación a una variable booleana.
DECLARE
customer_chosen BOOLEAN;
BEGIN
customer_chosen := SHOW_LOV('customer_list');
. . .
---
Algunos built-ins Útiles.
La tabla de la página siguiente describe algunos built-ins que se pueden utilizar en Triggers para agregar funcionalidad a los Items. Estos serán discutidos en futuras publicaciones.
Built-in
Descripción
Procedimiento
EDIT_TEXTITEM
Invoca el Editor de texto para el actual Text Item.
Procedimiento
ENTER_QUERY
Limpia el bloque actual y crea un registro de ejemplo. Los operadores pueden especificar condiciones de consulta antes de ejecutar la consulta con un comando de menú o botón. Si hay cambios en la confirmación, Forms Builder le pide al operador que los confirme antes de continuar con el proceso ENTER_QUERY..
Procedimiento
EXECUTE_QUERY
Limpia el bloque actual, abre una consulta y extrae una serie de registros seleccionados. Si hay cambios para confirmar, Forms Builder le pide al operador que los confirme antes de continuar con el proceso EXECUTE_QUERY.
Procedimiento
EXIT_FORM
Si está modo normal, sale del Form actual; Si está el modo ENTER-QUERY, cancela la consulta.
Función
GET_ITEM_PROPERTY
Retorna el valor de la propiedad especificada del Item en cuestión.
Procediento
GO_BLOCK
Navega hacia el bloque especificado.
Procedimiento
GO_ITEM
Navega al Item especificado.
Procedimiento
HIDE_VIEW
Oculta el Canvas especificado.
Procedimiento
LIST_VALUES
Invoca el LOV atado al Item actual.
Procedimiento
MESSAGE
Muestra el texto especificado en la linea de mensajes.
Procedimiento
SET_ITEM_PROPERTY
Cambia el valor de la propiedad indicada para el Item especificado.
Función
SHOW_ALERT
Muestra la alerta dada y devuelve un valor numérico cuando el operador presiona algún botón de la alerta.
Procedimiento
SHOW_EDITOR
Muestra el editor especificado en las coordenadas dadas y pasa una cadena al editor, o recupera una cadena existente del editor.
Función
SHOW_LOV
Invoca el LOV especificado y devuelve un valor booleano que indica si el usuario ha seleccionado un valor de la lista.
Procedimiento
SHOW_VIEW
Muestra el Canvas indicado en las coordenadas especificadas por la Posición X y Posición Y establecidas en las propiedades del Canvas. Si la vista ya está tomada, SHOW_VIEW lo eleva frente a cualquier otra vista en la misma ventana.
______________________________________________________________________________________
Usando Triggers.
When-Button-Pressed Trigger:
Este Trigger se activa cuando el usuario hace clic en un botón. Puede definir el Trigger en un Item individual o si es necesario en niveles más altos.
When-Button-Pressed acepta tanto built-ins restringidos como no restringidos. Puede utilizar los botones para proporcionar una amplia gama de funciones para los usuarios. Estas funciones incluyen:
 Navegación.
 Mostrar LOVs.
 Invocación de cálculos y otras funciones.
Ejemplo:
El Stock_Button en el bloque CONTROL está situado en un Canvas TOOLBAR del Form FRM_ORDERS. Cuando se pulsa, el botón activa el Trigger When-Button-Pressed. El código da como resultado la navegación al bloque INVENTORIES y la ejecución de una consulta en dicho bloque.
GO_BLOCK('INVENTORIES');
EXECUTE_QUERY;
---
When-Window-Closed Trigger:
Este Trigger se activa cuando cierra una ventana utilizando un comando de cierre específico del gestor de ventanas. Debe definir este Trigger en el nivel de Form.
El Trigger When-Window-Closed acepta tanto built-ins restringidos como no restringidos.
Utilice este Trigger para cerrar una ventana de forma programática cuando el operador emita el comando Close del gestor de ventanas. Forms Builder no cierra la ventana cuando el operador emite un comando de cierre específico del gestor de ventanas; Sólo activa el Trigger When-Window-Closed. Es responsabilidad del desarrollador escribir la funcionalidad requerida en este Trigger. Puede cerrar una ventana con los subprogramas built-ins HIDE_WINDOW, SET_WINDOW_PROPERTY y EXIT_FORM. No puede ocultar la ventana que contiene el Item actual.
Ejemplo:
Cuando el operador emite el comando Close del gestor de ventanas, el siguiente código en el Trigger When-Window-Closed cierra la ventana WIN_INVENTORY al establecer la propiedad VISIBLE como FALSE.
GO_ITEM('ORDERS.ORDER_ID');
SET_WINDOW_PROPERTY('WIN_INVENTORY',VISIBLE,PROPERTY_FALSE);
______________________________________________________________________________________
Ajunto el Módulo Form creado para esta práctica: Link.
______________________________________________________________________________________
Fuente: Oracle Forms Developer 10g: Build Internet Applications.