GUIA 3 PARTE II Introducción a PL/SQL PL/SQL proviene de Procedural Language (lenguaje procedural)/ Structured Query Language (Lenguaje de consulta estructurado). PL/SQL ofrece un conjunto de comandos procedurales (sentencias IF, bucles, asignaciones), organizado dentro de bloques (como se explica más adelante), que complementan y amplían el alcance de SQL. Construyendo bloques de programas PL/SQL PL/SQL es un lenguaje de bloques estructurados. Un bloque PL/SQL está definido por las palabras clave DECLARE, BEGIN, EXCEPTION, y END, las que separan el bloque en tres secciones: 1. Declarativa: sentencias que declaran las variables, constantes y otros elementos de código, los que pueden ser utilizados dentro de ese bloque 2. Ejecutables: las sentencias que se ejecutan cuando el bloque se corre 3. El manejo de excepciones: una sección especialmente estructurada que puede utilizar para "capturar" o atrapar, cualquier excepción que se produce cuando se corre la sección ejecutable Sólo la sección ejecutable es requerida. Usted puede no declarar nada en un bloque, y no tiene que capturar las excepciones producidas en ese bloque. Un bloque en sí mismo es una instrucción ejecutable, por lo que los bloques se pueden anidar dentro de otros bloques. Ejemplos: El clásico bloque "¡Hola Mundo!" contiene una sección ejecutable que llama al procedimiento DBMS_OUTPUT.PUT_LINE para mostrar texto en la pantalla: BEGIN DBMS_OUTPUT.put_line ('¡Hola Mundo!'); END; El bloque del siguiente ejemplo declara una variable de tipo VARCHAR2 (cadena) con una longitud máxima de 100 bytes para contener la cadena "¡Hola Mundo!". DBMS_OUTPUT.PUT_LINE acepta entonces la variable, en lugar de la cadena literal, para mostrar: DECLARE l_mensaje VARCHAR2 (100) := '¡Hola Mundo!'; BEGIN DBMS_OUTPUT.put_line (l_mensaje); END; Este siguiente bloque de ejemplo agrega una sección EXCEPTION que atrapa cualquier excepción (WHEN OTHERS) que podría producirse y muestra el mensaje de error, el cual es devuelto por la función (provista por Oracle) SQLERRM (). DECLARE l_mensaje VARCHAR2 (100) := '¡Hola Mundo!'; BEGIN DBMS_OUTPUT.put_line (l_mensaje); EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.put_line (SQLERRM); END; El siguiente bloque de ejemplo muestra la habilidad de PL/SQL para anidar bloques dentro otros bloques, así como el uso del operador de concatenación (||) con el que se unen varias cadenas. DECLARE l_mensaje VARCHAR2 (100) := '¡Hola'; BEGIN DECLARE l_mensaje2 VARCHAR2 (100) := l_mensaje || ' Mundo!'; BEGIN DBMS_OUTPUT.put_line (l_mensaje2); END; EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.put_line(DBMS_UTILITY.format_error_stack); END; Ejecución de Bloques PL/SQL Una vez que usted ha escrito un bloque de código PL/SQL, puede ejecutarlo (correrlo). Hay muchas herramientas diferentes ejecutar código PL/SQL. La más básica es el SQL*Plus, una interfaz de línea de comandos para ejecutar sentencias SQL, así como bloques PL/SQL. La figura 1 muestra un ejemplo de ejecución de mi más simple bloque "¡Hola Mundo!" en SQL*Plus. Figura 1: ejecución de Hola Mundo! en SQL*Plus Lo primero que se hace después de conectarme con la base de datos a través de SQL*Plus es habilitar la salida del servidor (SET SERVEROUTPUT ON), así las llamadas a DBMS_OUTPUT.PUT_LINE dará lugar a la presentación del texto en la pantalla. Luego escribo el código que constituye mi bloque. Finalmente entro una barra (/) para indicar a SQL*Plus que ejecute este bloque. SQL*Plus entonces ejecuta el bloque y muestra "¡Hola Mundo!" en la pantalla. SQL*Plus es proporcionado por Oracle como una especie de mínimo común denominador ambiente donde ejecutar sentencias SQL y bloques PL/SQL. Mientras algunos desarrolladores siguen confiando exclusivamente en SQL*Plus, la mayoría utiliza un entorno de desarrollo integrado (IDE). Variables y constantes • Tipos de datos* en PL/SQL: NUMBER, CHAR, VARCHAR/VARCHAR2, DATE, BOOLEAN, entre otros. • La sintaxis para declarar variables o constantes es: • * NUMBER, CHAR,VARCHAR/VARCHAR2 tienen precisión. • El operador de asignación es := y el de igualdad es =. El alcance o visibilidad de las variables sigue estas reglas: 1. Una variable es visible en el bloque en el cual se declara y en todos sus sub-bloques, a menos que se aplique la regla 2. 2. Si se declara una variable en un sub-bloque con el mismo nombre que una variable del bloque contenedor, la variable del sub-bloque es la que tiene prioridad en el sub-bloque. Ejercicio Crear la siguiente tabla DROP TABLE emp; CREATE TABLE emp( cod NUMBER(8) PRIMARY KEY, nom VARCHAR2(8) NOT NULL, fecha_ing DATE, sueldo NUMBER(8) CHECK(sueldo > 0) ); Procedimientos Todos los bloques que hemos ejecutado hasta ahora son "anónimos" - ellos no tienen nombres. Si el uso de bloques anónimos fuera la única manera con que usted podría organizar sus sentencias, sería muy difícil de utilizar PL/SQL para construir una gran, aplicación compleja. En cambio, PL/SQL admite la definición de bloques de código nombrados, también conocido como subprogramas. Los subprogramas pueden ser procedimientos o funciones. Por lo general, un procedimiento se utiliza para realizar una acción y una función se utiliza para calcular y devolver un valor. Ejemplo CREATE OR REPLACE PROCEDURE hola_mundo IS l_mensaje VARCHAR2 (100) := '¡Hola Mundo!'; BEGIN DBMS_OUTPUT.put_line (l_mensaje); END hola_mundo; Podemos llamar el procedimiento creado anteriormente con las siguientes sentencias BEGIN hola_mundo; END; Procedimientos con parámetros CREATE OR REPLACE PROCEDURE hola_lugar (lugar IN VARCHAR2) IS l_mensaje VARCHAR2 (100); BEGIN l_mensaje := '¡Hola ' || lugar; DBMS_OUTPUT.put_line (l_mensaje); END hola_lugar; Llamando el procedimiento BEGIN hola_lugar ('Mundo!'); hola_lugar ('Universo!'); END; Declaraciones anclado - %TYPE y %ROWTYPE Cuando se declara una variable, hay que darle un tipo de datos y de un tamaño. Vamos a suponer por un momento que tengo una tabla que se parece a esto: Podría crear un pl/sql- código de la unidad que acceder a algunas de estas columnas. Por ejemplo: En este fragmento de código, declaró el número 6 dígitos de longitud, una fecha y un varchar2 de 25 caracteres de largo. Aunque estos tamaños coinciden con mi cuadro, hay una forma mejor de hacer esto: Mismos resultados, pero ahora mi software es sólo un poco más fácil de mantener. Si yo uso constantemente %TYPE todo mi código, puede cambiar el tamaño de columna con un poco menos preocupación. Técnicamente, puede ser capaz de cambiar los tipos de datos y estar bien, pero he encontrado que, en la práctica, cuando el usuario cambia los tipos de datos, se necesitará revisar una gran cantidad de su código. %TYPE es usado cuando usted se refiere son las columnas individuales. Hay muchos casos en donde será usado toda una fila. En lugar de crear manualmente un tipo de registro, puede declarar una variable de %ROWTYPE. Por ejemplo, a continuación voy a seleccionar todas las columnas de mi tabla: Esta recoge la totalidad de las columnas y los ponga a disposición en su programa. Puede detallar cada una de las columnas en su lista de selección como este: %TYPE y %ROWTYPE se llaman anclado declaraciones. Básicamente, usted es el tipo de datos de su anclaje declaraciones a la columna de definiciones en su base de datos. Además de asegurar que sus datos tipos y tamaños siempre coinciden, se hace más fácil ya que el código no tiene que buscar los tamaños, así como cada vez que escribir un pedazo de código. Ejercicio Tomando en cuenta la siguiente tabla create table ARTICULO ( ARTICULO CHAR(255) DESCRIPCION CHAR(255), PESO FLOAT, PRECIO FLOAT constraint PK_ARTICULO primary key (ARTICULO) ); not null, -Crear un procedimiento para insertar datos -Insertar 10 registros a la tabla ARTICULO -Crear un bloque que indique cuantos registros con precios mayores de 100 existen