miércoles, 24 de mayo de 2017

Depurando Triggers

Objetivos:

 Describir los componentes de la Consola de Depuración (Debug Console).
 Utilizar el botón Run Form Debug.
 Depurar código PL/SQL.

NOTA: Usamos como ejemplo la Base de Datos: ORCL, la cual viene por defecto en cualquier versión de ORACLE.
______________________________________________________________________________________
El Proceso de Depuración.
A medida que empiece a definir Triggers y a agregar código al Form, encontrará que a veces obtiene resultados incorrectos o inesperados. En una aplicación grande, puede ser difícil determinar la fuente del problema.

Puede utilizar el depurador integrado de PL/SQL en Forms Builder para localizar y corregir errores de codificación. A continuación mostramos como.

Puede supervisar y depurar Triggers de varias maneras:
 Compilación: Los errores de sintaxis y de referencia de objetos (incluidas las referencias a objetos de base de datos) se informan al compilar un Trigger o generar el módulo Form. Esto le permite corregir estos problemas en el Editor PL/SQL antes de ejecutar la aplicación.

 Ejecutando el Form con el parámetro debug_messages = Yes: En el modo de depuración, puede solicitar que se muestren mensajes para indicar cuándo se disparan los Triggers. Esto le ayuda a ver si ciertos Triggers se están disparando, su origen y nivel, y el momento en que disparan. Si se produce un error, puede ver el último Trigger que disparó y así reducir el alcance del origen del error.

 Invocando del depurador de PL/SQL (PL/SQL Debugger): Puede invoca el depurador de Forms Builder haciendo clic en Run Form Debug en la barra de herramientas.

Con el depurador puede supervisar la ejecución del código dentro de un Trigger (y otras unidades de programa). Puede recorrer el código línea por línea, y puede supervisar subprogramas y variables invocadas a medida que lo hace. También puede modificar variables a medida que se ejecuta el Form, lo que le permite comprobar cómo varios cambios en los valores de los Items y los valores de las variables afectarán a su aplicación.
______________________________________________________________________________________
La Consola de Depuración.
La consola de depuración es un espacio de trabajo en Forms Builder que le permite ver varios aspectos del Form en ejecución y su entorno. Puede mostrar la consola de depuración seleccionando en el menú: Debug>Debug Console. Se muestra automáticamente cuando encuentra un punto de interrupción (Breakpoint )  en un Form el cual se ejecuta en modo de depuración.

Dentro de la consola, puede mostrar varios tipos de paneles: Pila (Stack), Variables, Vigilancia, Valores del Form, Breakpoints, Paquetes de PL/SQL, Variables globales y de sistema. Puede cambiar el tamaño de la consola de depuración y cualquiera de los paneles que se muestran en ella.
Puede elegir qué paneles mostrar o cerrar haciendo clic en los botones de la barra de herramientas de la Consola de depuración o seleccionando Debug>Debug Windows en el menú. Al mostrar y ocultar paneles dentro de la consola, los paneles se expanden y se contraen automáticamente para llenar la consola.

Puede desacoplar cualquiera de los paneles para mostrarlos fuera de la Consola de depuración haciendo clic en la flecha hacia arriba que se encuentra en la parte superior derecha del panel; Para re-acoplar el panel haga clic en la flecha hacia abajo.

Si hace clic con el botón derecho en el área situada junto a la flecha de acoplamiento/desacoplamiento, aparecerá un menú emergente que le permitirá ocultar, acoplar o desacoplar el panel.





La Consola de Depuración: Panel de Pila (Stack Panel).
La Pila de Llamadas (Stack Call) representa la cadena de subprogramas que comienza desde el punto de entrada inicial hasta el subprograma en ejecución. En la imagen anterior, el subprograma que se encuentra en ejecución es EMPLOYEES.SAL.CHECK_PCT, el cual fue llamado por EMPLOYEES.SAL.GET_SAL, el cual a su vez fue llamado desde un Trigger When-Button-Pressed (punto de entrada inicial de la pila de llamadas actual). Como puede ver, los marcos se enumeran en el orden inverso en el que se ejecutaron los subprogramas. El primer cuadro está en la parte inferior de la pila, mientras que el último cuadro está en la parte superior.

Un Marco de Pila o Stack Frame contiene información sobre el subprograma correspondiente, incluyendo el nombre del módulo, el nombre del paquete si existe, el nombre del subprograma y la siguiente instrucción que se va a ejecutar. Por ejemplo, EMPLOYEES.SAL.GET_SAL::19 indica que la línea 19 del subprograma GET_SAL del paquete SAL contenida en el módulo EMPLOYEES se ejecutará cuando la aplicación vuelva a ese subprograma. Cuando esto ocurra, el marco EMPLOYEES.SAL.CHECK_PCT se eliminará de la pila porque el subprograma EMPLOYEES.SAL.CHECK_PCT ha terminado de ejecutarse.

La Consola de Depuración: Panel de Variables (Variables Panel).
El Panel de Variables muestra las variables (y sus valores) del Stack Frame actual. Hay una lista emergente desde la que puede seleccionar el Stack Frame cuyas variables desea ver. También puede cambiar las variables mostradas en el Panel de Variables haciendo clic en un Stack Frame diferente del Stack Panel. Esto no cambia el orden de ejecución de las sentencias del programa, sólo cambia la información que se muestra en la consola de depuración.

Una característica del depurador es que cuando se suspende el Form, puede cambiar los valores de las variables haciendo clic en la columna de valores e ingresando un nuevo valor. Cuando el programa continúa, utilizará el nuevo valor que ha introducido, de modo que pueda probar el efecto de cambiar un valor en el resultado final.

Algunas variables, como parámetros, no pueden modificarse. Al hacer clic en una variable de sólo lectura, se resalta toda la celda. Al hacer clic en una variable modificable se resaltará sólo el valor, no toda la celda.

La Consola de Depuración: Panel de Vigilancia.
Una aplicación en ejecución puede tener decenas de variables que se pueden mostrar en varios paneles de la consola de depuración, pero puede haber muy pocas que necesita supervisar. El Panel de Vigilancia (Watch Panel) proporciona un lugar central donde puede realizar un seguimiento de las variables válidas que especifique. Solamente las variables que resuelven a un valor escalar son válidas. Las variables de un paquete almacenado no son válidas.

Una vez que se muestra una variable en la Lista de Vigilancia, cuando la ejecución se suspende en una ubicación diferente, los valores de la variable en la lista se actualizan según sea necesario si están disponibles en el contexto de ejecución actual. Si una variable no está definida en el subprograma en ejecución, #### aparece en la celda en lugar de un valor.

Para agregar una variable al Panel de Vigilancia, realice los pasos siguientes:
1. Abra la ventana donde se muestra la variable.
2. Seleccione la variable que desea agregar.
3. Haga clic con el botón derecho del ratón en la selección y seleccione Add to Watch.
Para eliminar un Item del Panel de Vigilancia:
 Selecciónelo en el Panel de Vigilancia, haga clic con el botón derecho del ratón y elija Remove.
 Para borrar todo, elija Remove all.

La Consola de Depuración: Panel de Valores del Form.
Puede utilizar el Panel de Valores del Form (Form Values Panel) para mostrar los valores de todos los Items y Parámetros en los módulos que se están ejecutando actualmente. Cambia entre una vista de Items y una vista de parámetros haciendo clic en las pestañas correspondientes del panel.

Puede cambiar los valores de los Items modificables para probar los efectos de dichos cambios. Si el valor es de sólo lectura, como es el caso de los Display Items, la celda completa se resalta cuando intenta editarlo. Si el valor es modificable, sólo se resalta el valor en la celda.

La Consola de Depuración: Panel de Paquetes PL/SQL.
Utilice el Panel Paquetes de PL/SQL para examinar los paquetes que han sido instanciados. Se enumeran tanto las variables globales del paquete como las definidas en la especificación del mismo. Sólo puede ver los paquetes mientras el proceso de ejecución está ejecutando PL/SQL. También puede seleccionar un botón de opción para determinar qué paquetes se muestran: Cliente, Servidor o Todos.

La Consola de Depuración: Panel de Variables Globales/Sistema.
Utilice el Panel de Variables Globales o de Sistema para mostrar los valores de las Variables del Sistema, Globales y de Línea de Comandos. Puede cambiar entre estos tipos de variables haciendo clic en las pestañas correspondientes del panel.

Las variables de Línea de Comandos y la mayoría de las variables del sistema son de sólo lectura. Las únicas variables de sistema modificables son DATE_THRESHOLD, EFFECTIVE_DATE, MESSAGE_LEVEL y SUPPRESS_WORKING. Puede modificar variables globales para que los nuevos valores serán utilizados posteriormente por la aplicación en ejecución.

La Consola de Depuración: Panel de Breakpoints.
El Breakpoints Panel consta de dos pestañas:
 La Pestaña de Breakpoints muestra los puntos establecidos en el código durante la sesión actual de Forms Builder, en orden de creación.
---Nombre del Trigger o Unidad de Programa.
---Número de línea donde se establece el punto.
---Una casilla de verificación para activar o desactivar temporalmente el punto.
 Habilita la navegación al código fuente donde está establecido el punto:
---Haciendo doble clic en el nombre del punto
---Resaltar (un solo clic), y luego Right-Clic para elegir View Source Code en el menú emergente. Desde este menú emergente, también puede eliminar el o los puntos.
 La Pestaña Break On Exceptions muestra una lista de las excepciones del sistema utilizadas con frecuencia que puede utilizar durante la depuración. La pantalla incluye:
---Nombre de la excepción.
---Número de error ORA asociado.
---Una casilla de verificación para activar o desactivar  el punto.
______________________________________________________________________________________
Establecimiento Breakpoints en el Código Cliente.
Se establecen Breakpoints en el código para que en Modo de Depuración Form detenga la ejecución cada vez que encuentre uno de estos puntos dando así el control al Depurador de Forms Builder, permitiendole supervisar o cambiar el entorno en ese punto. Cuando establece un punto, este permanece hasta que salga de la sesión Forms Builder. Puede habilitar y inhabilitar puntos de interrupción según sea necesario marcando o desmarcando la casilla de verificación en el Breakpoints Panel de la Consola de Depuración.

Sólo puede establecer puntos en líneas de código ejecutables, como asignaciones o llamadas de subprograma.
Maneras de establecer Breakpoints:
 Haciendo doble clic a la izquierda de una línea de código en el Editor PL/SQL.
 Haciendo clic con el botón secundario en una línea de código y seleccionando Insert/Remove Breakpoint.
 Seleccionando Debug>Insert/Remove Breakpoint desde el menú principal.
Realizar la misma acción nuevamente desactiva el Breakpoint. También puede eliminar uno o todos los puntos mediante el Breakpoints Panel.

Establecimiento Breakpoints en un Código Almacenado (Stored Code).
Si está conectado a la base de datos, puede establecer Breakpoints en paquetes, procedimientos y funciones, tal como lo hace en los subprogramas del lado del cliente.
Para hacerlo:
1. Expanda el nodo Database Objects.
2. Navegue hasta el subprograma almacenado.
3. Carguelo en el Editor de PL/SQL.

Nota: No puede establecer Breakpoints en Triggers de base de datos o librerías de PL/SQL almacenadas.

Si la Unidad de Programa no aparece en un Stack Frame o si no puede verlo mientras pasa a través de su código, es porque el mismo no se ha compilado con la información de depuración incluida. Existen tres métodos para compilar la unidad de programa almacenada con información de depuración:
 Cree el procedimiento almacenado en Forms Builder, de esta manera se crea con información de depuración.
 Utilice ALTER SESSION SET PLSQL_DEBUG = TRUE; antes de crear el procedimiento almacenado.
 Recompile manualmente la unidad de programa PL/SQL existente utilizando:
ALTER PROCEDURE <schema.procedure> COMPILE DEBUG;

Consejos Generales (Tips) para resolver Problemas con los Triggers.
Asegúrese de que está conectado a la base de datos (correcta) cuando compila Triggers que contienen SQL. Los mensajes de error pueden ser engañosos.

El Editor PL/SQL informa cual es la línea en se produce la falla, pero el error puede deberse a una dependencia de una línea de código anterior.

Los puntos y coma perdidos (;) y las comillas no coincidentes son una causa común de errores de compilación. Compruebe si un error de compilación no da una indicación obvia al problema.

Si un Trigger parece disparar con demasiada frecuencia, en un bloque o Item incorrecto del Form, debe verificar si dicho Trigger está definido en el nivel requerido. Por ejemplo, un Trigger When-Validate-Item a nivel de Form se activa para cada Item cambiado en el Form. Para comprobar esto, puede ejecutar el Form con los Mensajes de Depuración Activados (Debug Messages On).

Para los Triggers que rellenan otros Items, asegúrese de que pertenezcan al objeto en el que se producirá el evento de disparo, no en los Items que se van a rellenar.

Ejecución de un Form en Modo de Depuración.
En Forms Builder el botón Run Form Debug ejecuta la aplicación en modo de depuración. Cuando se encuentra un Breakpoint y el control pasa al depurador, puede utilizar ciertos comandos para reanudar la ejecución o recorrer el código de varias maneras y así ver cómo cada línea afecta a la aplicación y al entorno.

Al igual que cuando ejecuta un Form con el botón Run Form (), el botón Run Form Debug () ejecuta la aplicación en un entorno de tres niveles. Lo hace tomando su configuración de la ventana de Preferencias (Preferences) a la que accede seleccionando Edit>Preferences desde el menú principal y haciendo clic en la pestaña Runtime.
Introduzca la dirección URL del Servidor de Aplicaciones donde desea ejecutar el Form, la cual a su vez se ejecuta en el explorador predeterminado, a menos que especifique un navegador diferente en Ubicación del explorador Web. Si lo desea, puede usar una configuración especifica, con el parámetro config.

Ejemplo de un URL del Servidor de Aplicaciones:
Http://mymachine:8889/forms90/f90servlet?Config=test
Donde test es una sección en el archivo de configuración Forms Web (formsweb.cfg de forma predeterminada) que especifica la configuración a utilizar.

Pasando a Través del Código.
Una vez que el programa encuentra un Breakpoint, el Depurador PL/SQL le permite recorrer las unidades de programa de varias maneras para examinar el entorno a medida que avanza el programa, esto se logra utilizando los siguientes botones:
 Step Into: Ejecuta la siguiente instrucción.
 Step Over: Ejecuta la siguiente instrucción sin entrar en un subprograma anidado.
 Step Out: Completa el subprograma anidado y pasa a la siguiente sentencia ejecutable en el programa del que fue llamado.
 Go: Reanuda la ejecución hasta que el programa termina de manera normal o hasta que sea interrumpido por el siguiente Breakpoint.
 Pause: Hace una pausa en la ejecución del código PL/SQL en ejecución para permitirle examinar el entorno. Por ejemplo, puede comprobar los valores de las variables.
 Stop: Finaliza la depuración y la ejecución del programa por completo; La consola de depuración y todos los paneles de depuración abiertos se cierran y la ejecución de la aplicación finaliza.
Otro comando, disponible en el menú de depuración, es Run to Cursor. Cuando inserta el cursor del ratón en una línea de código en el Editor PL/SQL (haciendo clic en él), el comando Run to Cursor ejecuta todo el código hasta esa línea, luego se detiene y marca esa línea como la siguiente línea ejecutable de código.
______________________________________________________________________________________
Ejemplo de Depuración.
Este ejemplo simple demuestra algunas de las características básicas disponibles en el depurador. El Form de ejemplo consta de dos Text Items, un Display Item y un botón con un Trigger When-Button-Pressed. El código funciona de la siguiente manera:
1. El usuario debe introducir valores numéricos en los Text Items: InferiorSuperior y luego presionar el Botón Generar.
2. El Trigger (del Botón Generar) valida que ambos campos contengan valores, para luego llamar al procedimiento proc_generate.
3. El procedimiento proc_generate se encarga de llamar a la función func_between pasándole los valores contenidos en los Text Items antes mencionados a los parámetros p_up y p_down.
4. La función func_between invoca a su vez a la función VALUE del paquete DBMS_RANDOM (de Base de Datos), para luego retornar el valor obtenido truncado (sin decimales).
5. Al finalizar el proceso de la función func_between, el Control retorna al procedimiento proc_generate donde se procede a limpiar los valores introducidos por el usuario y luego asignar al Display Item el valor obtenido.

Ejemplo:
Trigger When-Button-Pressed:
BEGIN
IF :BLCK_CONTROL.LOWER_BOUND IS NULL OR :BLCK_CONTROL.UPPER_BOUND IS NULL THEN
MESSAGE('Debe especificar tanto el valor inferior como el superior.');
MESSAGE('Debe especificar tanto el valor inferior como el superior.');
ELSE
proc_generate;
END IF;
END;
---
Procedimiento proc_generate:
PROCEDURE proc_generate IS
v_result NUMBER;
v_up NUMBER;
v_down NUMBER;
BEGIN
  v_up := :BLCK_CONTROL.UPPER_BOUND;
  v_down := :BLCK_CONTROL.LOWER_BOUND;
  v_result := func_between(v_up, v_down);

  :BLCK_CONTROL.UPPER_BOUND := NULL;
  :BLCK_CONTROL.LOWER_BOUND := NULL;

:BLCK_CONTROL.RESULT := v_result;
END;
---
Función func_between:
FUNCTION func_between(
p_up IN NUMBER,
p_down IN NUMBER
    ) RETURN NUMBER IS
v_total NUMBER := 0;
BEGIN
v_total := DBMS_RANDOM.VALUE(p_down,p_up);
RETURN TRUNC(v_total);
END func_between;
---
Proceso de Depuración:
1. Establezco mi Breakpoint y ejecuto y Form con el Botón: Run Form Debug.
2. Una vez ejecutada la aplicación introduzco los valores 15 y 39 para los Límites Inferior y Superior respectivamente, luego presiono el Botón Generar:
3. Form Builder ejecuta el código contenido en el Trigger y detiene el proceso una vez encuentra el Breakpoint antes establecido:
Notar como en el Panel Form Values es posible visualizar los valores introducidos por el usuario.
4. Luego con el ayuda del botón Step Into:(Ubicado en la barra de Herramientas de Form en modo de depuración) es posible avanzar (Flecha Amarilla:) a través del código a medida que avanza la ejecución:
Notar como cambia la vista del código al hacer clic en los Stack Frames.
5. Para continuar solo tenemos que seguir recorriendo el código con los botones disponibles en la barra de herramientas de form en modo de depuración:
La anterior imagen muestra el Panel de la variables del bloque que esta siendo recorrido.
Resultado:
______________________________________________________________________________________
Ajunto el Módulo Form creado para esta práctica: Link.
______________________________________________________________________________________
Fuente: Oracle Forms Developer 10g: Build Internet Applications.

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.