Introducción a oracle pl sql potencia tus desarrollos (diario de un autodidacta nº 3) (spanish editi

Page 1


INTRODUCCIÓN A ORACLE PL/SQL POTENCIA TUS DESARROLLOS

******ebook converter DEMO Watermarks*******


ISAAC NARANJO

******ebook converter DEMO Watermarks*******


Copyright © Isaac Naranjo García Prohibida la reproducción total o parcial del contenido de este libro sin previa autorización del autor Primera Edición 2017

twitter @IsaccoNG Página de Author https://www.amazon.com/ISAAC-NARANJOGARCÍA/e/B01LYGLS7G

******ebook converter DEMO Watermarks*******


Cada dĂ­a es una nueva aventura.

******ebook converter DEMO Watermarks*******


ÍNDICE DE CONTENIDOS SOBRE EL AUTOR INTRODUCCIÓN CAPÍTULO 1 INSTALACIÓN DE LA BASE DE DATOS ORACLE 1.1 SISTEMA OPERATIVO 1.2 REQUISITOS FÍSICOS MÍNIMOS PARA LA INSTALACIÓN 1.3 CONFIGURACIÓN DE RED 1.4 CONFIGURACIÓN DEL NOMBRE DE HOST 1.5 ACTIVAR ACCESO REMOTO POR SSH 1.6 MEMORIA RAM Y SWAP 1.7 INSTALACIÓN DE PAQUETES NECESARIOS 1.8 USUARIO Y GRUPOS DE SEGURIDAD 1.9 CONFIGURACIÓN DEL PARÁMETRO DE SEGURIDAD SELINUX 1.10 CONFIGURACIÓN DE LOS PARÁMETROS DEL KERNEL 1.11 LÍMITES DEL USUARIO ORACLE 1.12 VARIABLES DE ENTORNO PARA EL USUARIO ORACLE 1.13 ESTRUCTURA DE DIRECTORIOS Y PERMISOS 1.14 INSTALACIÓN DE LA BASE DE DATOS 12C PASO 1 DE 9, CONFIGURAR ACTUALIZACIONES DE SEGURIDAD PASO 2 DE 9, SELECCIONAR OPCIÓN DE INSTALACIÓN PASO 3 DE 9, CLASE DE SISTEMA PASO 4 DE 10, OPCIONES DE INSTALACIÓN DE GRID PASO 5 DE 10, SELECCIONAR TIPO DE INSTALACIÓN PASO 6 DE 13, SELECCIONAR IDIOMAS DEL PRODUCTO PASO 7 DE 13, SELECCIONAR EDICIÓN DE LA BASE DE DATOS PASO 8 DE 13, ESPECIFICAR UBICACIÓN DE INSTALACIÓN PASO 9 DE 13, CREAR INVENTARIO PASO 10 DE 21, SELECCIONAR TIPO DE CONFIGURACIÓN PASO 11 DE 21, ESPECIFICAR IDENTIFICADORES DE BASE DE DATOS PASO 12 DE 21, ESPECIFICAR OPCIONES DE CONFIGURACIÓN PASO 13 DE 21, ESPECIFICAR OPCIONES DE ALMACENAMIENTO DE BASE DE DATOS PASO 14 DE 21, ESPECIFICAR OPCIONES DE GESTIÓN PASO 15 DE 21, ESPECIFICAR OPCIONES DE RECUPERACIÓN PASO 16 DE 21, ESPECIFICAR CONTRASEÑAS DE ESQUEMA PASO 17 DE 21, GRUPO DEL SISTEMA OPERATIVO PRIVILEGIOS PASO 18 DE 21, REALIZAR COMPROBACIONES DE REQUISITOS ******ebook converter DEMO Watermarks*******


PASO 19 DE 21, RESUMEN 1.15 VERIFICACIÓN DE LA INSTALACIÓN 1.16 CONFIGURAR REGLAS DE FIREWALL 1.17 CONSOLA DE ADMINISTRACIÓN 1.18 CONFIGURAR SERVICIO PARA ORACLE 12C CONCLUSIÓN CAPÍTULO 2 ORACLE SQL DEVELOPER 2.1 ORACLE SQL DEVELOPER 2.2 INSTALACIÓN DE ORACLE SQL DEVELOPER 2.3 CONEXIÓN CON LA BASE DE DATOS ORACLE 2.4 CONOCIENDO UN POCO SQL DEVELOPER PANEL DBA HOJA DE TRABAJO O EJECUCIÓN DE COMANDOS SQL CONCLUSIÓN CAPÍTULO 3 CREACIÓN DE LA BASE DE DATOS 3.1 CDB Y PBD 3.2 CREACIÓN DEL ESQUEMA 3.3 CREACIÓN DE LA BASE DE DATOS PROYECTOS CONCLUSIÓN CAPÍTULO 4 ORACLE PL/SQL 4.1 PL/SQL 4.2 BLOQUES PL/SQL 4.3 ENTRADA Y SALIDA DE DATOS 4.4 TIPOS DE DATOS 4.5 IDENTIFICADORES 4.6 VARIABLES 4.7 CONSTANTES 4.8 LITERALES 4.9 OPERADORES 4.9.1 OPERADORES ARITMÉTICOS 4.9.2 OPERADORES LÓGICOS O DE COMPARACIÓN 4.9.3 OPERADORES LÓGICOS 4.9.4 OPERADOR DE ASIGNACIÓN 4.9.5 OPERADORES DE CONCATENACIÓN DE CADENAS DE CARÁCTER 4.9.6 ORDEN DE PRECEDENCIA EN LOS OPERADORES 4.10 COMENTARIOS CONCLUSIÓN CAPÍTULO 5 ESTRUCTURAS DE CONTROL 5.1 ESTRUCTURA ALTERNATIVA ******ebook converter DEMO Watermarks*******


5.1.1 ESTRUCTURA ALTERNATIVA SIMPLE 5.1.2 ESTRUCTURA ALTERNATIVA DOBLE 5.1.3 ESTRUCTURA ALTERNATIVA MÚLTIPLE 5.1.4 ESTRUCTURA ALTERNATIVA MÚLTIPLE CON CASE DE COMPROBACIÓN 5.1.5 ESTRUCTURA ALTERNATIVA MÚLTIPLE CON CASE DE BÚSQUEDA 5.2 ESTRUCTURA REPETITIVA 5.2.1 ESTRUCTURA REPETITIVA WHILE 5.2.2 ESTRUCTURA REPETITIVA FOR CONCLUSIÓN CAPÍTULO 6 PROCEDIMIENTOS 6.1 PROCEDIMIENTOS EN PL/SQL 6.2 CREACIÓN DE PROCEDIMIENTOS 6.3 EJEMPLOS DE PROCEDIMIENTOS CONCLUSIÓN CAPÍTULO 7 FUNCIONES 7.1 FUNCIONES EN PL/SQL 7.2 CREACIÓN DE FUNCIONES 7.3 EJEMPLOS DE FUNCIONES CONCLUSIÓN CAPÍTULO 8 PARÁMETROS 8.1 PASO DE PARÁMETROS 8.1.1 NOTACIÓN POSICIONAL 8.1.2 NOTACIÓN NOMINAL 8.1.3 NOTACIÓN MIXTA 8.2 TIPOS DE PARÁMETROS 8.2.1 PARÁMETROS DE ENTRADA, IN 8.2.2 PARÁMETROS DE SALIDA, OUT 8.2.3 PARÁMETROS DE ENTRADA/ SALIDA, IN OUT 8.3 DEFINICIÓN DE LOS TIPOS DE PARÁMETROS CONCLUSIÓN CAPÍTULO 9 PAQUETES 9.1 PAQUETES EN PL/SQL 9.2 ELEMENTOS QUE COMPONEN UN PAQUETES 9.3 VENTAJAS DEL USO DE PAQUETES 9.4 CREACIÓN DE PAQUETES 9.5 EJEMPLOS DE PAQUETES CONCLUSIÓN CAPÍTULO 10 DISPARADORES ******ebook converter DEMO Watermarks*******


10.1 DISPARADORES EN PL/SQL 10.2 PARTES DE UN DISPARADORES 10.3 TIPOS DE DISPARADORES 10.4 CREACIÓN DE DISPARADORES CONCLUSIÓN CAPÍTULO 11 ALMACENAMIENTO DE SUBPROGRAMAS 11.1 ALMACENAMIENTO DE SUBPROGRAMAS EN ORACLE 11.2 COMPILAR OBJETOS DESDE PL/SQL 11.3 BORRAR OBJETOS DESDE PL/SQL CONCLUSIÓN CAPÍTULO 12 CURSORES 12.1 CURSORES EN PL/SQL 12.2 ATRIBUTOS DE UN CURSOR 12.3 VARIABLES DE ACOPLAMIENTO 12.4 MANEJO DE CURSORES CON FOR… LOOP 12.5 USO DE ALIAS EN LA DEFINICIÓN DE CURSORES 12.6 CURSORES PARA ACTUALIZACIÓN DE FILAS 12.7 CURSORES PARA BORRADO DE FILAS CONCLUSIÓN CAPÍTULO 13 GESTIÓN DE EXCEPCIONES 13.1 EXCEPCIONES EN PL/SQL 13.2 EXCEPCIONES PREDEFINIDAS EN ORACLE 13.3 EXCEPCIONES DEFINIDAS POR USUARIOS CONCLUSIÓN CAPÍTULO 14 TIPOS DE DATOS COMPUESTOS 14.1 REGISTROS 14.2 COLECCIONES 14.2.1 TABLAS INDEXADAS 14.2.2 TABLAS ANIDADAS 14.2.3 ARRAYS VARIABLES 14.2.4 OPERACIONES CON COLECCIONES INICIALIZAR COLECCIONES REFERENCIAR COLECCIONES ASIGNACIÓN Y COMPARACIÓN DE COLECCIONES ASIGNACIÓN DE ELEMENTOS A UNA COLECCIÓN COMPARACIÓN COMPLETA DE COLECCIONES 14.2.5 COLECCIONES MULTINIVEL EJEMPLO DE VARRAY MULTINIVEL EJEMPLO DE TABLA MULTINIVEL 14.2.6 MÉTODOS PARA COLECCIONES ******ebook converter DEMO Watermarks*******


CONCLUSIÓN CAPÍTULO 15 CURSORES VARIABLES 15.1 CURSORES VARIABLES EN PL/SQL 15.2 VENTAJAS DEL USO DE CURSORES VARIABLES 15.3 DEFINICIÓN DE CURSORES VARIABLES 15.4 DECLARACIÓN DE VARIABLES DE CURSOR 15.5 CONTROL DE VARIABLES DE CURSOR 15.5.1 APERTURA DE VARIABLES DE CURSOR 15.5.2 OBTENCIÓN DE UNA VARIABLE DE CURSOR 15.5.3 CIERRE DE UNA VARIABLE DE CURSOR 15.6 EJEMPLOS DE CURSOR VARIABLE CONCLUSIÓN CAPÍTULO 16 SQL DINÁMICO 16.1 USO DE SQL DINÁMICO 16.2 SENTENCIA EXECUTE INMEDIATE 16.3 RECUPERACIÓN DE VARIAS FILAS CONCLUSIÓN CONCLUSIÓN FINAL ANEXO FORMATOS DE CONVERSIÓN PARA FECHAS DIRECTORIO DE RECURSOS BIBLIOGRAFÍA WEBGRAFÍA

******ebook converter DEMO Watermarks*******


SOBRE EL AUTOR ¡Hola!, mi nombre es Isaac Naranjo y soy el autor de la serie de libros Diario de un Autodidacta. En esta sección te voy contar algunas cosas sobre mí, ¡pero tranquilo!, no quiero aburrirte con una descripción excesivamente extensa. Soy un apasionado de la informática y las nuevas tecnologías, llevo algo más de una década peleándome con los ordenadores. Estudio y trabajo dentro de este sector tan apasionante y tan difícil en ocasiones. Actualmente trabajo para una importante empresa española del sector de la Alimentación. Mi pasión por la informática y la innovación, y las ganas de compartir con el mundo mis experiencias, me ha llevado a escribir libros sobre temas que considero interesantes. En los ebooks he encontrado una herramienta perfecta para compartir con el mundo lo que he aprendido y aprendo cada día. Este libro es el tercer volumen de la serie Diario de un Autodidacta, el primer libro de la serie trata sobre la poderosa tecnología para desarrollo de aplicaciones Oracle Apex 5. Con este libro aprenderás a desarrollar un proyecto completo mediante Apex 5. Si te apasiona el Desarrollo de Aplicaciones Web te recomiendo sin duda Oracle Apex 5 y como no, le des un vistazo a mi libro. Es el primer libro de un autor español que trata el tema Apex. El desarrollo del proyecto lo hacemos mediante el tema Material Apex, que es una auténtica pasada. Con este libro podrás iniciarte en el camino para convertirte en un profesional de Apex y consolidar conocimientos, en caso de conocer ya la tecnología. El segundo libro, trata sobre ORACLE SQL. Todo desarrollador que trabaje con Bases de Datos debe conocer SQL y si trabajas con Bases de Datos Oracle, este libro será tu manual de referencia, ya que contiene todo lo necesario para iniciarse en el Lenguaje Estructurado de Consulta sobre Oracle. Considero que me queda mucho camino por recorrer y mucho contenido por aportar a la comunidad, esto se traduce en mucho horas de trabajo. Por último, comentarte que puedes contactar conmigo a través del Email diariodeunautodidacta@gmail.com, déjame un margen de algunos días para

******ebook converter DEMO Watermarks*******


responderte.

******ebook converter DEMO Watermarks*******


INTRODUCCIÓN Este libro va sobre el lenguaje PL/SQL (Procedural Language / Structured Query Language), es un manual de referencia dónde he recopilado todo lo necesario para iniciarse y desenvolverse con soltura en el Lenguaje de programación incrustado en la Base de Datos Oracle. A lo largo de 16 capítulos vamos a tratar lo fundamental e imprescindible del lenguaje PL/SQL. ¿Por qué un libro de Oracle PL/SQL? Conocer el lenguaje PL/SQL es necesario para toda persona que se dedique al mundo del desarrollo de aplicaciones y gestión de Bases de Datos Oracle, o quiera iniciarse en este mundo tan grande y complejo. Existe mucha documentación sobre PL/SQL, pero en la mayoría de los casos, la documentación es tan amplia que nos perdemos entre tanta información y obviamos lo realmente importante. En este libro pretendo ir a lo realmente importante, eliminando la paja y las extensiones teóricas no necesarias. Con lo aprendido tras la lectura de este libro, podrás usar el lenguaje de programación PL/SQL sin problemas en tus aplicaciones para la Base de Datos Oracle. Sin más dilataciones, comencemos con la materia.

******ebook converter DEMO Watermarks*******


CAPÍTULO 1 INSTALACIÓN DE LA BASE DE DATOS ORACLE En este primer capítulo vamos a tratar todo el proceso de instalación y puesta en marcha de la Base de Datos Oracle. Algo muy importante que debemos de tener en cuenta, y no olvidar, es que Oracle 12c es un producto que requiere licenciamiento. Debemos comprar una o varias licencias, dependiendo de nuestros requisitos. Para nuestro caso, vamos a realizar una instalación completa de Oracle y trabajaremos en modo pruebas, por lo que podemos trastear todo lo que queramos. Lo que no podemos hacer es poner la Base de Datos en producción.

******ebook converter DEMO Watermarks*******


1.1 SISTEMA OPERATIVO Para la instalación de la Base de Datos Oracle vamos a optar por un sistema GNU / Linux, bajo muy opinión y experiencia, Linux es una opción muy válida, por no decir la mejor para montar nuestro propio Servidor de Bases de Datos. Las versiones soportadas por Oracle 12c de Linux son: Red Hat Enterprise Linux (RHEL) CentOS Oracle Linux La distribución RHEL requiere de la compra de una licencia, y no es una licencia barata. Las distribuciones CentOS y Oracle Linux son open source y podemos usarlas libremente sin necesidad de comprar ninguna licencia. Aunque CentOS y Oracle Linux son distribuciones muy similares, yo personalmente prefiero CentOS. Para nuestro propósito, vamos a decantarnos por CentOS. Linux CentOS es uno de los Sistemas Operativos más usados por proveedores de Hosting y sin duda es una opción idónea para la instalación de la Base de Datos Oracle. Aunque si no te gusta CentOS y prefieres usar otra distribución, perfectamente puedes hacerlo.

******ebook converter DEMO Watermarks*******


1.2 REQUISITOS FÍSICOS MÍNIMOS PARA LA INSTALACIÓN Oracle recomiendo para la instalación de la Base de Datos Oracle 12c Standard Edition, los siguientes requisitos mínimos son: 2 GB de RAM Memoria Swap, al menos el doble de la memoria RAM 1 GB de espacio libre en el directorio de la instalación, directorio tmp. Como mínimo 8 GB de espacio en disco Lógicamente, dependiendo del uso que vayamos a darle al servidor y del tipo de instalación que vayamos a realizar, deberemos redimensionar las características hardware de la máquina atendiendo a estas necesidades. Vamos a partir para no tener problemas en la instalación, de una máquina que tenga 80 GB libres en disco y 4GB de Memoria RAM como mínimo. No vamos a abordar el proceso de instalación del Sistema GNU / Linux puesto que alargaríamos mucho este primer capítulo y es un tema que queda fuera de los objetivos de este libro. La instalación del Sistema Operativo no es difícil y es un proceso muy intuitivo, no deberías de tener problemas con ello. Recuerda que mi recomendación es CentOS. Una anotación que me gustaría hacer antes de comenzar con el proceso de configuración e instalación del servidor de Base de Datos Oracle es la siguiente: Cuando aparezca el símbolo # delante del comando a ejecutar, significa que dicho comando deberemos ejecutarlo como usuario superadministrador, root. Si aparece el símbolo $, significa que el comando debemos ejecutarlo como usuario oracle. El usuario oracle lo crearemos en el punto 1.8.

******ebook converter DEMO Watermarks*******


1.3 CONFIGURACIÓN DE RED A partir de este punto, consideramos que el Sistema Operativo ya está instalado. En primer lugar, vamos a asignar una configuración de red a nuestro Servidor, para ello vamos a Aplicaciones, Herramientas del Sistema, Configuración. En la sección Hardware, accedemos a Red. En la pantalla Red, seleccionados Cableado y hacemos clic sobre el icono de engranajes. Hecho esto, accederemos a una nueva pantalla, nos desplazamos a la sección IPv4. Dentro de esta sección asignamos una configuración de red. Puedes asignar el direccionamiento IP que desees, en mi caso he asignado la dirección IP 192.168.7.100 Otra opción, de la cual disponemos para asignar una configuración de red en el sistema, es mediante el correspondiente fichero de configuración. Para ello, accedemos a la ruta /etc/sysconfig/network-scripts/ y buscamos el fichero de configuración de nuestra tarjeta de red, suele comenzar por ifcfg-etc. Un ejemplo de configuración sería este: TYPE=Ethernet BOOTPROTO=none DEFROUTE=yes IPV4_FAILURE_FATAL=no IPV6INIT=yes IPV6_AUTOCONF=yes IPV6_DEFROUTE=yes IPV6_FAILURE_FATAL=no NAME=MiRed UUID=73a15264-36eb-4b22-892a-5e624ff0ca44 ONBOOT=yes DNS1=192.168.7.1 IPADDR=192.168.7.100

******ebook converter DEMO Watermarks*******


PREFIX=24 GATEWAY=192.168.7.1 IPV6_PEERDNS=yes IPV6_PEERROUTES=yes

******ebook converter DEMO Watermarks*******


1.4 CONFIGURACIÓN DEL NOMBRE DE HOST Para configurar el nombre de nuestro Servidor, debemos editar el fichero hostname. Como usuario root, ejecutamos: # gedit /etc/hostname

Añadimos: ServerOracle

Guardamos y cerramos el fichero. Configuramos también el fichero hosts: #/etc/hosts

Y añadimos: Ip_Servidor ServerOracle

En mi caso: 192.168.7.100 ServerOracle

Guardamos los cambios y cerramos el fichero. El fichero hosts es usado por el sistema para guardar la relación entre dominios y direcciones ip.

******ebook converter DEMO Watermarks*******


1.5 ACTIVAR ACCESO REMOTO POR SSH Para facilitar el proceso de instalación y configuración de nuestro entorno de desarrollo, podemos configurar una conexión remota al Servidor Linux CentOS mediante SSH, Secure SHell. Para ello, desde la terminal y como usuario root se ejecuta: # systemctl start sshd.service

Por defecto este servicio viene instalado en CentOS 7, con el comando anterior estamos iniciando el servicio. Para dejar configurado el servicio de forma permanente ejecutamos: # systemctl enable sshd.service

Para realizar la conexión remota por SSH al Servidor podemos usar un Software adicional como por ejemplo Putty, en caso de acceder desde un Sistema MS Windows o Mac OS, o bien por cliente SSH desde una terminal de un sistema GNU / Linux cliente. Para conectarnos desde un cliente SSH: $ ssh usuario@direccion_ip_Servidor

En nuestro caso $ssh oracle@192.168.7.100

O bien, en caso de que tengamos una entrada DNS configurada apuntando a nuestro Servidor, podríamos acceder mediante el nombre de host: $ssh oracle@ServerOracle

******ebook converter DEMO Watermarks*******


1.6 MEMORIA RAM Y SWAP Para la instalaciĂłn de Oracle 12c debemos tener como mĂ­nimo 2 GB de RAM. Para el caso de la memoria Swap, Oracle recomienda el doble de la memoria RAM. Para comprobar la memoria RAM disponible en el sistema ejecutamos el comando: # free -m -h

******ebook converter DEMO Watermarks*******


1.7 INSTALACIĂ“N DE PAQUETES NECESARIOS Instalamos los paquetes necesarios: # yum install gcc gcc-c++ glibc-devel glibc-headers ksh libaio-devel libstdc++-devel sysstat unixODBC-devel zlib-devel compat-libcap1 compat-libstdc++-33

Es posibles que el sistema nos indique que algunos de los paquetes ya se encuentran instalados.

******ebook converter DEMO Watermarks*******


1.8 USUARIO Y GRUPOS DE SEGURIDAD Creamos ahora los Grupos de Seguridad, oinstall, dba y oper: # groupadd -g 501 oinstall # groupadd -g 502 dba # groupadd -g 503 oper

A continuaciรณn vamos a crear el usuario oracle y lo hacemos miembro de los Grupos de Seguridad creados: # useradd -u 501 -g oinstall -G dba,oper oracle

******ebook converter DEMO Watermarks*******


1.9 CONFIGURACIÓN DEL PARÁMETRO DE SEGURIDAD SELINUX Debemos configurar el parámetro SELINUX a permissive. Para ello, editamos el archivo /etc/selinux/config: # gedit /etc/selinux/config

Modificamos el valor SELINUX a permissive, quedando: SELINUX=permissive

Guardamos los cambios y cerramos el fichero. Para hacer efectivo ese cambio, debemos reiniciar el servidor: # init 6

******ebook converter DEMO Watermarks*******


1.10 CONFIGURACIÓN DE LOS PARÁMETROS DEL KERNEL Vamos a añadir ahora los parámetros recomendados por Oracle en el kernel del sistema. # gedit /etc/sysctl.conf con

Y añadimos al fichero: fs.file-max = 6815744 kernel.sem = 250 32000 100 128 kernel.shmmni = 4096 kernel.shmall = 1073741824 kernel.shmmax = 4398046511104 net.core.rmem_default = 262144 net.core.rmem_max = 4194304 net.core.wmem_default = 262144 net.core.wmem_max = 1048576 fs.aio-max-nr = 1048576 net.ipv4.ip_local_port_range = 9000 65500

Guardamos los cambios en el fichero. Para aplicar los cambios ejecutamos el siguiente comando: # sysctl -p

******ebook converter DEMO Watermarks*******


1.11 LÍMITES DEL USUARIO ORACLE Para definir los límites del usuario oracle, editamos el fichero limits.conf: # gedit /etc/security/limits.conf

y añadimos: oracle soft nofile 1024 oracle hard nofile 65536 oracle soft nproc 2047 oracle hard nproc 16384 oracle soft stack 10240 oracle hard stack 32768

Guardamos los cambios en el fichero

******ebook converter DEMO Watermarks*******


1.12 VARIABLES DE ENTORNO PARA EL USUARIO ORACLE Editamos el fichero bash_profiles para el usuario oracle: # gedit /home/oracle/.bash_profile

Y añadimos las variables de entorno: export TMP=/tmp export ORACLE_HOSTNAME=serveroracle export ORACLE_UNQNAME=oracle12 export ORACLE_BASE=/ora01/app/oracle export ORACLE_HOME=$ORACLE_BASE/product/12.1.0/db_1 export ORACLE_SID=oracle12 PATH=/usr/sbin:$PATH:$ORACLE_HOME/bin export LD_LIBRARY_PATH=$ORACLE_HOME/lib:/lib:/usr/lib; export CLASSPATH=$ORACLE_HOME/jlib:$ORACLE_HOME/rdbms/jlib; alias cdob='cd $ORACLE_BASE' alias cdoh='cd $ORACLE_HOME' alias tns='cd $ORACLE_HOME/network/admin' alias envo='env | grep ORACLE' umask 022 envo

Guardamos los cambios en el fichero y lo cerramos.

******ebook converter DEMO Watermarks*******


1.13 ESTRUCTURA DE DIRECTORIOS Y PERMISOS Vamos a crear a continuaciรณn la estructura de directorios donde se alojarรก el software de la Base de Datos Oracle 12c: # mkdir -p /ora01/app/oracle/product/12.1.0/db1

Asignamos permisos para el usuario oracle sobre el directorio creado: # chown oracle:oinstall -R /ora01

******ebook converter DEMO Watermarks*******


1.14 INSTALACIÓN DE LA BASE DE DATOS 12C Lo primero que debemos hacer es ir a la web oficial de Oracle, sección descargas, y descargar el software necesario para instalar la Base de Datos. Para nuestro caso, vamos a descargar la versión (12.1.0.2.0) - Standard Edition (SE2). Descargamos los dos ficheros correspondientes para Linux (Linux x86-64) File 1 y File 2. Una vez descargado el software, vamos a crear un directorio denominado oracle, dentro de /tmp. En el directorio tmp alojaremos el software de Oracle 12c. Creamos el directorio: # mkdir /tmp/oracle

Copiamos los archivos descargados al directorio creado: # cp /home/oracle/Descargas/linuxamd64_12102_database_se2_1of2.zip /tmp/oracle # cp /home/oracle/Descargas/linuxamd64_12102_database_se2_2of2.zip /tmp/oracle

Descomprimimos los archivos: # cd /tmp/oracle # unzip linuxamd64_12102_database_1of2.zip # unzip linuxamd64_12102_database_2of2.zip

Y asignamos permisos para el usuario oracle: # chown oracle:oinstall -R /tmp/oracle/

A continuación nos desplazamos al directorio donde se han descomprimido los archivos de instalación: # cd /oracle/database

Llegado a este punto, vamos a proceder con la instalación de la Base de Datos, todo el proceso de instalación lo vamos a realizar mediante el usuario oracle. Cambiamos a usuario oracle ejecutando:

******ebook converter DEMO Watermarks*******


# su oracle

Iniciamos el asistente para instalación de la Base de Datos Oracle 12c, para ello ejecutamos: $ ./runInstaller

Vamos a seguir los pasos de cada una de las pantallas del asistente para proceder con la instalación de Oracle 12c. PASO 1 DE 9, CONFIGURAR ACTUALIZACIONES DE SEGURIDAD En esta primera pantalla, introduciremos una dirección de email para recibir notificaciones de Oracle sobre parches, novedades, etc. También podemos activar la opción de recibir notificaciones de seguridad a través de My Oracle Support. Esta última opción no es obligatoria y la dejaremos desactivada. Hacemos clic en siguiente. PASO 2 DE 9, SELECCIONAR OPCIÓN DE INSTALACIÓN En esta pantalla se nos presentan tres opciones: Crear y Configurar Base de Datos. Se instalará el software de Oracle 12c sin Base de Datos. Posteriormente a la instalación del software, podremos ejecutar el asistente para crear la Base de Datos. Instalar solo software de Base de Datos. Solo instalará el software, sin Base de Datos. Actualizar Base de Datos Existente. Se realizará una actualización de la versión de Oracle existente. Esta opción es más compleja y debemos de disponer de copias de seguridad antes de realizar cualquier tipo de actualización. Seleccionamos la primera opción, Crear y Configurar Base de Datos, y hacemos clic en siguiente. PASO 3 DE 9, CLASE DE SISTEMA Seleccionamos el tipo de Sistema para Oracle 12c. Tenemos dos opciones disponibles:

******ebook converter DEMO Watermarks*******


Clase Escritorio. Este sistema es apropiado para instalaciones de Oracle en modo prueba, en equipos de Escritorio. Crea una Base de Datos y una configuración mínima para que no se consuman todos los recursos. Clase Servidor. Es el sistema recomendado para un Servidor dedicado a la Base de Datos Oracle. Permite opciones de configuración más avanzadas. Vamos a seleccionar la opción Clase Servidor, ya que vamos a ejecutar una instalación completa de Oracle 12c y a continuación, clic en siguiente. PASO 4 DE 10, OPCIONES DE INSTALACIÓN DE GRID Elegimos el tipo de instalación, las opciones disponibles son: Instalación de Base de Datos de Instancia Única. Mediante esta opción, Oracle se instalará en un equipo individual con una sola instancia. Instalación de Base de Datos de Oracle Real Application Clusters. Usamos esta opción para montar un clúster de Oracle formado por varios equipos, se usa en instalaciones de altos requisitos de disponibilidad. Instalación de la Base de Datos Oracle RAN One Node. Esta opción es similar a la anterior, pero con un solo nodo. Seleccionamos Instalación de Base de Datos de Instancia Única y siguiente. PASO 5 DE 10, SELECCIONAR TIPO DE INSTALACIÓN Tenemos dos opciones disponibles: Instalación Típica. Es una opción menos personalizable, solo podemos editar las opciones más básicas y el resto se establecen por defecto. Instalación Avanzada. Con esta opción podemos personalizar las opciones avanzadas, contraseñas para los usuarios SYS, SYSTEM, SYSMAN y DBSNMP, juegos de caracteres de Base de Datos, idiomas del producto, copias de seguridad automatizadas, instalación personalizada y opciones de almacenamiento alternativas como Oracle Automatic Management.

******ebook converter DEMO Watermarks*******


Seleccionamos Instalación Avanzada y hacemos clic en siguiente. PASO 6 DE 13, SELECCIONAR IDIOMAS DEL PRODUCTO Comprobamos que está seleccionado el idioma español y hacemos clic en siguiente. PASO 7 DE 13, SELECCIONAR EDICIÓN DE LA BASE DE DATOS En esta pantalla se ofrece la posibilidad de elegir la edición de la Base de Datos a instalar. Dependiendo del fichero de instalación descargado, se mostrarán unas opciones u otras. En nuestro caso, aparecerá seleccionada la versión Standard Edition Two, puesto que es la edición de la Base de Datos que hemos descargado. Continuamos con el asistente haciendo clic en siguiente. PASO 8 DE 13, ESPECIFICAR UBICACIÓN DE INSTALACIÓN Disponemos de las siguientes opciones: Directorio Base de Oracle Debemos elegir el directorio para la Base de Datos Oracle, en este directorio se alojarán todos los archivos relacionados con la configuración y el software de Oracle. Esta ubicación será el directorio base de Oracle para el propietario de la instalación. En directorio de Base de Datos, hacemos clic en Examinar y seleccionamos el directorio: /ora01/app/oracle

Ubicación del software De igual forma, debemos especificar una ubicación para almacenar los archivos de software de Oracle, separados de los archivos de configuración de la Base de Datos. Este directorio, es el directorio raíz de Oracle. En Ubicación del Software, hacemos clic sobre Examinar y seleccionamos el directorio: /ora01/app/oracle/product/12.1.0/db1

******ebook converter DEMO Watermarks*******


Pulsamos en siguiente. PASO 9 DE 13, CREAR INVENTARIO Especificamos un directorio para los archivos de Metadatos, este directorio se denomina de inventario. Automáticamente se configura un subdirectorio para los datos de inventario de cada producto. En Directorio de Inventario, seleccionamos (con el botón Examinar) la ruta: /ora01/app/oraInventory

Debemos especificar también un grupo del sistema que tenga permisos de escritura sobre el directorio. Seleccionamos en Nombre del Grupo oraInventory, el grupo oinstall. Continuamos, clic en siguiente. PASO 10 DE 21, SELECCIONAR TIPO DE CONFIGURACIÓN Tenemos dos opciones disponibles: Uso General / Procesamiento de Transacciones. Es la configuración por defecto y de uso general o para aplicaciones con muchas transacciones, consultas, inserciones y modificaciones. Almacén de Datos. Optimiza la Base de Datos como almacén de datos, alojar la información y poder consultarla, sin el uso habitual de consultas, inserciones y modificaciones. Seleccionamos Uso General / Procesamiento de Transacciones y hacemos clic en siguiente para continuar con el asistente. PASO 11 DE 21, ESPECIFICAR IDENTIFICADORES DE BASE DE DATOS En esta pantalla debemos indicar los identificadores para la Base de Datos, estos identificadores son: Nombre de la Base de Datos Gobal: oracle12

******ebook converter DEMO Watermarks*******


Identificador del Sistema Oracle (SID): oracle12 Crear como Base de Datos del Contenedor. Vamos a marcar esta opción para poder disponer de varias Bases de Datos en un mismo servidor, agrupadas en una visualización global. Introducimos como Nombre de Base de Datos de Conexión: proyectos. Un punto importante a tener en cuenta es que el SID de la Base de Datos debe coincidir con el indicado en las variables de entorno añadidas en el fichero .bash_profile. Seguimos avanzando en el asistente haciendo clic en siguiente. PASO 12 DE 21, ESPECIFICAR OPCIONES DE CONFIGURACIÓN Debemos configurar ahora las opciones de Memoria, Juego de Caracteres y Esquemas de Ejemplo. Memoria. Indicamos la cantidad de memoria RAM que se asignará a Oracle, marcamos la opción de Activar Gestión Automática de Memoria para que el propio Oracle pueda realizar una asignación a los diferentes procesos. Lógicamente mientras más memoria asignemos a Oracle mayor rendimiento tendrá el Servidor de Base de Datos. Debemos de tener en cuenta, que hay que reservar una cantidad de memoria para los procesos del Sistema Operativo. Asignaremos la memoria RAM en función del uso que le vamos a dar al servidor, 40 % de la memoria disponible. En los requisitos hardware, hemos dicho que Oracle recomienda como mínimo 2 Gigas de Memoria RAM. Con esta cantidad de memoria, el servidor se quedará muy justo, por lo que deberíamos de tener como mínimo 4 GB de RAM. Posteriormente a la instalación, es posible ajustar los valores de memoria RAM asignados. Juego de Caracteres. En esta pestaña podemos elegir el juego de caracteres para la Base de Datos. Al realizar una instalación nueva de la Base de Datos y no existir ninguna información que debamos importar, seleccionamos el valor por defecto WE8MSWIN1252.

******ebook converter DEMO Watermarks*******


Esquema de Ejemplo. Seleccionamos la opción Crear Base de Datos con Esquemas de Ejemplo, nos creará usuarios y tablas de ejemplo. Clic en siguiente. PASO 13 DE 21, ESPECIFICAR OPCIONES DE ALMACENAMIENTO DE BASE DE DATOS Llegado a este punto, nos toca seleccionar el tipo de almacenamiento. Comentamos a continuación las opciones disponibles: Sistemas de Archivos. Oracle recomienda para un rendimiento óptimo de la Base de Datos que los archivos de datos y software se encuentren ubicados en sitios distintos. Oracle Automatic Storage Management. La gestión Automática del Almacenamiento (Oracle ASM) simplifica la administración del almacenamiento y sitúa los archivos de modo que se obtenga un rendimiento óptimo. No hemos preparado el sistema previamente para la opción ASM, por lo tanto no podemos seleccionar dicha opción. Elegimos pues la opción Sistema de Archivos. Seleccionamos la ruta: /ora01/app/oracle/oradata

En entornos de producción, lo recomendable es que los archivos se alojen en un sistema de almacenamiento redundante y en diferentes discos para el Sistema Operativo y el software Oracle. Hacemos clic en siguiente. PASO 14 DE 21, ESPECIFICAR OPCIONES DE GESTIÓN En caso de que dispongamos de la herramienta Enterprise Manager (EM) Cloud Control, como no necesitamos comprar licencias para ello, podemos indicar aquí los datos. Esta herramienta nos permite gestionar de manera centralizada varios servidores

******ebook converter DEMO Watermarks*******


de Base de Datos Oracle. Para nuestro cometido no es necesaria, es una herramienta pensada para entornos de producción más complejos. Por defecto, Oracle Database Express gestiona Oracle 12c. Dejamos sin seleccionar la opción Registrar en Enterprise Manager (EM) Cloud Control Pulsamos en siguiente y continuamos con el asistente. PASO 15 DE 21, ESPECIFICAR OPCIONES DE RECUPERACIÓN Vamos a marcar la Opción Activar Recuperación para disponer de un área de recuperación. Para ello, vamos a indicar una ruta para ubicar los archivos de recuperación. Indicamos la ruta: /ora01/app/oracle/recovery_area

Clic en siguiente. PASO 16 DE 21, ESPECIFICAR CONTRASEÑAS DE ESQUEMA Lo siguiente que vamos a hacer es indicar las contraseñas para los usuarios, estos usuarios son SYS, SYSTEM, DBSNMP Y PDBADMIN. Para facilitar esta labor, vamos a marcar la opción Usar la Misma Contraseña para Todas las Cuentas. La contraseña introducida debe cumplir con los estándares recomendados por Oracle. En caso de no cumplir la clave con los estándares, se nos mostrará un mensaje de advertencia. Clic en Siguiente. PASO 17 DE 21, GRUPO DEL SISTEMA OPERATIVO PRIVILEGIOS El siguiente paso es establecer los grupos de seguridad para el Sistema, dicho grupos de seguridad son los que creamos en el punto 1.8 USUARIOS Y GRUPOS DE SEGURIDAD, quedando de la siguiente forma: Grupo de Administración de Base de Datos (OSDBA): dba

******ebook converter DEMO Watermarks*******


Grupo del Operador de Base de Datos (OSOPER): por defecto oper Grupo de Recuperación y Copia (OSBACKUPDBA): dba

de

Seguridad de

Base

de

Datos

Grupo Administrativo de Data Guard (OSDGDBA): dba Grupo Administrativo de Gestión de Claves de Cifrado (OSKMDBA): dba Pulsamos en Siguiente. PASO 18 DE 21, REALIZAR COMPROBACIONES DE REQUISITOS Se realizará una comprobación de requisitos, se verificará que el Sistema Operativo cuenta con los requisitos mínimos de instalación. En caso de existir un requisito que no cumpla con los valores mínimos, se mostrará en la lista. Si el requisito que incumple los valores mínimos no es obligatorio, podremos realizar la instalación. En el caso de nuestra instalación, la memoria Swap no cumple con los requisitos (recuerda que hemos dicho que debe ser el doble de la memoria RAM). Al no ser un requisito obligatorio, podremos ejecutar la instalación de Oracle 12c, marcamos Ignorar Todo y continuamos con la Instalación pulsando en Clic. Añadir que para una instalación de Oracle en Producción, es necesario cumplir con los requisitos de memoria, calculando el hardware de acuerdo a las necesidades. Recordamos que estamos haciendo una instalación real de Oracle, pero en un entorno de pruebas. Para la instalación de la Base de datos Oracle 12c en producción se precisa de un equipo potente. Al ignorar los requisitos, se nos mostrará un mensaje de advertencia. Cerramos dicho mensaje y continuamos con el asistente. PASO 19 DE 21, RESUMEN En el último paso, antes de iniciar la instalación de Oracle 12c, el asistente mostrará un resumen. Si todo es correcto, hacemos clic en Instalar. Se iniciará el proceso de instalación. Llegada la instalación a un punto, se solicitará la ejecución de unos scripts. Es importante ejecutar ambos script antes de continuar con el proceso de instalación.

******ebook converter DEMO Watermarks*******


Sin cerrar la Ventana Ejecutar Scripts de Configuración, abrimos una consola del sistema y como usuario root, ejecutamos los siguientes scripts: # /ora01/app/oraInventory/orainstRoot.sh # /ora01/app/oracle/product/12.1.0/db_1/root.sh

Si todo es correcto y no se generan errores, hacemos clic en aceptar sobre la Ventana Ejecutar Scripts de Configuración, y continuamos con el proceso de instalación. Finalizada la instalación, se iniciará la creación de la Base de Datos. Una vez creada la Base de Datos, el asistente de instalación mostrará en una ventana la URL de acceso EM Database Express. https://serveroracle:5500/em

Si hacemos clic en Gestión de Contraseñas, podremos establecer las contraseñas para los usuarios SYS, SYSTEM, AUDSYS, GSMUSER, SPATIAL_WFS_ADMIN_USR, SPATIAL_CSW_ADMIN_USR, APEX_PUBLIC_USER, SYSDG, DIP, SYSBACKUP, MDDATA, GSMCATUSER, SYSKM, ORACLE_OCM, OLAPSYS, SI_INFORMTN_SCHEMA, DVSYS, ORDPLUGINS, XDB. En caso de modificar algunas de las claves, estás deben cumplir con un mínimo de 8 caracteres, un carácter en mayúscula, uno en minúscula y un dígito. Dejamos de momento todo como está y hacemos clic en Aceptar. El proceso de instalación y creación de la Base de Datos queda finalizado.

******ebook converter DEMO Watermarks*******


1.15 VERIFICACIÓN DE LA INSTALACIÓN Una vez realizada la instalación de Oracle 12c es conveniente realizar una serie de comprobaciones. En primer lugar vamos a comprobar si la Base de Datos está iniciada y es accesible. Desde la terminal del sistema y como usuario oracle, ejecutamos: $ sqlplus /nolog SQL>conn / as sysdba SQL>select status from v$instance;

Si la consulta se ejecuta de forma correcta, devolverá el valor de OPEN. STATUS -----------OPEN

******ebook converter DEMO Watermarks*******


1.16 CONFIGURAR REGLAS DE FIREWALL Para permitir el acceso a nuestro servidor de Base de Datos desde otros equipos de la red, debemos configurar el Firewall del sistema con una serie de reglas que permitan tal acceso. Desde una terminal del sistema y como root, ejecutamos: # firewall-cmd --permanent --zone=public –add-port=5500/tcp

Con la ejecución de este comando, abrimos el puerto para acceder a la consola de Administración del sistema mediante https. Abrimos también el puerto para acceder a la consola de Administración mediante http: # firewall-cmd --permanent --zone=public --add-port=8080/tcp

Y por último abrimos el puerto del Listener de Oracle: # firewall-cmd --permanent --zone=public –add-port=1521/tcp

Para finalizar reiniciamos el Firewall: # firewall-cmd –reload

******ebook converter DEMO Watermarks*******


1.17 CONSOLA DE ADMINISTRACIÓN Por defecto se activará el acceso https mediante el puerto 5500 a la consola de Administración web de Oracle 12c, Oracle Enterprise Manager Database Express 12c. Para acceder a la consola web, desde el navegador ejecutamos: https://IP_Servidor_Oracle:5500/em

Para nuestro caso: https://192.168.7.100:5500/em

Oracle Enterprise Manager Database Express, también denominado EM Express, es una herramienta en entorno web para administrar Oracle Database 12c. Está construida dentro del servidor de Bases de Datos, ofrece soporte para tareas administrativas básicas, como almacenamiento y administración de usuarios, y proporciona soluciones integrales para el diagnóstico de rendimiento y afinación. Para acceder a la herramienta, debemos introducir los datos para el usuario administrador SYS. En la siguiente imagen podemos ver la interfaz de Oracle Enterprise Manager Database Express para Oracle 12c.

Figura 1.1 – Interfaz Web Oracle Manager Database Express 12c

******ebook converter DEMO Watermarks*******


Vamos a dejar el puerto configurado por defecto, pero comentar que podemos también configurar el acceso mediante el puerto 8080 a la consola de administración. Accedemos a SQL Plus y ejecutamos como SYS el siguiente comando: SQL> dbms_xdb_config.sethttpport(8080);

Si queremos comprobar el estado de los puertos, ejecutamos desde la consola SQL Plus los siguientes comandos. Para el puerto https: SQL> select dbms_xdb_config.getHttpsPort() from dual;

Para el puerto http: SQL> select dbms_xdb.getHttpPort() from dual;

Por último comprobamos el estado del listener de Oracle, para ello ejecutamos desde la terminal del sistema: $ lsnrctl status | grep HTTP

******ebook converter DEMO Watermarks*******


1.18 CONFIGURAR SERVICIO PARA ORACLE 12C Bien, ahora vamos a configurar el servicio de arranque automรกtico para Oracle 12c. El primer requisito es tener las variables de entorno correctamente configuradas, en el punto 1.12 realizamos la mencionada configuraciรณn. Revisamos el contenido del fichero /etc/oratab, este fichero contiene el SID para la Base de Datos y la ruta de instalaciรณn del software, para la configuraciรณn que hemos realizado el contenido debe ser: orcl:/ora01/app/oracle/product/12.1.0/db_1:Y

El siguiente paso es crear el script para arranque del servicio. Ejecutamos como usuario root desde una consola del sistema: # gedit /etc/init.d/dbora

Y agregamos el siguiente cรณdigo: #! /bin/sh ORACLE_HOME=/ora01/app/oracle/product/12.1.0/db_1 ORACLE=oracle PATH=${PATH}:$ORACLE_HOME/bin HOST=`hostname` PLATFORM=`uname` export ORACLE_HOME PATH # if [ ! "$2" = "ORA_DB" ] ; then runuser -l $ORACLE $0 $1 ORA_DB if [ "$PLATFORM" = "Linux" ] ; then touch /var/lock/subsys/dbora fi exit fi

******ebook converter DEMO Watermarks*******


# case $1 in 'start') $ORACLE_HOME/bin/dbstart $ORACLE_HOME & $ORACLE_HOME/bin/lsnrctl start LISTENER ;; 'stop') $ORACLE_HOME/bin/dbshut $ORACLE_HOME & rm -f /var/lock/subsys/dbora $ORACLE_HOME/bin/lsnrctl stop LISTENER ;; *) echo "usage: $0 {start|stop}" exit ;; esac # exit

Configuramos los permisos necesarios sobre el fichero creado: # chgrp dba /etc/init.d/dbora # chmod 750 /etc/init.d/dbora

Para finalizar, creamos los enlaces simbรณlicos sobre el fichero: # ln -s /etc/init.d/dbora /etc/rc.d/rc0.d/K01dbora # ln -s /etc/init.d/dbora /etc/rc.d/rc3.d/S99dbora # ln -s /etc/init.d/dbora /etc/rc.d/rc5.d/S99dbora

Perfecto, nuestro servidor de Base de Datos quedรณ configurado. Reiniciamos el sistema y comprobamos que el servicio se inicia de forma correcta.

******ebook converter DEMO Watermarks*******


******ebook converter DEMO Watermarks*******


CONCLUSIÓN Hemos llegado al final de este primer capítulo, a lo largo del capítulo hemos visto todo el proceso de instalación y configuración de Oracle 12c sobre un sistema GNU / Linux. En el siguiente capítulo vamos a ver la herramienta que vamos a usar para trabajar sobre la Datos de Datos.

******ebook converter DEMO Watermarks*******


CAPÍTULO 2 ORACLE SQL DEVELOPER En este segundo capítulo del libro, vamos a instalar la herramienta case Oracle SQL Developer. Explicaremos como instalar la herramienta y como configurar la conexión con la Base de Datos que usaremos para trabajar. Hablaremos también un poco sobre la interfaz de SQL Developer con el objetivo de familiarizarnos con dicha herramienta.

******ebook converter DEMO Watermarks*******


2.1 ORACLE SQL DEVELOPER Oracle SQL Developer es un entorno de desarrollo integrado libre que simplifica el desarrollo y gestión de la Base de Datos Oracle en implementaciones tradicionales y en la nube. SQL Developer ofrece un desarrollo completo, de extremo a extremo, de las aplicaciones PL/SQL, una hoja de cálculo para ejecutar consultas y scripts, una consola de DBA para la gestión de la Base de Datos, una interfaz de informes, una solución completa de modelado de datos y una plataforma de migración para mover la Base de Datos Oracle. En general, SQL Developer es una herramienta gráfica para el desarrollo de Base de Datos Oracle. Permite visualizar objetos de Base de Datos, ejecutar sentencias SQL, ejecutar scripts SQL, editar y depurar sentencias PL/SQL. Con esta herramienta mejoramos nuestra productividad y simplificamos el trabajo de desarrollo sobre la Base de Datos Oracle. Es una herramienta que no necesita instalación y precisa del JDK para su funcionamiento. SQL Developer posee un árbol jerárquico de objetos en Base de Datos y nos permite realizar operaciones sobre ellos. Proporciona además, algunas herramientas adicionales, destacando las hojas de trabajo desde dónde podemos ejecutar sentencias SQL y PL/SQL. La Web oficial del producto es: http://www.oracle.com/technetwork/developer-tools/sql-developer/downloads/index.html

En resumen, podemos decir que Oracle SQL Developer se divide en dos partes fundamentalmente, Panel Izquierdo (árbol jerárquico), sirve para buscar y seleccionar objetos, y el Panel Derecho, que sirve para mostrar la información de los objetos seleccionados. Debajo del Panel Derecho tenemos otro panel, este panel nos muestra información sobre errores y logs que se generan con la ejecución de las sentencias. Como ya hemos mencionado, son muchas las opciones disponibles en SQL Developer, vamos a intentar centrarnos en las opciones más básicas y útiles.

******ebook converter DEMO Watermarks*******


2.2 INSTALACIÓN DE ORACLE SQL DEVELOPER Vamos a instalar la herramienta SQL Developer. Lo primero que debemos hacer es ir a la web oficial y descargar el software en función del Sistema Operativo. Para un Sistema Linux, debemos descargar el paquete Linux RPM. Una vez descargado, procedemos a instalar el software. Desde una consola del sistema, ejecutamos el siguiente comando como usuario root: # rpm -Uhv sqldeveloper-(build number)-1.noarch.rpm

Sustituimos “build number” por la versión del software que hemos descargado. Esta versión de SQL Developer para Sistemas Linux no incluye el JDK, por lo que tendremos que descargarlo e instalarlo de forma independiente. Desde la página oficial, podemos obtener la versión JDK para Linux. http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html

Para instalar JDK en Linux, ejecutamos el siguiente comando: yum localinstall jdk-version-linux.rpm

Una vez instalado JDK, debemos decirle a SQL Developer la ubicación de JDK. Para ello debemos editar el fichero product.conf. El fichero se ubica en la ruta: /home/usuario_sistema/.sqldeveloper/version_sqldeveloper/product.conf # gedit //home/usuario_sistema/.sqldeveloper/version_sqldeveloper/product.conf

En SetJavaHome escribimos la ruta de JDK. Configurada la ruta, guardamos los cambios en el fichero. Ahora abrimos una consola del sistema y como usuario oracle ejecutamos: $ sqldeveloper

Si la ruta de JDK está correctamente configurada, sqldeveloper debe iniciarse. En el caso de un sistema Windows, debemos descargar el paquete Windows 64-bit with

******ebook converter DEMO Watermarks*******


JDK 8 included o bien el paquete Windows 32-bit/64-bit, es preferible descargar el primero puesto que tiene la ventaja que trae incluido JDK y nos ahorramos el paso de tener que configurar la ruta en el fichero product.conf. La instalaciĂłn en Windows de SQL Developer es muy sencilla, simplemente descomprimimos el paquete descargado y la carpeta resultante la copiamos por ejemplo en C. Para iniciar SQL Developer, ejecutamos el archivo sqldeveloper.exe ubicado dentro de la carpeta. Podemos crear un acceso directo de dicho archivo al escritorio. En la siguiente imagen podemos ver la interfaz de la herramienta Oracle SQL Developer:

Figura 2.1 – Interfaz de la Herramienta Oracle SQL Developer

******ebook converter DEMO Watermarks*******


2.3 CONEXIÓN CON LA BASE DE DATOS ORACLE Para crear una conexión con la Base de Datos, seguimos los siguientes pasos: Vamos a Archivo, Nuevo, Conexión a Base de Datos, o bien hacemos clic en el icono Nueva Conexión del Panel Izquierdo. Se inicia el dialogo para Crear una Nueva Conexión a la Base de Datos. Los parámetros que tenemos que configurar son: Nombre Conexión, bdoracle Usuarios, sys Contraseña, **** Tipo de conexión, Básico Rol, SYSDBA Nombre del Host, Nombre del HOST o bien, la dirección IP del Servidor Puerto, 1521 SID, orcl Establecida la conexión con la Base de Datos, podemos seleccionar un objeto existente, o crear un nuevo objeto. Al seleccionar un objeto existente del Esquema de Base de Datos, en el Panel Derecho mostrará la información correspondiente al objeto seleccionado, dicha información se organiza en diferentes pestañas. El tipo y número de pestañas dependerá del tipo de objeto seleccionado. Al hacer clic con el botón derecho sobre un objeto existente, se desplegará un menú con diferentes opciones. En el caso de una tabla, por ejemplo tenemos opciones para editar, abrir, importar datos, exportar, etc. Desde el árbol jerárquico podemos también crear un nuevo objeto, simplemente hacemos clic con el derecho y seleccionando el tipo de objeto que queremos crear, por

******ebook converter DEMO Watermarks*******


ejemplo una Vista. Se nos mostrarรกn las opciones disponibles de creaciรณn del objeto seleccionado de objeto.

******ebook converter DEMO Watermarks*******


2.4 CONOCIENDO UN POCO SQL DEVELOPER En este punto vamos a hablar un poco de la herramienta SQL Developer. El objetivo es familiarizarnos con dicha herramienta, puesto que vamos a usarla a lo largo del libro. PANEL DBA Una pestaña interesante y que debemos conocer es la DBA. Para poder usar el Panel DBA, debemos crear primero una conexión como usuario administrador, SYS. Al conectarnos, tendremos disponible un árbol jerárquico con opciones que tienen que ver con la administración de la Base de Datos. Las opciones disponibles se clasifican dentro del árbol jerárquico en Configuración de la Base de Datos, Estado de la Base de Datos, Almacenamiento, Copia de Seguridad / Recuperación de RMAN, Programador, Pump de Datos, Rendimiento y Seguridad. Por ejemplo, para ver el estado en tipo real de la Base de Datos, haz clic en Estado de la Base de Datos, Instancia de la Base de Datos. Se presentará en el Panel Derecho una pantalla con información y gráficos muy interesantes sobre el estado de la Instancia de la Base de Datos. HOJA DE TRABAJO O EJECUCIÓN DE COMANDOS SQL Desde Herramientas, Hoja de Trabajo SQL, o bien pulsando el icono SQL de la barra de herramientas, accedemos a la Hoja de Trabajo de SQL Developer. Con una Hoja de Trabajo podemos escribir y ejecutar sentencias SQL, PL/SQL y SQL Plus. La interfaz dispone de dos secciones principales, un Editor SQL y un Generador de Consultas. Vamos a comentar a continuación cada una de estas secciones. EDITOR SQL En esta sección se escriben las sentencias que vamos a ejecutar. Para ejecutar varias sentencias que no sean PL/SQL, estas sentencias deben finalizar con punto o en caso de una nueva línea, con una barra /. Para sentencias PL/SQL, con una barra / y en una línea nueva.

******ebook converter DEMO Watermarks*******


Para dar un formato adecuado, podemos usar la opción formato o formato avanzado del menú contextual. Podemos arrastrar desde el Árbol Jerárquico, Panel Izquierdo, Conexiones, algunos tipos de objetos. Por ejemplo, en el caso de una tabla, se crea una sentencia SELECT de forma automática. Introducida una sentencia SQL, podemos ejecutarla desde el icono de Sentencia de Ejecución. Con esta opción se ejecuta la sentencia sobre la que se encuentra el cursor, mediante el icono Ejecutar Script, se ejecutan todas las sentencias que existan actualmente escritas en la Hoja de Trabajo. GENERADOR DE CONSULTAS Como su propio nombre indica, nos permite, o mejor dicho, nos facilita la creación de una consulta sobre un objeto seleccionado, una tabla o una vista. En la Pestaña Principal tenemos una representación gráfica del objeto tipo tabla, o vista. Podemos seleccionar las columnas que queremos mostrar. Debajo de la Pestaña Principal, disponemos de otra pestaña. Desde esta pestaña podemos indicar los criterios para las expresiones seleccionadas, las columnas de la tabla o vista. Los criterios o características que podemos configurar son: salida, Expresión, Agregar, Alias, Tipo de Orden, Orden de Clasificación, Agrupamientos, Criterio para y Criterios. En resumen y a modo general, las capacidades ofrecidas en SQL Developer son: Crear Conexiones con una Base de Datos, es posible crear conexiones con otro tipo de Base de Datos que no sea Oracle, por ejemplo MySQL. Explorar Objetos de un esquema de Base de Datos Crear todos los tipos de objetos de Base de Datos Modificar los objetos existentes Consultar y actualizar tablas y otros tipos de objetos como, por ejemplo vistas. Exportar Datos DDL e importar datos.

******ebook converter DEMO Watermarks*******


Administrar Servicios REST Digamos que las opciones listadas, son las más importantes, pero se pueden realizar algunas operaciones más desde SQL Developer de las comentadas. Por último, comentar que SQL Developer es un proyecto sobre el cual Oracle va realizando revisiones y se publican nuevas versiones cada cierto tiempo, ofreciendo en cada revisión nuevas funcionalidades.

******ebook converter DEMO Watermarks*******


CONCLUSIÓN Finalizamos ya con el capítulo 2, en este capítulo hemos realiza una introducción a SQL Developer, herramienta que todo DBA y Desarrollador que trabaje con Bases de Datos Oracle debería conocer. Con lo aprendido ya disponemos de conocimientos sobre el manejo y funcionamiento básico de la herramienta. En el siguiente capítulo vamos a crear la Base de Datos sobre la cual vamos a trabajar.

******ebook converter DEMO Watermarks*******


CAPÍTULO 3 CREACIÓN DE LA BASE DE DATOS En este capítulo vamos a crear la Base de Datos y la conexión desde SQL Developer que usaremos para trabajar con el lenguaje SQL en los próximos capítulos.

******ebook converter DEMO Watermarks*******


3.1 CDB Y PBD En la versión 12 de Oracle, durante el proceso de instalación nos encontramos con la opción de Base de Datos de contenedor, conocida por las siglas CDB y PDB. Nosotros lo hemos configurado en el Paso 11 de 21, ESPECIFICAR IDENTIFICADORES DE BASE DE DATOS. CDB y PDB significa Container and Plugable Databases, CDB es el contenedor de la Base de Datos principal. Digamos que es una Base de Datos tradicional con la característica de que soporta arquitectura multiusuario. Las Bases de Datos PDB conectan con el contenedor para que la información sea accesible entre SGA (Sistema de gestión de almacenes) y los procesos del contenedor, CDB. Para más información puedes consultar el siguiente enlace: http://docs.oracle.com/database/121/ADMIN/cdb_pdb_admin.htm#ADMIN13663

Vamos a comprobar, partiendo de la instalación que hemos realizado de Oracle 12c, si existe una instancia PDB activa. Iniciamos una sesión es SQL Plus con el usuario SYS y ejecutamos: $ sqlplus /nolog SQL> conn / as sysdba SQL> SHOW con_id CON_ID -----------------------------1 SQL> SHOW con_name; CON_NAME -----------------------------CDB$ROOT

Podemos ver en el resultado de la consulta, que existe una instancia PDB.

******ebook converter DEMO Watermarks*******


3.2 CREACIÓN DEL ESQUEMA Vamos a proceder ahora a crear el esquema de Base de Datos que usaremos. Desde la consola de SQL Plus y como usuario SYS vamos ejecutar los siguientes pasos. En primer lugar vamos a crear un tablespace para datos y otra para índices. Los Tablespace son la ubicación en el Sistema Operativo dónde se van a almacenar los objetos del esquema que vamos a crear. Creamos el Tablespace destinado a datos: SQL> CREATE TABLESPACE "PRODAT" LOGGING DATAFILE '/ora01/app/oracle/oradata/PROYECTOS/prodat.dbf' SIZE 1024M EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO;

Y el Tablespace destinado a índices: SQL> CREATE TABLESPACE "PROIDX" LOGGING DATAFILE '/ora01/app/oracle/oradata/PROYECTOS/proidx.dbf' SIZE 512M EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO;

Lo siguiente que vamos a hacer es crear el usuario, este usuario va a trabajar sobre los Tablespaces creados y será el propietario de los objetos que vamos a crear sobre estos Tablespace. SQL> CREATE USER C##PROJECT PROFILE DEFAULT IDENTIFIED BY PRO1 DEFAULT TABLESPACE "PRODAT" TEMPORARY TABLESPACE "TEMP" ACCOUNT UNLOCK;

Por último, asignamos los permisos necesarios para poder trabajar. Asignamos permisos mínimos, el usuario podrá conectarse y realizar las operaciones básicas, consulta, modificación y creación de objetos dentro del esquema. SQL> GRANT "CONNECT" TO C##PROJECT; SQL> GRANT "RESOURCE" TO C##PROJECT;

Completamos la asignación de permisos con privilegios específicos. SQL> GRANT ALTER ANY INDEX TO C##PROJECT; SQL> GRANT ALTER ANY SEQUENCE TO C##PROJECT; SQL> GRANT ALTER ANY TABLE TO C##PROJECT;

******ebook converter DEMO Watermarks*******


SQL> GRANT ALTER ANY TRIGGER TO C##PROJECT; SQL> GRANT CREATE ANY INDEX TO C##PROJECT; SQL> GRANT CREATE ANY SEQUENCE TO C##PROJECT; SQL> GRANT CREATE ANY SYNONYM TO C##PROJECT; SQL> GRANT CREATE ANY TABLE TO C##PROJECT; SQL> GRANT CREATE ANY TRIGGER TO C##PROJECT; SQL> GRANT CREATE ANY VIEW TO C##PROJECT; SQL> GRANT CREATE PROCEDURE TO C##PROJECT; SQL> GRANT CREATE PUBLIC SYNONYM TO C##PROJECT; SQL> GRANT CREATE TRIGGER TO C##PROJECT; SQL> GRANT CREATE VIEW TO C##PROJECT; SQL> GRANT DELETE ANY TABLE TO C##PROJECT; SQL> GRANT DROP ANY INDEX TO C##PROJECT; SQL> GRANT DROP ANY SEQUENCE TO C##PROJECT; SQL> GRANT DROP ANY TABLE TO C##PROJECT; SQL> GRANT DROP ANY TRIGGER TO C##PROJECT; SQL> GRANT DROP ANY VIEW TO C##PROJECT; SQL> GRANT INSERT ANY TABLE TO C##PROJECT; SQL> GRANT QUERY REWRITE TO C##PROJECT; SQL> GRANT SELECT ANY TABLE TO C##PROJECT; SQL> GRANT UNLIMITED TABLESPACE TO C##PROJECT;

******ebook converter DEMO Watermarks*******


3.3 CREACIÓN DE LA BASE DE DATOS PROYECTOS En este punto vamos a crear la Base de Datos Proyectos, sobre la cual vamos a trabajar a lo largo del libro. Lo primero que debemos hacer es ejecutar SQL Developer y a continuación configurar una conexión para el esquema que acabamos de crear. En el punto 2.3 CONEXIÓN CON LA BASE DE DATOS ORACLE, hemos visto cómo crear una conexión con la Base de Datos como usuario SYS. Ahora vamos a crear una conexión para el esquema PROJECT, usando el usuario PROJECT que creamos en el punto anterior. Desde SQL Developer, Archivo, Nuevo, Conexión a Base de Datos y asignamos la siguiente configuración: Nombre Conexión, PROJECT Usuarios, PROJECT Contraseña, PRO1 Tipo de conexión, Básico Rol, valor por defecto Nombre del Host, 192.168.7.100 Puerto, 1521 SID, orcl Una vez establecida la conexión, vamos a cargar los script para la creación de la Base de Datos. En la carpeta de recursos correspondiente a este capítulo, puedes encontrar los scripts BD_PROYECTOS.SQL y BD_PROYECTOS_INIT.SQL. Te recomiendo revises estos archivos para que puedas ver las tablas y las relaciones entre tablas de la Base de Datos que vamos a crear.

******ebook converter DEMO Watermarks*******


El Modelo Relacional puedes verlo a continuación:

Figura 3.1 – Modelo Relacional Base de Datos Proyectos

Desde SQL Developer vamos a Archivo, Abrir y seleccionamos el archivo BD_PROYECTOS.SQL. Ejecutamos el script haciendo clic sobre el botón Ejecutar Script o bien pulsando F5. SQL Developer nos indicará que seleccionemos una conexión existente o que creemos una, seleccionamos la conexión PROJECT. Una vez ejecutado el script y siempre que no se generen errores, la Base de Datos se habrá creado. Repetimos los pasos indicamos y seleccionamos el archivo BD_PROYECTOS_INIT.SQL, este archivo cargará la información sobre la Base de Datos. Perfecto, pues ya tenemos nuestro esquema preparado y estamos listos para comenzar a trabajar y aprender PL/SQL.

******ebook converter DEMO Watermarks*******


CONCLUSIÓN Hemos finalizado un nuevo capítulo. A lo largo del contenido de este capítulo, hemos explicado cómo crear un esquema de Base de Datos en Oracle 12c, tablespaces y usuario, y la asignación de permisos sobre el usuario creado. Posteriormente hemos configurado la conexión al esquema creado desde SQL Developer y cargado los scripts para creación de la Base de Datos. En el siguiente capítulo entramos ya en materia.

******ebook converter DEMO Watermarks*******


CAPÍTULO 4 ORACLE PL/SQL En este capítulo vamos a hacer una introducción al lenguaje PL/SQL y hablaremos sobre los aspectos básicos del lenguaje.

******ebook converter DEMO Watermarks*******


4.1 PL/SQL Procedural Language / Structured Query Language, PL/SQL, es un lenguaje incluido en la Base de Datos Oracle, basado en el lenguaje ADA e incorpora todas las características de un lenguaje de tercera generación. Con PL/SQL podemos crear procedimientos, funciones, paquetes, disparadores y otro tipo de objetos como por ejemplo una vista o un dblink. Todos estos objetos que creamos mediante el uso de PL/SQL, se almacenan en la Base de Datos Oracle y están incluidos dentro de las políticas de seguridad de Oracle. PL/SQL surge ante la necesidad de extender SQL, ya que SQL es un lenguaje de consulta y no de programación. Las características del lenguaje PL/SQL son: Uso de variables, de constantes y tipos de datos predefinidos o definidos. Estructuras de Control Paquetes Procedimientos Funciones Funciones predefinidas Tratamiento de Excepciones Utilización de comentarios

******ebook converter DEMO Watermarks*******


4.2 BLOQUES PL/SQL La unidad de trabajo en el lenguaje PL/SQL es el bloque, denominados también bloques anónimos. Un bloque está formado por una sección de declaración, otra de instrucciones y otra de tratamiento de excepciones. En un bloque se distinguen las siguientes secciones: La sección declaración es opcional, en esta sección se declaran las variables y constantes que vamos a utilizar en el bloque. La sección de instrucciones, que incluirá las instrucciones SQL y PL/SQL. La sección de excepciones, es opcional también e incluirá las instrucciones que tratarán las excepciones o errores que puedan surgir en la ejecución del bloque. La estructura básica de un bloque queda definida de la siguiente forma: [DECLARE Declaraciones] BEGIN Intrucciones [EXCEPTION Tratamiento de Excepciones] END;

Las secciones opcionales se muestran entre corchetes.

******ebook converter DEMO Watermarks*******


4.3 ENTRADA Y SALIDA DE DATOS Para mostrar datos en pantalla mediante PL/SQL utilizamos el procedimiento PUT_LINE incluido en el paquete DBMS_OUTPUT. El formato es el siguiente: DBMS_OUTPUT.PUT_LINE(EXPRESIÓN);

Para que la instrucción funcione, debemos definir el valor ON en la variable de entorno SERVEROUTPUT: SQL> SET SERVEROUTPUT ON;

Referente a la forma en que se introducen datos en un programa PL/SQL, podemos distinguir: Pasando los datos como parámetros al realizar la llamada al procedimiento o función Leer los datos desde una tabla o vista. Usando variables de sustitución desde un bloque anónimo.

******ebook converter DEMO Watermarks*******


4.4 TIPOS DE DATOS El lenguaje PL/SQL dispone de los mismos tipos de datos que SQL y añade tipos propios. Los tipos de datos más importantes del lenguaje son: CHAR (longitud). Permite almacenar cadenas de caracteres de longitud fija, la longitud máxima de almacenamiento se indica entre paréntesis. En caso de no indicar la longitud, se considera una cadena de un solo carácter. VARCHAR2 (longitud). Almacena cadenas de caracteres de longitud variable, entre paréntesis se especifica el valor de longitud máximo. Permite almacenar cadenas de hasta 32.767 bytes. LONG (longitud). A igual que VARCHAR, permite almacenar cadenas de caracteres de longitud variable hasta 2 Gigasbytes. NUMBER (precisión, escala). Permite almacenar números con la longitud de dígitos indicada en precisión, de los cuales serán decimales los indicados en escala. BINARY_INTEGER. Almacena en memoria números en formato binario en el rango -2147482647 y +2147482647. PLS_INTEGER. Es igual BINARY_INTEGER, pero tiene dos ventajas, las operaciones con este tipo de datos son más rápidas y en caso de desbordamiento de memoria, se producen excepciones. BOOLEAN. Almacena valores lógicos, TRUE, FALSE y NULL. DATE. Permite almacenar fecha y horas en el formato establecido, dicho formato podemos modificarlo.

******ebook converter DEMO Watermarks*******


4.5 IDENTIFICADORES Los identificadores son el conjunto de caracteres alfanumérico que usamos para nombrar los diferentes tipos de elementos, como variables, constantes, etc. Todos los lenguajes de programación establecen una serie de normas que rigen la composición de los identificadores. En PL/SQL se establecen las siguientes normas: Una longitud entre 1 y 30 caracteres. Comenzar por una letra. Sólo se admiten letras, números, y los símbolos $, # y _. PL/SQL no diferencia entre mayúsculas y minúsculas (Case Sensitive) en identificadores y palabras reservadas.

******ebook converter DEMO Watermarks*******


4.6 VARIABLES Una variable es un espacio en memoria reservado para almacenar información, cuyo valor puede variar a lo largo de la ejecución de un programa. Cada variable tiene asociado un identificador y un tipo de dato. Lo primero que debemos hacer antes de emplear una variable es declararla en la sección de declaración. La sintaxis para declarar una variable es la siguiente: <identificador><tipo de dato> [NOT NULL ] := {Default} <valor>;

Debemos indicar en primer lugar el nombre de la variable, el identificador y a continuación el tipo de dato. Podemos incluir la cláusula NOT NULL que indica que la variable no puede tomar un valor nulo, en este caso es obligatorio asignar un valor a la variable. Para asignar un valor a la variable los hacemos de la siguiente forma: variable:= valor;

O bien: variable:= Default valor;

Es posible asignar un valor a una variable aunque no esté declarada con NOT NULL. Vamos a ver unos ejemplos de declaración de Variables: DECLARE codproyecto CHAR(10); codservicio VARCHAR2(5); codempleado NUMBER(10,2); codtarea NUMBER (8) NOT NULT DEFAULT 1;

El tipo de valor asignado a las variables puede ser de cualquier tipo de los permitidos en PL/SQL. En la declaración de tipos de datos para una variable, podemos usar dos atributos, estos son:

******ebook converter DEMO Watermarks*******


%TYPE. Nos permite declarar el tipo de variable como el tipo de otra variable o como el tipo de atributo de una tabla. La sintaxis es la siguiente: <identificador><identificador variable o atributo>%TYPE;

Un ejemplo sería el siguiente: nombreempleado proyectos_empleados.nombre%TYPE;

Declaramos la variable nombreempleado con el mismo tipo que el atributo nombre de la tabla proyectos_empleados. Si queremos declarar una variable con el mismo tipo que la variable precio, lo haríamos de la siguiente forma: precioproducto precio%TYPE;

%ROWTYPE. Nos permite declarar una variable con el mismo tipo de tabla o vista de una Base de Datos. La sintaxis es la siguiente: <identificador><identificador tabla o vista>%ROWTYPE;

Un ejemplo de esto sería declarar una variable con el mismo tipo que una fila de la tabla departamentos: departamento proyectos_departamentos%ROWTYPE;

******ebook converter DEMO Watermarks*******


4.7 CONSTANTES Las constantes almacenan valores que no varían durante la ejecución de un programa, al igual que las variables, hay que definirlas en la sección de declaración para poder usarlas. La sintaxis de declaración de una constante es la siguiente: <nombre constante> CONSTANT <tipo> := <valor>;

En la declaración de una constante, es obligatorio asignarle un valor. Ejemplo: IVA CONSTANT NUMBER(2) := 21;

******ebook converter DEMO Watermarks*******


4.8 LITERALES Los literales son los valores que se expresan en un programa, directamente sin la intervención de una variable y pueden ser de cualquier tipo. Distinguimos los siguientes tipos: Numéricos. Se escriben tal cual, teniendo en cuenta que el separador decimal en PL/SQL por defecto es el punto y podemos emplear la notación científica. Algunos ejemplos son: 1.200, +12e1, 128e2. Carácter. Un solo carácter que se escribe entre comillas simples. Ejemplos: 'b', 'C', '4', '@', '<'. Cadena de Caracteres. Varios caracteres limitados por comillas simples. Ejemplos de cadena son: 'Isaac', 'Nombre de usuario:', 'F001BA2'. Fecha / Hora. Son literales que contienen fechas y hora, también se deben indicar entre comillas simples. Ejemplos: '12/12/2016', '07/12/16 15:52:48,210000000 EUROPE/PARIS'. Booleano. Es un literal que se representa mediante los valores TRUE, FALSE o NULL.

******ebook converter DEMO Watermarks*******


4.9 OPERADORES Los operadores nos permiten realizar los diferentes tipos de operaciones sobre los datos, a estos datos los llamados operandos. Los operandos en PL/SQL son los mismos que en SQL, añadiendo algunos más. Vamos a verlos a continuación. 4.9.1 OPERADORES ARITMÉTICOS Son operadores que nos permiten la realización de operaciones matemáticas, son los siguientes:

Podemos restar dos fechas dadas, dando como resultado la diferencia entre ambas fechas expresadas en número de días. También podemos sumar a una fecha un número de días (fecha + ndias) o restar un número de días (fecha – n). 4.9.2 OPERADORES LÓGICOS O DE COMPARACIÓN Estos operadores comparan dos valores y devuelven un valor verdadero (TRUE) o falso (FALSE) en función de si se cumple o no se cumple la condición establecida.

******ebook converter DEMO Watermarks*******


4.9.3 OPERADORES Lร GICOS Los operadores lรณgicos trabajan sobre valores booleanos (TRUE, FALSE y NULL) y devuelven un valor booleano. Existen tres tipos de operadores: Operador lรณgico AND. Devuelve verdadero si todos los valores sobre los que opera son verdaderos, siguiendo lo indicado en la siguiente tabla

Operador lรณgico OR. Devuelve verdadero si unos de los operadores sobre los que opera es verdadero, de acuerdo a lo indicado en la siguiente tabla:

Operador lรณgico NOT. Devuelve el valor contrario del operador. NOT VERDADERO = FALSO, NOT FALSO = VERDADERO Y NOT NULL = NULL.

******ebook converter DEMO Watermarks*******


4.9.4 OPERADOR DE ASIGNACIÓN El operador de asignación en PL/SQL es := y asigna un valor a una variable. El valor que asignamos a una variable puede ser otra variable, una constante, una expresión o un literal. Las sintaxis de asignación es la siguiente: <variable> := <valor>;

Algunos ejemplos: fecha1 DATE := '12/12/2016'; nombre VARCHAR2(80) := 'Juan Antonio'; precio NUMBER(10,2) := 200,25; total NUMBER(20,5) := (800*21/100)+800;

4.9.5 OPERADORES DE CONCATENACIÓN DE CADENAS DE CARÁCTER El operador que usamos en PL/SQL para concatenar o unir cadenas es ||. Un ejemplo de uso es el siguiente: nombrecompleto := nombre |' '| apellido1 |' '| apellido2;

4.9.6 ORDEN DE PRECEDENCIA EN LOS OPERADORES El orden en el que se avalúan las operaciones de una expresión lo determina el orden de procedencia de los operadores, de acuerdo a lo indicado en la siguiente tabla.

Según lo indicado en la tabla, en la operación 160 – 60 *2, la multiplicación se

******ebook converter DEMO Watermarks*******


realizarĂĄ antes que la suma. El orden de procedencia puede ser modificado mediante el uso del parĂŠntesis. Si queremos modificar el orden en el que se realizan las operaciones del ejemplo anterior, lo harĂ­amos de la siguiente forma: (160-60)*2

******ebook converter DEMO Watermarks*******


4.10 COMENTARIOS Tal como ocurre en todos los lenguajes de programación, en PL/SQL se pueden añadir comentarios. Los comentarios ayudan a los programadores, facilitando la comprensión del código y no intervienen en la ejecución del programa. Simplemente son líneas informativas que el programa no ejecuta y proporcionan información sobre funcionamiento del código, modificaciones realizadas, etc. En resumen, los comentarios son para el programador. En PL/SQL podemos usar dos tipos de comentarios, son: Comentarios de líneas. Se inicia con -- y todo lo que aparece detrás y este comprendido en una sola línea, no será considerado como código PL/SQL. Ejemplo: -- Esto es un ejemplo de comentario de una sola línea

Comentarios de varias líneas. Comienza con /* y finaliza con */, se usan para comentarios que comprendan varias líneas. Ejemplo: /* Esto es un ejemplo de comentario de varias líneas */

******ebook converter DEMO Watermarks*******


CONCLUSIÓN Llegamos al final de este capítulo, a lo largo del capítulo hemos estudiado lo básico que se debe conocer de un lenguaje de programación, tipos de datos, definición de variables, definición de constantes, operadores, etc. Ya hemos entrado en contacto con el lenguaje PL/SQL, en el siguiente capítulo vamos a ver las estructuras de control que posee PL/SQL.

******ebook converter DEMO Watermarks*******


CAPÍTULO 5 ESTRUCTURAS DE CONTROL Como todos los lenguajes de programación, PL/SQL incluye diferentes estructuras de control que nos permiten controlar el flujo de ejecución de un programa. En este capítulo, vamos a estudiar los diferentes tipos de estructuras de control de PL/SQL.

******ebook converter DEMO Watermarks*******


5.1 ESTRUCTURA ALTERNATIVA La estructura alternativa consta de la sentencia IF y la sentencia CASE, permite, en función del cumplimiento o no de una determinada condición, decidir la secuencia de código a ejecutar. Existen varias variantes de la estructura alternativa en PL/SQL, vamos a verlas. 5.1.1 ESTRUCTURA ALTERNATIVA SIMPLE La estructura alternativa simple comprueba una condición determinada, si la condición establecida se cumple, se ejecuta una secuencia de instrucciones. En caso de que no se cumpla, la secuencia de código no se ejecutará. La sintaxis de la estructura alternativa simple es la siguiente: IF <condición> THEN instrucción_1; instrucción_2; instrucción_n; END IF;

Veamos un ejemplo, vamos a crear un bloque anónimo donde vamos a seleccionar el presupuesto del proyecto con código 3 y lo guardamos en la variable VPRO. A continuación, comprobamos si el presupuesto es superior a 12000. En caso de que se cumpla la condición establecida, aplicamos un descuento del 15% en el presupuesto del proyecto. DECLARE VPRE PROYECTOS_PROYECTOSTIC.PRESUPUESTO%TYPE; BEGIN SELECT PRESUPUESTO INTO VPRE FROM PROYECTOS_PROYECTOSTIC WHERE CODPROYECTO=3; IF VPRE > 12000 THEN UPDATE PROYECTOS_PROYECTOSTIC SET PRESUPUESTO = PRESUPUESTO(PRESUPUESTO*15/100) WHERE CODPROYECTO=3; DBMS_OUTPUT.PUT_LINE('15% DE DESCUENTO APLICADO AL PROYECTO CON CÓDIGO 3');

******ebook converter DEMO Watermarks*******


END IF; END;

En PL/SQL la sentencia SELECT nos permite incluir antes de la cláusula FROM una cláusula denominada INTO. La cláusula INTO seguida del nombre de una o varias variables nos permite guardar el resultado de una consulta. 5.1.2 ESTRUCTURA ALTERNATIVA DOBLE En la estructura alternativa doble, si se cumple la condición establecida, se ejecuta una secuencia de instrucciones. En caso de que no se cumpla la secuencia, se ejecuta otra secuencia de instrucciones. La sintaxis de la estructura alternativa doble en la siguiente: IF <condición> THEN instrucción_1; instrucción_2; instrucción_n; ELSE instrucción_1; instrucción_2; instrucción_n; END IF;

Vamos a ver un ejemplo para esta estructura, la condición establecida es la misma que la anterior, pero en este caso, seleccionamos el presupuesto del proyecto con código 2. Si la condición se cumple, aplicamos un descuento del 15% sobre el presupuesto. En caso de que no se cumpla la condición, aplicamos un descuento del 8%. DECLARE VPRE PROYECTOS_PROYECTOSTIC.PRESUPUESTO%TYPE; BEGIN SELECT PRESUPUESTO INTO VPRE FROM PROYECTOS_PROYECTOSTIC WHERE CODPROYECTO=2; IF VPRE > 12000 THEN

******ebook converter DEMO Watermarks*******


UPDATE PROYECTOS_PROYECTOSTIC SET PRESUPUESTO = PRESUPUESTO(PRESUPUESTO*15/100) WHERE CODPROYECTO=2; DBMS_OUTPUT.PUT_LINE('15% DE DESCUENTO APLICADO AL PROYECTO CON CÓDIGO 2'); ELSE UPDATE PROYECTOS_PROYECTOSTIC SET PRESUPUESTO = PRESUPUESTO(PRESUPUESTO*8/100) WHERE CODPROYECTO=2; DBMS_OUTPUT.PUT_LINE('8% DE DESCUENTO APLICADO AL PROYECTO CON CÓDIGO 2'); END IF; END;

5.1.3 ESTRUCTURA ALTERNATIVA MÚLTIPLE La estructura alternativa múltiple, consiste en varias estructuras alternativas dobles anidadas. La estructura alternativa múltiple tiene la siguiente sintaxis: IF <condición> THEN instrucción_1; instrucción_2; instrucción_n; ELSEIF <condición> THEN instrucción_1; instrucción_2; instrucción_n; [ELSE instrucción_n+1]; END IF;

Veamos un ejemplo, en este ejemplo vamos a trabajar sobre el proyecto con código 5. El funcionamiento es idéntico al ejemplo anterior, añadiendo una sentencia IF, ELSIF. En este ejemplo se evalúa la condición establecida en el primer IF, si la condición se cumple se ejecuta la sentencias del primer bloque IF. En caso de que la condición no se

******ebook converter DEMO Watermarks*******


cumpla, el flujo del programa pasa a evaluar la condición establecida en el siguiente bloque IF, ELSIF. Si la condición es correcta se ejecuta las sentencias escritas en este bloque de código. En caso de que no se cumpla ninguna condición de las establecidas en los bloques IF - ELSIF, se ejecutan las sentencias escritas en el bloque ELSE. DECLARE VPRE PROYECTOS_PROYECTOSTIC.PRESUPUESTO%TYPE; BEGIN SELECT PRESUPUESTO INTO VPRE FROM PROYECTOS_PROYECTOSTIC WHERE CODPROYECTO=5; IF VPRE > 10000 THEN UPDATE PROYECTOS_PROYECTOSTIC SET PRESUPUESTO = PRESUPUESTO(PRESUPUESTO*15/100) WHERE CODPROYECTO=5; DBMS_OUTPUT.PUT_LINE('15% DE DESCUENTO APLICADO AL PROYECTO CON CÓDIGO 5'); ELSIF VPRE < 8000 THEN UPDATE PROYECTOS_PROYECTOSTIC SET PRESUPUESTO = PRESUPUESTO(PRESUPUESTO*10/100) WHERE CODPROYECTO=5; DBMS_OUTPUT.PUT_LINE('10% DE DESCUENTO APLICADO AL PROYECTO CON CÓDIGO 5'); ELSE UPDATE PROYECTOS_PROYECTOSTIC SET PRESUPUESTO = PRESUPUESTO(PRESUPUESTO*8/100) WHERE CODPROYECTO=5; DBMS_OUTPUT.PUT_LINE('8% DE DESCUENTO APLICADO AL PROYECTO CON CÓDIGO 5'); END IF; END;

5.1.4 ESTRUCTURA ALTERNATIVA MÚLTIPLE CON CASE DE COMPROBACIÓN La estructura alternativa múltiple dispone de la instrucción CASE de comprobación. La sintaxis para este tipo de instrucción es la siguiente: CASE <Expresión> WHEN <Valor_1> THEN Instrucción; WHEN <Valor_2> THEN

******ebook converter DEMO Watermarks*******


Instrucción; WHEN <Valor_N> THEN Instrucción; [ELSE Instrucción;] END CASE;

En primer lugar se evalúa la expresión, si el valor de la expresión coincide con la condición establecida en valor_1, se ejecutan las instrucciones de este bloque y termina la sentencia CASE. En caso de que no se cumpla la expresión valor_1, se evalúa la condición establecida en valor_2, y así sucesivamente. Si no se cumplen ningunas de las expresiones establecidas, y hemos definido un bloque ELSE, se ejecutan las instrucciones del bloque ELSE y finalizando la sentencia CASE. Vamos a ver un ejemplo sobre esto: DECLARE VPRI PROYECTOS_PROYECTOSTIC.IDPRIORIDAD%TYPE; VPOR NUMBER(2,0); BEGIN SELECT IDPRIORIDAD INTO VPRI FROM PROYECTOS_PROYECTOSTIC WHERE CODPROYECTO=1; CASE VPRI WHEN 'baja' THEN VPOR := 10; WHEN 'media' THEN VPOR := 15; WHEN 'alta' THEN VPOR := 20; WHEN 'muy alta' THEN VPOR := 25; ELSE VPOR := 30;

******ebook converter DEMO Watermarks*******


END CASE; UPDATE PROYECTOS_PROYECTOSTIC SET PRESUPUESTO=PRESUPUESTO+ (PRESUPUESTO*VPOR/100); END;

En el ejemplo seleccionamos la prioridad del proyecto con código 1 y evaluamos la condición. El valor coincidente, indica el porcentaje a aplicar al presupuesto del proyecto al final del bloque. 5.1.5 ESTRUCTURA ALTERNATIVA MÚLTIPLE CON CASE DE BÚSQUEDA La estructura alternativa admite otra variación, el uso de la instrucción CASE de búsqueda. Esta estructura presenta el siguiente formato: CASE WHEN <Condición_1> THEN Instrucción; WHEN <Condición_2> THEN Instrucción; WHEN <Condición_N> THEN Instrucción; [ELSE Instrucción;] END CASE;

El funcionamiento de esta estructura es similar a la estructura alternativa múltiple con IF. Vamos a modificar el ejemplo del punto anterior para adaptarlo a este tipo de estructura. DECLARE VPRI PROYECTOS_PROYECTOSTIC.IDPRIORIDAD%TYPE; VPOR NUMBER(2,0);

******ebook converter DEMO Watermarks*******


BEGIN SELECT IDPRIORIDAD INTO VPRI FROM PROYECTOS_PROYECTOSTIC WHERE CODPROYECTO=1; CASE WHEN VPRI = 'baja' THEN VPOR := 10; WHEN VPRI = 'media' THEN VPOR := 15; WHEN VPRI = 'alta' THEN VPOR := 20; WHEN VPRI = 'muy alta' THEN VPOR := 25; ELSE VPOR := 30; END CASE; UPDATE PROYECTOS_PROYECTOSTIC SET PRESUPUESTO=PRESUPUESTO+ (PRESUPUESTO*VPOR/100); END;

El resultado es el mismo que obtenemos en la estructura alternativa con CASE de comprobaciรณn.

******ebook converter DEMO Watermarks*******


5.2 ESTRUCTURA REPETITIVA La estructura repetitiva nos permite repetir una secuencia de instrucciones un número determinado de veces, de acuerdo al cumplimiento de una condición establecida. En PL/SQL disponemos de dos tipos de estructuras repetitivas, vamos a verlas en los siguientes puntos. 5.2.1 ESTRUCTURA REPETITIVA WHILE La estructura repetitiva while permite la ejecución de un grupo de instrucciones mientras se cumpla la condición establecida. Al finalizar la ejecución, se vuelve a comprobar la condición. Si se cumple la condición, se vuelve a ejecutar la secuencia y así sucesivamente. En caso de que no se cumpla, el bucle finaliza. La sintaxis para esta estructura es la siguiente: WHILE <Condición> loop instrucción_1; instrucción_2: instrucción_n; END LOOP;

Vemos a continuación un ejemplo para este tipo de estructura. DECLARE VNOMBRE PROYECTOS_PROYECTOSTIC.NOMBRE%TYPE; C NUMBER(1,0):= 1; F NUMBER(1,0); BEGIN SELECT COUNT(CODPROYECTO) INTO F FROM PROYECTOS_PROYECTOSTIC WHERE NOMBRE LIKE '%Desarrollo%'; WHILE C <= F LOOP SELECT NOMBRE INTO VNOMBRE FROM PROYECTOS_PROYECTOSTIC WHERE CODPROYECTO = C; DBMS_OUTPUT.PUT_LINE(VNOMBRE); C:=C+1;

******ebook converter DEMO Watermarks*******


END LOOP; END;

En este ejemplo, contamos el número de filas que tiene la tabla proyectos_proyectostic que contenga la palabra Desarrollo en el atributo nombre y lo almacenamos en la variable F. Posteriormente, mediante un bucle WHILE, mostramos en pantalla el nombre de cada proyecto. 5.2.2 ESTRUCTURA REPETITIVA FOR La estructura repetitiva FOR, es una estructura que repite un bloque de instrucciones un número determinado de veces. El bucle FOR se emplea cuando se conoce el número de veces que se va a repetir la secuencia de instrucciones. La sintaxis para esta instrucción es la siguiente: FOR <Variable de Control> IN <Valor Inicial>..<Valor Final> LOOP instrucción_1; instrucción_2: instrucción_n; END LOOP;

La variable de control no es necesaria declararla en la sección DECLARE del bloque, ya que por defecto se declara de forma implícita como tipo BINARY_INTEGER. La variable se iniciará con el valor indicado como valor inicial, por cada ejecución del bucle la variable aumentará su valor en una unidad hasta llegar al valor final. Vamos a modificar el ejemplo visto en el punto anterior para adaptarlo a la estructura FOR. DECLARE VNOMBRE PROYECTOS_PROYECTOSTIC.NOMBRE%TYPE; C NUMBER(1,0):= 1; F NUMBER(1,0); BEGIN SELECT COUNT(CODPROYECTO) INTO F FROM PROYECTOS_PROYECTOSTIC WHERE NOMBRE LIKE '%Desarrollo%';

******ebook converter DEMO Watermarks*******


FOR I IN C..F LOOP SELECT NOMBRE INTO VNOMBRE FROM PROYECTOS_PROYECTOSTIC WHERE CODPROYECTO = I; DBMS_OUTPUT.PUT_LINE(VNOMBRE); END LOOP; END;

El resultado es el mismo que para la estructura WHILE. Por defecto, la variable de control aumenta en una unidad, pero es posible conseguir que la variable de control decremente en una unidad por cada ejecuciรณn del bucle. FOR <Variable de Control> IN REVERSE <Valor Inicial>..<Valor Final> LOOP instrucciรณn_1; instrucciรณn_2: instrucciรณn_n; END LOOP;

Vamos a ver un ejemplo en el cual imprimimos en pantalla los valores que toma i en forma descendente, para ello usamos la opciรณn IN REVERSE. BEGIN FOR I IN REVERSE 1..99 LOOP DBMS_OUTPUT.PUT_LINE(I); END LOOP; END;

******ebook converter DEMO Watermarks*******


CONCLUSIÓN Con lo visto en este capítulo, ya conocemos la base del lenguaje PL/SQL y estamos preparado para comenzar a trabajar con subprogramas. En el próximo capítulo vamos a entrar en materia y comenzaremos a estudiar los Procedimientos.

******ebook converter DEMO Watermarks*******


CAPÍTULO 6 PROCEDIMIENTOS Hasta ahora hemos estado trabajando con bloques anónimos, es decir, bloques que no tienen asociado un nombre. Estos bloques son escritos y ejecutados, pero no quedan almacenados en la Base de Datos. Los subprogramas son otro tipo de bloques, no anónimos, que tienen asociado un nombre y pueden recibir y devolver valores. Existen dos tipos de subprogramas, los procedimientos y las funciones, ambos subprogramas se almacenan en la Base de Datos y pueden ser llamados desde otros subprogramas o bloques anónimos. Un subprograma consta de una cabecera y un cuerpo. La cabecera incluirá: El nombre del subprograma. Los datos que recibe el subprograma. Por cada dato se debe indicar el nombre y el tipo de dato. El tipo de dato que devuelve, solo para los subprogramas que sean funciones. El cuerpo incluirá: La sección de declaración, es opcional. La sección de instrucciones, para el caso de una función, debe incluirse una instrucción que devuelve el valor de retorno. La sección de excepción, también es opcional. En este capítulo vamos a estudiar los procedimientos, y en el siguiente capítulo veremos las funciones.

******ebook converter DEMO Watermarks*******


6.1 PROCEDIMIENTOS EN PL/SQL Un procedimiento es un subprograma que puede recibir una serie de parámetros y no devuelve ningún parámetro.

******ebook converter DEMO Watermarks*******


6.2 CREACIร N DE PROCEDIMIENTOS Las sintaxis para definir un procedimiento es la siguiente: CREATE [OR REPLACE] PROCEDURE <Nombre Procedimiento> [(<Lista de Parรกmetros>)] [{IS|AS} Declaraciones] BEGIN Instrucciones; [EXCEPTION Tratamiento de Excepciones] END <Nombre Procedimiento>;

Tal como podemos observar en la sintaxis, para crear un procedimiento necesitamos emplear la instrucciรณn CREATE PROCEDURE, y a continuaciรณn la cabecera y el cuerpo del procedimiento. Con la opciรณn OR REPLACE, indicamos que en caso de ya existir un procedimiento con el mismo nombre, dicho procedimiento serรก reemplazado por el procedimiento creado. A diferencia de como ocurre en los bloques anรณnimos, la secciรณn de declaraciones comienza con la palabra IS o la palabra AS en lugar de DECLARE. Los parรกmetros son opcionales. Para cada parรกmetro definido, se debe indicar el nombre del parรกmetro y el tipo. Para separar cada parรกmetro usamos la coma (,). La definiciรณn de los parรกmetros dentro de un procedimiento debe seguir el siguiente formato: (<nombre parรกmetro_1><tipo_1>,<nombre parรกmetro_2><tipo_2>,...)

En los tipos de datos no debemos indicar el tamaรฑo, es decir, si definimos como parรกmetro una cadena de caracteres variable, debe quedar como VARCHAR2 y no VARCHAR2(Logitud). Veamos a continuaciรณn algunos ejemplos de procedimientos.

******ebook converter DEMO Watermarks*******


6.3 EJEMPLOS DE PROCEDIMIENTOS Vamos a crear un procedimiento que muestre la fecha actual del sistema formateada. CREATE OR REPLACE PROCEDURE OBTENER_FECHA_ACTUAL IS FECHA VARCHAR2(50); BEGIN SELECT TO_CHAR(SYSDATE,'DD "DE " FMMONTH " DE " YYYY') INTO FECHA FROM DUAL; DBMS_OUTPUT.PUT_LINE(FECHA); END;

Una vez creado el procedimiento, queda almacenado en la Base de Datos. Para hacer una llamada al procedimiento creado, lo hacemos desde un bloque anรณnimo: BEGIN OBTENER_FECHA_ACTUAL; END;

Creamos ahora un procedimiento para dar de alta un nuevo servicio. CREATE OR REPLACE PROCEDURE NUEVO_SERVICIO (PCODSERVICIO VARCHAR2, PNOMBRE VARCHAR2, PDESCRIPCION VARCHAR2) IS BEGIN INSERT INTO PROYECTOS_SERVICIOS (CODSERVICIO, NOMBRE, DESCRIPCION) VALUES(PCODSERVICIO, PNOMBRE , PDESCRIPCION); END NUEVO_SERVICIO;

Llamamos a este procedimiento de la siguiente forma: BEGIN NUEVO_SERVICIO('009NS', ' Nuevo servicio',' esto es un ejemplo de descripciรณn'); END;

Creamos otro procedimiento para actualizar el presupuesto de proyecto, especificando

******ebook converter DEMO Watermarks*******


el código de proyecto. CREATE OR REPLACE PROCEDURE ACTUALIZAR_PRESUPUESTO (PCODPROYECTO NUMBER, PPRESUPUESTO NUMBER) IS BEGIN UPDATE PROYECTOS_PROYECTOSTIC SET PRESUPUESTO=PPRESUPUESTO WHERE CODPROYECTO = PCODPROYECTO; END ACTUALIZAR_PRESUPUESTO;

Para llamar a este procedimiento, usamos el siguiente bloque: BEGIN ACTUALIZAR_PRESUPUESTO(4, 1000); END;

Desde un procedimiento es posible llamar a otro procedimiento. También podemos llamar a un procedimiento mediante la orden EXECUTE y a continuación la llamada al procedimiento. Para los ejemplos vistos anteriormente quedaría: SQL> EXECUTE OBTENER_FECHA_ACTUAL; SQL> EXECUTE NUEVO_SERVICIO('009NS','Nevo servicio','esto es un ejemplo de descripción'); SQL> EXECUTE ACTUALIZAR_PRESUPUESTO(4, 1000);

******ebook converter DEMO Watermarks*******


CONCLUSIÓN Finalizamos el capítulo 6, durante el capítulo hemos trabajo y estudiado los procedimientos, con lo visto en el capítulo ya estamos preparado para definir cualquier tipo de procedimiento para la Base de Datos Oracle. En el capítulo 7, vamos a trabajar con funciones.

******ebook converter DEMO Watermarks*******


CAPÍTULO 7 FUNCIONES En este capítulo vamos a hablar de subprogramas del tipo función. Anteriormente hemos dicho que procedimientos y funciones son subprogramas, la diferencia entre ellos es que las funciones retornan un valor y los procedimientos no. Vamos a ver a continuación como creamos funciones en Oracle y varios ejemplos de funciones.

******ebook converter DEMO Watermarks*******


7.1 FUNCIONES EN PL/SQL La función es un subprogama que recibe una serie de parámetros y devuelve un valor. Las funciones nos ayudan a resolver problemas en tareas más simples e implementan tareas u operaciones que son repetitivas en la ejecución de un programa. Cada función se define para realizar una determinada labor. Para hacer uso de una función, simplemente tenemos que llamarla. En muchos casos usamos funciones y desconocemos como trabajan internamente, simplemente pasamos los parámetros y nos retorna un valor.

******ebook converter DEMO Watermarks*******


7.2 CREACIÓN DE FUNCIONES La sintaxis para definir una función en PL/SQL en la siguiente: CREATE [OR REPLACE] FUNCTION <Nombre Función> [(<Lista de Parámetros>)] RETURN <Tipo Valor Devuelto> [{IS|AS} Declaraciones] BEGIN Instrucciones; RETURN <Expresión>; [EXCEPTION Tratamiento de Excepciones] END <Nombre Función>;

Al igual que para los procedimientos, para crear una función usamos la instrucción CREATE [OR REPLACE] y sustituimos PROCEDURE por FUNCTION, y a continuación especificamos la cabecera y el cuerpo de la función. En el caso de las funciones, a diferencia de los procedimientos, en la cabecera debemos indicar el tipo de valor devuelto después de la palabra RETURN. Dentro del cuerpo de la función, debemos incluir también la instrucción: RETURN <Expresión>;

Con dicha instrucción la función devuelve un valor al programa que ejecuta la llamada. Vamos a ver algunos ejemplos de funciones que nos van a ayudar a entender mejor el concepto de función.

******ebook converter DEMO Watermarks*******


7.3 EJEMPLOS DE FUNCIONES Función que toma como parámetro un número decimal de cualquier tipo, con varios decimales, y devuelve un número decimal formateado con dos decimales. CREATE OR REPLACE FUNCTION FORMATO_NUMERO (PNUMBER IN NUMERIC) RETURN VARCHAR2 IS VNUMERO VARCHAR2(255); BEGIN SELECT TO_CHAR(PNUMBER,'999G999G9999G999G999D99') INTO VNUMERO FROM DUAL; RETURN VNUMERO; END;

Creada la función, es necesario llamarla, para ello al igual que la llamada a un procedimiento, usamos un bloque anónimo. Llamamos a la función por su nombre e indicamos los parámetros correspondientes. Hay que tener en cuenta que la función devuelve un valor, por lo que podemos situar la llamada a la función en cualquier lugar donde se pueda escribir una expresión. Ejemplos de tipos de instrucciones de llamada a una instrucción son: <variable>:=<Nombre Función>[<Lista de Parámetros>]; DBMS_OUTPUT.PUT_LINE(<Nombre Función>[<Lista de Parámetros>]);

Para llamar a la función definida usamos un bloque anónimo de la siguiente forma: BEGIN DBMS_OUTPUT.PUT_LINE(formato_numero(12200.666999998844)); END;

O bien: DECLARE PARAMETRO VARCHAR2(255);

******ebook converter DEMO Watermarks*******


BEGIN PARAMETRO:= 'hola'; DBMS_OUTPUT.PUT_LINE(formato_numero(12200.666999998844)); END;

Creamos ahora una función que devuelve el último código de la tabla proyectos_empleados. CREATE OR REPLACE FUNCTION MAXCOD RETURN NUMERIC AS MAXIMO NUMERIC DEFAULT 0; BEGIN SELECT MAX(CODEMPLEADO) INTO MAXIMO FROM PROYECTOS_EMPLEADOS; IF MAXIMO IS NULL THEN RETURN 1; ELSE RETURN MAXIMO+1; END IF; END;

Para la función definida, hacemos la llamada de la siguiente forma: BEGIN DBMS_OUTPUT.PUT_LINE(MAXCOD); END;

Esta función es muy útil para usar en tablas donde los registros deben de tener un orden y sin saltos, como por ejemplo el contador de facturas. Veamos otro ejemplo de función que nos devuelve el día en formato DD de una fecha pasada como parámetro. CREATE OR REPLACE FUNCTION DIA (FECHA IN DATE) RETURN VARCHAR2

******ebook converter DEMO Watermarks*******


IS DIA NUMERIC; BEGIN SELECT EXTRACT(DAY FROM FECHA) INTO DIA FROM DUAL; RETURN DIA; END;

Para llamar a esta funciรณn usamos el siguiente bloque anรณnimo: BEGIN DBMS_OUTPUT.PUT_LINE(DIA('12/12/2016')); END;

******ebook converter DEMO Watermarks*******


CONCLUSIÓN Con este último ejemplo finalizamos este capítulo, a lo largo del capítulo hemos definido las funciones, como creamos funciones en Oracle y algunos ejemplos de funciones. En el siguiente capítulo hablaremos sobre los parámetros.

******ebook converter DEMO Watermarks*******


CAPÍTULO 8 PARÁMETROS Como ya hemos visto en los capítulos 6 y 7, el paso de información a un subprograma se realiza mediante parámetros. Podemos distinguir dos tipos de parámetros, los parámetros formales y los parámetros reales o actuales. Los parámetros formales se declaran en la cabecera del procedimiento o función. Los parámetros actuales o reales aparecen en la llamada al procedimiento o función. Algo muy importante que debemos de tener en cuenta, es que los parámetros formales y actuales deben ser compatibles, es decir, no podemos definir un parámetro formal y un parámetro actual de distinto tipo en el mismo subprograma.

******ebook converter DEMO Watermarks*******


8.1 PASO DE PARÁMETROS En PL/SQL podemos realizar el paso de parámetros utilizando tres métodos, estos métodos son: 8.1.1 NOTACIÓN POSICIONAL En la notación posicional cada parámetro actual se corresponde con cada parámetro formal, de acuerdo a las posiciones. El primer parámetro formal toma el valor primer parámetro actual, el segundo parámetro formal toma el valor del segundo parámetro actual, así sucesivamente. La notación posicional es la más usada. Un ejemplo de notación posicional sería el siguiente: NUEVO_SERVICIO('009NS', ' Nuevo servicio',' esto es un ejemplo de descripción');

8.1.2 NOTACIÓN NOMINAL La notación nominal incluye el símbolo => a continuación de cada parámetro actual indicando el nombre del parámetro formal al que se le va a asignar dicho valor. Los parámetros se pueden pasar sin tener en cuenta el orden. Ejemplo de notación nominal sería: NUEVO_SERVICIO('009NS'=> CODSERVICIO, 'Nuevo servicio'=> NOMBRE,' Esto es un ejemplo de descripción'=> DESCRIPCION);

8.1.3 NOTACIÓN MIXTA Consiste en usar ambas notaciones, teniendo en cuenta que la notación posicional precede a la nominal. Independientemente del método que usemos para el paso de parámetros, un parámetro formal puede tener asignado un valor mediante DEFAULT. En este caso, no es necesario indicar el parámetro en la llamada.

******ebook converter DEMO Watermarks*******


8.2 TIPOS DE PARÁMETROS Los parámetros en PL/SQL pueden ser de entrada, salida y entrada/salida. 8.2.1 PARÁMETROS DE ENTRADA, IN Los parámetros de entrada son los datos que se pasan a un subprograma para que dicho subprograma realiza operaciones con dichos datos. En el subprograma no podemos asignar ningún valor al parámetro formal, solo podemos realizar operaciones con el valor del parámetro. El parámetro actual o real puede ser una variable, una constante o una expresión. 8.2.2 PARÁMETROS DE SALIDA, OUT Los parámetros de salida son usados para devolver datos desde el subprograma llamado. El parámetro formal definido en la cabecera debe ser una variable, a esta variable se le asigna el valor en el subprograma llamado y este valor es devuelto al subprograma que realiza la llamada. 8.2.3 PARÁMETROS DE ENTRADA/ SALIDA, IN OUT Este tipo de parámetros sirven para pasar datos del subprograma llamado al subprograma que realiza la llamada, en este caso, el subprograma llamado puede modificar el valor del parámetro y devolver dicho valor modificado al subprograma llamante. El parámetro debe ser también una variable. Los parámetros con los que hemos estado trabajando en los procedimientos y funciones vistas anteriormente son parámetros de entrada. Los parámetros de entradas son los parámetros por defecto y es el único tipo de parámetro al cual se le puede asignar un valor por defecto.

******ebook converter DEMO Watermarks*******


8.3 DEFINICIÓN DE LOS TIPOS DE PARÁMETROS Para definir el tipo de parámetro se debe indicar a continuación del nombre del parámetro formal IN (Entrada), OUT (Salida) o IN OUT (Entrada/Salida). Si el parámetro definido es de entrada, no es necesario especificar nada a continuación del nombre, ya que es el parámetro por defecto. La forma de definir los parámetros es la siguiente: <Nombre Parámetro>[IN|ON|IN OUT]<Tipo de Parámetro>[:=Default<valor>]

A modo de ejemplo vamos a realizar un procedimiento que reciba un parámetro de entrada, idproyecto, y un parámetro de salida, pntareas. Este procedimiento recibe el código de un proyecto y devuelve el número de tareas realizadas en dicho proyecto. CREATE OR REPLACE PROCEDURE CONUSLTAR_TAREAS (PIDPROYECTO NUMBER, PNTAREAS OUT NUMBER) IS BEGIN SELECT COUNT(CODTAREA) INTO PNTAREAS FROM PROYECTOS_TAREAS WHERE IDPROYECTO=PIDPROYECTO; END;

A continuación creamos otro procedimiento que recibe el código de proyecto y llama al procedimiento anterior, mostrando el resultado: CREATE OR REPLACE PROCEDURE MOSTRAR_TAREAS (PIDPROYECTO NUMBER) IS PNTAREAS NUMBER; BEGIN CONUSLTAR_TAREAS(PIDPROYECTO, PNTAREAS); DBMS_OUTPUT.PUT_LINE('EL PORYECTO '||PIDPROYECTO||' TIENE '|| PNTAREAS); END;

Para llamar al procedimiento mostrar_tareas, ejecutamos: SQL> EXECUTE MOSTRAR_TAREAS(1);

******ebook converter DEMO Watermarks*******


Ahora vamos a crear otro procedimiento en el que vamos a usar un parámetro de entrada/salida, trata de un procedimiento que recibe el código del proyecto y la cantidad que queremos sumarle al presupuesto del proyecto correspondiente. El parámetro cantidad es de tipo entrada/salida, puesto que pasamos el parámetro como entrada al procedimiento mod_prespuestos. El procedimiento modifica el parámetro y devuelve el parámetro modificado, salida. Quedaría de la siguiente forma: CREATE OR REPLACE PROCEDURE MOD_PRESUPUESTOS (PCODPROYECTO NUMBER, CANTIDAD IN OUT NUMBER) IS IMPPRES NUMBER(10,2); BEGIN SELECT PRESUPUESTO INTO IMPPRES FROM PROYECTOS_PROYECTOSTIC WHERE CODPROYECTO = PCODPROYECTO; CANTIDAD := CANTIDAD + IMPPRES; END;

Ahora creamos otro procedimiento que realiza una llamada al procedimiento anterior, recibe como parámetro de entrada la cantidad que queremos sumar al presupuesto del proyecto y el código del proyecto. CREATE OR REPLACE PROCEDURE IMPPRES (PCODPROYECTO NUMBER, CANTIDAD NUMBER) IS IMPPRESAX NUMBER(10,2); BEGIN IMPPRESAX:= CANTIDAD; MOD_PRESUPUESTOS(PCODPROYECTO, IMPPRESAX); DBMS_OUTPUT.PUT_LINE('EL PRESPUESTO FINAL PARA EL PROYECTO '||PCODPROYECTO||' ES '||IMPPRESAX); END;

Por último, ejecutamos el procedimiento imppres de la siguiente forma: execute imppres(1, 200);

******ebook converter DEMO Watermarks*******


CONCLUSIÓN En este capítulo hemos hablado sobre los tipos de parámetros y cómo usarlos en los subprogramas que creamos en Oracle, podemos decir que ya podemos crear cualquier tipo de subprograma (procedimiento o función) mediante PL/SQL. Lo que toca a continuación es mucha práctica, una vez se tienen claros los conceptos básicos, no hay otro camino, práctica, práctica y más práctica. En el próximo capitulo vamos a estudiar los paquetes, otro tipo de objeto disponible en la Base de Datos Oracle.

******ebook converter DEMO Watermarks*******


CAPÍTULO 9 PAQUETES Después de hablar en capítulos anteriores, sobre procedimientos y funciones, ahora nos toca hablar sobre otro tipo de objeto, los paquetes. La creación de paquetes, nos proporciona una serie de ventajas interesantes, vamos a estudiarlas.

******ebook converter DEMO Watermarks*******


9.1 PAQUETES EN PL/SQL Un paquete es una agrupación de tipos de datos, variables, constantes, procedimientos y funciones que se han empaquetados juntos. Se agrupan juntos, porque normalmente comparte funcionalidades similares. Todas las funciones y procedimientos que componen el paquete, se registran y almacena en el diccionario de datos como un solo paquete. La ventaja del uso de paquetes respecto al uso de funciones y procedimientos, es que cuando se llama a su contenido desde un subprograma, el paquete se carga en el área de ejecución y permanece aquí. Las funciones y procedimientos se borran del área de ejecución una vez son usados.

******ebook converter DEMO Watermarks*******


9.2 ELEMENTOS QUE COMPONEN UN PAQUETES Un paquete consta de dos partes: Especificación. Es la zona donde declaramos las variables, constantes, excepciones, cursores y subprogramas que definimos en el paquete para ser usados. Cuerpo. Es las zona donde implementamos el código de los subprogramas que definimos en la especificación, también puede contener otro tipo de declaraciones y subprogramas que no hemos definido en la especificación.

******ebook converter DEMO Watermarks*******


9.3 VENTAJAS DEL USO DE PAQUETES El uso de paquete proporciona una de serie de ventajas, destacamos las siguientes: Los paquetes encapsulan los tipos de datos y subprogramas dentro de un módulo, este módulo debe de tener asignado un nombre. Con esto conseguimos modularidad y facilitamos el desarrollo. En el diseño de una aplicación, solo necesitamos de inicio la información de la especificación del paquete. Podemos codificar y compilar la especificación sin necesidad de definir el cuerpo. Esto nos permite hacer referencia al paquete desde otros subprogramas sin necesidad de codificar el cuerpo del paquete, otorgándonos flexibilidad. Al definir un paquete, se puede especificar los tipos de datos y subprogramas para que sean públicos o privados. Los tipos públicos son visibles y accesibles desde fuera del paquete y los tipos privados son ocultos e inaccesibles. En un paquete pueden existir subprogramas (procedimientos y funciones) que serán accesibles y otras rutinas a las cuales no se podrá acceder dese el exterior. Las variables son persistentes en una sesión, sus valores se mantienen en la sesión del usuario que ejecuta el paquete. Las variables contienen el valor de inicialización del paquete, no el valor de asignado por un usuario. Cuando un procedimiento o función de un determinado paquete es llamado por primera vez, el paquete al que pertenece queda almacenado en memoria. Por lo tanto las posteriores llamadas al paquete realizarán un acceso a memoria en lugar de a disco, mejorando el rendimiento. El lenguaje PL/SQL nos permite que procedimientos y funciones de un mismo paquete tengan el mismo nombre, ello nos permite sobrecargar funciones o procedimientos. Esto es útil cuando tengamos la necesidad de definir funciones o procedimientos que acepten diferentes tipos de datos.

******ebook converter DEMO Watermarks*******


9.4 CREACIร N DE PAQUETES La sintaxis para definir un paquete en PL/SQL es la siguiente: CREATE [OR REPLACE] PACKAGE <Nombre Paquete> IS Declaraciones END; CREATE [OR REPLACE] PACKAGE BODY <Nombre Paquete> IS Bloque de Cรณdigo END;

Vamos a ver a continuaciรณn algunos ejemplos de creaciรณn de paquetes.

******ebook converter DEMO Watermarks*******


9.5 EJEMPLOS DE PAQUETES En este punto vamos a crear un ejemplo de paquete que agrupa tres funciones a las cuales les pasamos un dato tipo fecha. Función ANIO, devuelve el año en formato YY de la fecha pasada como parámetro. Función DIA, devuelve el día en formato DD de la fecha pasada como parámetros. Función MES, devuelve el mes en formato MM de la fecha pasada como parámetros. El código del paquete es el mostrado a continuación. En primer lugar creamos la especificación del paquete: CREATE OR REPLACE PACKAGE PKG_FECHAS AS FUNCTION ANIO (FECHA IN DATE) RETURN VARCHAR2; FUNCTION DIA (FECHA IN DATE) RETURN VARCHAR2; FUNCTION MES (FECHA IN DATE) RETURN VARCHAR2; END PKG_FECHAS;

Y a continuación creamos el cuerpo del paquete: CREATE OR REPLACE PACKAGE BODY PKG_FECHAS AS FUNCTION ANIO (FECHA IN DATE) RETURN VARCHAR2 IS ANIO NUMERIC; TMP VARCHAR2(10); BEGIN SELECT EXTRACT(YEAR FROM FECHA) INTO ANIO FROM DUAL; TMP:=TO_CHAR((SUBSTR(ANIO,3,4)));

******ebook converter DEMO Watermarks*******


ANIO:=TO_NUMBER(TMP); RETURN ANIO; END ANIO; FUNCTION DIA (FECHA IN DATE) RETURN VARCHAR2 IS DIA NUMERIC; BEGIN SELECT EXTRACT(DAY FROM FECHA) INTO DIA FROM DUAL; RETURN DIA; END DIA; FUNCTION MES (FECHA IN DATE) RETURN VARCHAR2 IS MES NUMERIC; MESLE VARCHAR2(20); BEGIN SELECT EXTRACT(MONTH FROM TO_DATE(FECHA)) INTO MES FROM DUAL; SELECT TO_CHAR(TO_DATE(TO_CHAR(MES),'MM'),'MONTH','NLS_DATE_LANGUAGE = SPANISH') INTO MESLE FROM DUAL; RETURN MESLE; END MES; END PKG_FECHAS;

Revisa bien este código para que termines de entender la sintaxis de creación de un paquete, no es nada difícil construir un paquete en PL/SQL, pero debemos de tener cuidado con la sintaxis. En el código del ejemplo podemos observar como la sintaxis para escribir el código de las funciones difiere un poco a como lo hacemos para escribir funciones como subprogramas independientes. Para llamar a las funciones del paquete PKG_FECHAS lo hacemos de la siguiente

******ebook converter DEMO Watermarks*******


forma: Llamada a la funciรณn ANIO: BEGIN DBMS_OUTPUT.PUT_LINE(PKG_FECHAS.ANIO('12/12/2016')); END;

Llamada a la funciรณn DIA: BEGIN DBMS_OUTPUT.PUT_LINE(PKG_FECHAS.DIA('12/12/2016')); END;

Llamada a la funciรณn MES: BEGIN DBMS_OUTPUT.PUT_LINE(PKG_FECHAS.MES('12/12/2016')); END;

Vamos a ver otro ejemplo mรกs extenso. Lo primero es crear la tabla roles y usuarios, tablas sobre las que va a trabajar el procedimiento login_usuarios: CREATE TABLE "ROLES" ( "ROL" VARCHAR2(60) NOT NULL ENABLE, CONSTRAINT "ROLES_PK" PRIMARY KEY ("ROL") ENABLE ) / CREATE TABLE "USUARIOS" ( "CODUSUARIO" NUMBER NOT NULL ENABLE, "USUARIO" VARCHAR2(20), "PASSWORD" VARCHAR2(100), "IDROL" VARCHAR2(60),

******ebook converter DEMO Watermarks*******


"FECHA_ALTA" VARCHAR2(100), "ESTADO" VARCHAR2(50), CONSTRAINT "USUARIOS_PK" PRIMARY KEY ("CODUSUARIO") ENABLE ) / ALTER TABLE "USUARIOS" ADD CONSTRAINT "IDROL_FK" FOREIGN KEY ("IDROL") REFERENCES "ROLES" ("ROL") ENABLE /

Añadimos datos a las tablas creadas: DECLARE P VARCHAR2(100) DEFAULT NULL; BEGIN INSERT INTO ROLES (ROL) VALUES ('ADMINISTRADOR'); INSERT INTO ROLES (ROL) VALUES('USUARIO'); P:= LOGIN_USUARIOS.HASH('ADMIN','1234'); INSERT INTO USUARIOS (CODUSUARIO, USUARIO, PASSWORD, IDROL, FECHA_ALTA, ESTADO) VALUES (1,'ADMIN',P,'ADMINISTRADOR','30 DE MARZO DE 2016','DESBLOQUEADO'); P:= LOGIN_USUARIOS.HASH('USUARIO','1234'); INSERT INTO USUARIOS (CODUSUARIO, USUARIO, PASSWORD, IDROL, FECHA_ALTA, ESTADO) VALUES (2,'USUARIO',P,'USUARIO','31 DE MARZO DE 2016','DESBLOQUEADO'); END;

Ahora creamos el paquete login_usuarios, en primer lugar definimos la especificación del paquete: CREATE OR REPLACE PACKAGE "LOGIN_USUARIOS" AS FUNCTION LOGIN(P_USERNAME IN VARCHAR2, P_PASSWORD IN VARCHAR2) RETURN BOOLEAN; FUNCTION HASH(P_USERNAME IN VARCHAR2, P_PASSWORD IN VARCHAR2) RETURN VARCHAR2; END LOGIN_USUARIOS;

******ebook converter DEMO Watermarks*******


Definida la especificaciรณn, creamos el cuerpo del paquete: CREATE OR REPLACE PACKAGE BODY "LOGIN_USUARIOS" AS FUNCTION LOGIN( P_USERNAME IN VARCHAR2, P_PASSWORD IN VARCHAR2) RETURN BOOLEAN IS L_PASSWORD

VARCHAR2 (4000);

L_STORED_PASSWORD VARCHAR2 (4000); L_COUNT

NUMBER;

BEGIN SELECT COUNT ( * ) INTO L_COUNT FROM USUARIOS WHERE USUARIO = P_USERNAME AND ESTADO = 'DESBLOQUEADO'; IF L_COUNT

> 0 THEN

SELECT PASSWORD INTO L_STORED_PASSWORD FROM USUARIOS WHERE USUARIO = P_USERNAME; L_PASSWORD

:= HASH (P_USERNAME, P_PASSWORD);

IF L_PASSWORD = L_STORED_PASSWORD THEN RETURN TRUE; ELSE RETURN FALSE; END IF;

******ebook converter DEMO Watermarks*******


ELSE RETURN FALSE; END IF; END; FUNCTION HASH( P_USERNAME IN VARCHAR2, P_PASSWORD IN VARCHAR2) RETURN VARCHAR2 IS L_PASSWORD VARCHAR2(4000); L_SALT

VARCHAR2(4000) := '3E0PWPJ2Z2KA3IZEB8D3Q6RFO8SMS8';

BEGIN L_PASSWORD := UTL_RAW.CAST_TO_RAW(DBMS_OBFUSCATION_TOOLKIT.MD5 (INPUT_STRING => P_PASSWORD || SUBSTR(L_SALT,10,13) || P_USERNAME || SUBSTR(L_SALT, 4,10))); RETURN L_PASSWORD; END; END LOGIN_USUARIOS;

En este paquete, hemos creado dos funciones. Por un lado tenemos la función login que recibe dos parámetros (nombre de usuario y contraseña) y valida esos datos, es decir, comprueba si esos datos existen en la tabla usuarios, y retorna un valor TRUE o FALSE en función del resultado de la comprobación. Por otro lado tenemos la función hash, que recibe los mismos parámetros que la función login y a partir de estos valores, genera y devuelve una clave encriptida.

******ebook converter DEMO Watermarks*******


CONCLUSIÓN Llegamos al final del capítulo 9, en los diferentes puntos del capítulo, hemos definido los paquetes y la sintaxis para su creación, también hemos hablado sobre las ventajas que presentan los paquetes frente a las funciones y procedimientos que se crean de forma independiente. Seguramente habrá situaciones en las que interese crear paquetes y otras en las que no, te toca a ti decidir. Lo que sí espero, es que el tema de creación de paquetes en PL/SQL quede claro. Continuamos, en el siguiente capítulo nos toca hablar sobre disparadores.

******ebook converter DEMO Watermarks*******


CAPĂ?TULO 10 DISPARADORES Estudiamos ahora otro tipo de objeto disponible para la Base de Datos Oracle, al cual le podemos sacar mucho partido, hablamos de los disparadores o triggers.

******ebook converter DEMO Watermarks*******


10.1 DISPARADORES EN PL/SQL Los disparadores (Triggers) son objetos almacenados en la Base de Datos Oracle que se ejecutan o disparan en el momento en el que se produce un determinado evento. El disparador se puede definir para que se ejecute o dispare al ejecutarse sobre una tabla una sentencia DML, SELECT, DELETE y UPDATE. La funciรณn del disparador es la de realizar operaciones en paralelo a las acciones que se realizan sobre una determinada tabla. Hay varios tipos de disparadores, para sentencias DML de tablas o vistas y para eventos de la propia Base de Datos y esquemas (System Triggers).

******ebook converter DEMO Watermarks*******


10.2 PARTES DE UN DISPARADORES Un disparador se compone de las siguientes partes: Nombre del Disparador (Trigger) Definición de las sentencias que provoca el disparo, INSERT, DELETE Y UPDATE. Especificaremos alguna de estas sentencias y el momento en que se disparará. Especificación de la Tabla, ON. La cláusula ON se escribe a continuación de la tabla asociada. Condición, WHEN. No es obligatoria, permite especificar la condición que se debe dar para que el disparador se ejecute. Solo se puede añadir a los disparadores de fila. Acción. Es el código PL/SQL que se ejecuta cuando el trigger es disparado.

******ebook converter DEMO Watermarks*******


10.3 TIPOS DE DISPARADORES Al hablar de tipos de disparadores, podemos distinguir: Disparadores de Sentencia. Son aquellos disparadores que se disparan una sola vez, sin tener en cuenta la filas afectadas por la sentencia que provoca el disparo del trigger. Para este tipo de trigger no se incluye FOR EACH ROW ni WHEN a la hora de crear el trigger. Disparadores de Fila. Son los disparadores que se disparan varias veces como filas afectadas por la sentencia que provoca el disparo. Para este tipo de disparador debemos indicar la clรกusula FOR EACH ROW, que indica que es un disparador de fila y la clรกusula WHEN, que es opcional en la definiciรณn del trigger.

******ebook converter DEMO Watermarks*******


10.4 CREACIÓN DE DISPARADORES La sintaxis para crear un disparador es la siguiente: CREATE [OR REPLACE] TRIGGER <Nombre Trigger> [BEFORE|AFTER] [DELETE|INSERT|UPDATE {OF columnas}] [OR [DELETE|INSERT|UPDATE {OF columnas}]] [OR ...] ON <Nombre Objeto> [FOR EACH ROW [WHEN <Expresión>] [DECLARE] <Variables> BEGIN <Instrucciones de ejecución> [EXCEPTION] <Instrucciones de excepción> END;

Anotaciones sobre la sintaxis de creación de un trigger que debemos conocer: BEFORE. Define el disparador para que se ejecute antes que la acción. AFTER. Define el disparador para que se ejecuta después de la acción. FOR EACH ROW. Indica que el trigger se dispara por cada fila afectada por la transacción. WHEN. Indica la condición que deben cumplir las filas para que el disparador actúe sobre dichas filas Vamos a crear un ejemplo de Trigger, antes de escribir el código para el Trigger vamos a crear una secuencia que nos va a servir para este ejemplo. En Oracle una secuencia nos proporciona una lista de números consecutivos que nos sirve por ejemplo para simular el tipo de dato autonumérico, disponible en otros tipos de Base de Datos como por ejemplo MYSQL. En Oracle no existe este tipo de dato.

******ebook converter DEMO Watermarks*******


Creamos una secuencia para el campo CODCLIENTES de la tabla proyectos_clientes: CREATE SEQUENCE "PROYECTOS_CLIENTES_SEQ" MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 5 CACHE 20 NOORDER NOCYCLE NOPARTITION

Y a continuación creamos el trigger o disparador: CREATE OR REPLACE TRIGGER "BI_PROYECTOS_CLIENTES" BEFORE INSERT ON "PROYECTOS_CLIENTES" FOR EACH ROW BEGIN IF :NEW."CODCLIENTE" IS NULL THEN SELECT "PROYECTOS_CLIENTES_SEQ".NEXTVAL INTO :NEW."CODCLIENTE" FROM SYS.DUAL; END IF; END;

En este ejemplo vemos como al insertar un nuevo registro en la tabla proyectos_clientes, se dispara el trigger BI_PROYECTOS_CLIENTES (que se dispara antes de la acción de la inserción) y el campo codclientes toma el siguiente valor de la secuencia proyectos_clientes_seq. Con esta combinación de secuencia y trigger, conseguimos similar los campos tipo autonúmerios. Los disparadores pueden trabajar con valores anteriores (:NEW) y valores posteriores (:OLD) de una fila modificada. Pongamos otro ejemplo, el siguiente trigger se dispara cuando se ejecuta una sentencia INSERT sobre la tabla denominada usuarios, asignando un nuevo valor al campo FECHA_ALTA. Este tipo de triggers son muy útiles para controlar en qué fecha y hora se realiza una determinada operación. CREATE OR REPLACE TRIGGER "FECHA_ALTA_USUARIO_BI" BEFORE INSERT ON "USUARIOS" FOR EACH ROW BEGIN

******ebook converter DEMO Watermarks*******


SELECT TO_CHAR(SYSDATE,'DD "DE " FMMONTH " DE " YYYY') INTO :NEW."FECHA_ALTA" FROM DUAL; END; ALTER TRIGGER "FECHA_ALTA_USUARIO_BI" ENABLE

Por último añadir que podemos definir disparadores para sentencias DML (INSERT, UPDATE Y DELETE), sentencias DDL que se pueden asignar a eventos del DATABASE o SCHEMA (ALTER, ANALYZE, ASSOCIATE STATISTICS, AUDIT, COMMENT, CREATE, DIASSOCIATE STATICTICS, DROP, GRANT, NOAUDIT, RENAME, REVOKE, TRUCATE Y DDL) disparadores para eventos de Base de Datos.

******ebook converter DEMO Watermarks*******


CONCLUSIÓN Genial, el tema de disparadores o triggers queda visto, con los ejemplos expuestos en el capítulo, has podido comprobar la utilidad que tienen el tipo de objeto trigger. Podemos hacer muchas cosas con los triggers, ahora te toca a ti darles uso y como no, practicar con ello. En el próximo capítulo vamos a hablar un poco sobre cómo se almacenan los objetos en la Base de Datos Oracle.

******ebook converter DEMO Watermarks*******


CAPĂ?TULO 11 ALMACENAMIENTO DE SUBPROGRAMAS Como ya hemos mencionado anteriormente, todos los subprogramas, procedimientos y funciones, creados se almacenan en la Base de Datos Oracle, vamos a hablar un poco esto.

******ebook converter DEMO Watermarks*******


11.1 ALMACENAMIENTO DE SUBPROGRAMAS EN ORACLE Una vez almacenados los subprogramas creados, podemos acceder a ellos. Cuando ejecutamos la orden CREATE PROCEDURE o CREATE FUNCTION, Oracle compila el código fuente. Si durante el proceso de compilación se generan errores, Oracle nos informa del error. En caso de que no se generen errores, se crea el objeto y el subprograma creado queda almacenado en el diccionario de datos. Todos los subprogramas creados, se añaden a la tabla USER_OBJETCS, esta tabla contiene información sobre los diferentes tipos de objetos almacenados en la Base de Datos, tablas, procedimientos, funciones, disparadores, paquetes, etc. Podemos consultar la tabla USER_OBJETCS escribiendo la siguiente consulta como administrador (SYS) de la Base de Datos: SELECT * FROM USER_OBJETCS;

De la tabla USER_OBJETCS, los campos más interesantes son: OBJECT_NAME, Nombre del objeto. OBJECT_TYPE. Tipo de objeto. Podemos ver los tipos de objetos creados por tipo mediante las consultas: SELECT OBJECT_NAME, OBJECT_TYPE FROM USER_OBJECTS WHERE OBJECT_TYPE = 'PROCEDURE'; SELECT OBJECT_NAME, OBJECT_TYPE FROM USER_OBJECTS WHERE OBJECT_TYPE = 'FUNCTION'; SELECT OBJECT_NAME, OBJECT_TYPE FROM USER_OBJECTS WHERE OBJECT_TYPE = 'TRIGGER'; SELECT OBJECT_NAME, OBJECT_TYPE FROM USER_OBJECTS WHERE OBJECT_TYPE = 'PACKAGE'; …

Disponemos de otro campo interesante que nos proporcionan información sobre el estado del objeto, STATUS. Dicho campo nos indica si el objeto está disponible (VALID) o no disponible (NO VALID). SELECT OBJECT_NAME, OBJECT_TYPE, STATUS FROM USER_OBJECTS;

Podemos también acceder al código fuente de un determinado objeto mediante la vista USER_SOURCE.

******ebook converter DEMO Watermarks*******


La vista USER_SOURCE contiene los siguientes campos: NAME. Nombre del objeto. TYPE. Tipo de objeto. LINE. Número de líneas del código fuente del objeto. TEXT. Contiene el código fuente de cada línea (campo LINE) del objeto. Para visualizar el código de la función MAXCOD escribimos: SELECT LINE,TEXT FROM USER_SOURCE WHERE NAME='MAXCOD';

******ebook converter DEMO Watermarks*******


11.2 COMPILAR OBJETOS DESDE PL/SQL Desde PL/SQL podemos compilar un objeto mediante la siguiente orden: ALTER <Tipo de Objeto> <Nombre Objeto> COMPILE;

******ebook converter DEMO Watermarks*******


11.3 BORRAR OBJETOS DESDE PL/SQL En caso de que queramos borrar un determinado objeto, lo hacemos con la orden: DROP <Tipo de Objeto> <Nombre Objeto>;

******ebook converter DEMO Watermarks*******


CONCLUSIÓN Hemos hablado sobre cómo se almacenan los subprogramas en la Base de Datos Oracle, el contenido del capítulo ha sido un poco a modo de cultura general. He pensado que sería interesante que los lectores de este libro, personas interesadas en aprender PL/SQL, conocieran donde se almacenan los objetos creados y como obtener información sobre dichos objetos. En los siguientes capítulos vamos a entrar en materia algo más avanzada.

******ebook converter DEMO Watermarks*******


CAPÍTULO 12 CURSORES En los programas que hemos creado en capítulos anteriores, las consultas SQL incluidas en el código PL/SQL han devuelto una sola fila. Esto es debido a que hemos estado usando cursores de tipo implícito, este tipo de cursores solo permiten operar sobre una sola fila. Si una consulta de las escritas en los capítulos anteriores, devolviera más de una fila y usáramos la cláusula SELECT INTO para almacenar el resultado devuelto, se generaría una excepción de Oracle. Trabajar con consultas que devuelven varías filas es algo muy necesario, para ello existen los denominados cursores explícitos. En este capítulo, vamos a estudiar este tipo de cursores.

******ebook converter DEMO Watermarks*******


12.1 CURSORES EN PL/SQL Para poder usar un cursor explícito, debemos declararlo. Al igual que las variables, un cursor se declara en la sección de declaraciones de la siguiente forma: CURSOR <Nombre Cursor> IS <Sentencia_Select>;

Para usar un cursor, lo primero que debemos hacer es abrirlo mediante la siguiente instrucción: OPEN <Nombre Cursor>;

Cuando abrimos el cursor, la sentencia SELECT se ejecuta y se almacena en memoria el resultado devuelto por la consulta. Una vez almacenados los datos devueltos, el siguiente paso es acceder a esa información almacenada. Para ello, usamos la siguiente instrucción: FETCH <Nombre_Cursor> INTO <Variables>;

Podemos definir una o varias variables separadas por coma. Otra opción es definir una única variable que almacene el resultado por cada atributo mediante %ROWTYPE de la siguiente forma: <Variable><Nombre _ursor>%ROWTYPE;

La instrucción FETCH recupera las filas de datos devueltas por la consulta, recupera una fila y pasa de forma automática a la siguiente fila. Los datos se almacenan en variables o campos que corresponden a las columnas seleccionadas por la consulta. Una vez el cursor ha realizado su función, debemos cerrarlo con la instrucción CLOSE: CLOSE <Nombre_Cursor>;

******ebook converter DEMO Watermarks*******


12.2 ATRIBUTOS DE UN CURSOR Un Cursor tiene una serie de atributos que nos informan de su estado, para consultar un atributo se emplea la siguiente sintaxis: <Nombre_Cursor>%<Atributo>;

Los atributos que podemos aplicar al uso de cursores son: %FOUND. Devuelve verdadero (TRUE) si la última instrucción SELECT devuelve una fila y devuelve falso (False) en caso que no devuelva ninguna fila. %NOTFOUND. Tiene un funcionamiento inverso a %FOUND, es decir, devuelve FALSE si la instrucción ejecutada devuelve una fila y TRUE en caso contrario. %ROWCOUNT. Devuelve el número de filas afectadas por una sentencia DML (INSERT, UPDATE O DELETE) o el número de filas devueltas por una sentencia SELECT. %ISOPEN. Devuelve verdadero (TRUE) si el cursor está abierto y falso (FALSE) si el cursor está cerrado. Vamos a ver a continuación un ejemplo de uso de cursor. DECLARE CURSOR C IS SELECT NOMBRE, APELLIDO1, APELLIDO2 FROM PROYECTOS_EMPLEADOS; VNOMBRE PROYECTOS_EMPLEADOS.NOMBRE%TYPE; VAPELLIDO1 PROYECTOS_EMPLEADOS.APELLIDO1%TYPE; VAPELLIDO2 PROYECTOS_EMPLEADOS.APELLIDO2%TYPE; BEGIN OPEN C; FETCH C INTO VNOMBRE, VAPELLIDO1, VAPELLIDO2; WHILE C%FOUND LOOP DBMS_OUTPUT.PUT_LINE(C%ROWCOUNT||' '||VNOMBRE||' '||VAPELLIDO1||' '||VAPELLIDO2); FETCH C INTO VNOMBRE, VAPELLIDO1, VAPELLIDO2;

******ebook converter DEMO Watermarks*******


END LOOP; CLOSE C; END;

En este ejemplo hemos declarado un cursor que nos muestra el nombre y apellidos de los empleados de la tabla proyectos_servicios. El manejo de un cursor mediante la sentencia FETCH implica las siguientes operaciones: Declaraciรณn del cursor Declaraciรณn de variables que almacenan los datos devueltos por la consulta SELECT Apertura del cursor Operaciรณn sobre los datos que devuelve el cursor mediante la sentencia FETCH Cerrar el cursor

******ebook converter DEMO Watermarks*******


12.3 VARIABLES DE ACOPLAMIENTO Son variables que usamos cuando no es posible indicar en la sentencia SELECT asociada en la declaración del cursor los términos exactos de la sentencia. Para usar una variable de acoplamiento, debemos declararla al igual que cualquier otro tipo de variable. Pongamos un ejemplo para aclarar este concepto. Vamos a declarar un bloque anónimo que contiene un cursor, dicho cursor tiene asociado una sentencia SELECT que a su vez contiene una variable de acoplamiento, COD, a la cual le asignamos un valor en la sección de declaración. DECLARE VDESCRIPCION PROYECTOS_TAREAS.DESCRIPCION%TYPE; VHORAS_TAREA PROYECTOS_TAREAS.HORAS_TAREA%TYPE; COD NUMBER(10,0) := 5; CURSOR C IS SELECT DESCRIPCION, HORAS_TAREA FROM PROYECTOS_TAREAS WHERE IDPROYECTO = COD; BEGIN OPEN C; FETCH C INTO VDESCRIPCION, VHORAS_TAREA; WHILE C%FOUND LOOP DBMS_OUTPUT.PUT_LINE(C%ROWCOUNT||' '||VDESCRIPCION||' '||VHORAS_TAREA); FETCH C INTO VDESCRIPCION, VHORAS_TAREA; END LOOP; CLOSE C; END;

También tenemos la opción de definir variables de acoplamiento dentro de un procedimiento o función, y pasar a estos subprogramas parámetros que realizarán funciones de variables de acoplamiento. Si lo aplicamos al ejemplo anterior, nos quedaría un procedimiento como el siguiente:

******ebook converter DEMO Watermarks*******


CREATE OR REPLACE PROCEDURE TAREAS(COD NUMBER) AS CURSOR C IS SELECT DESCRIPCION, HORAS_TAREA FROM PROYECTOS_TAREAS WHERE IDPROYECTO = COD; VDESCRIPCION PROYECTOS_TAREAS.DESCRIPCION%TYPE; VHORAS_TAREA PROYECTOS_TAREAS.HORAS_TAREA%TYPE; BEGIN OPEN C; FETCH C INTO VDESCRIPCION, VHORAS_TAREA; WHILE C%FOUND LOOP DBMS_OUTPUT.PUT_LINE(C%ROWCOUNT||' '||VDESCRIPCION||' '||VHORAS_TAREA); FETCH C INTO VDESCRIPCION, VHORAS_TAREA; END LOOP; CLOSE C; END;

Para llamar a este procedimiento, escribimos: BEGIN TAREAS(5); END;

******ebook converter DEMO Watermarks*******


12.4 MANEJO DE CURSORES CON FOR… LOOP Mediante la sentencia FOR… LOOP podemos realizar las operaciones de manera implícita, sin obviar la declaración de un cursor. El uso de esta estructura requiere: Declarar el cursor Procesar el cursor mediante la instrucción: FOR <Variable> IN <Cursor> LOOP Intrucciones; END LOOP;

Variable es un tipo registro que definimos de forma implícita: CURSOR%ROWTYPE;

El manejo de cursores mediante la instrucción FOR… LOOP implica las siguientes operaciones: Apertura del cursor Declaración de la variable tipo %ROWTYPE Ejecución de la primera instrucción FETCH para recuperar la primera fila y almacenar el resultado en la variable tipo %ROWTYPE Se ejecutan las instrucciones del bucle FOR… LOOP Ejecución de otra instrucción FETCH almacenando de nuevo el resultado en la variable tipo %ROWTYPE. Si el cursor no posee más filas, finaliza el bucle FOR… LOOP. En caso de que el cursor posea más filas, volvemos al paso anterior. Vamos a ver el ejemplo del punto 12.2 adaptado a la instrucción FOR… EN LOOP: DECLARE

******ebook converter DEMO Watermarks*******


CURSOR C IS SELECT NOMBRE, APELLIDO1, APELLIDO2 FROM PROYECTOS_EMPLEADOS; BEGIN FOR F IN C LOOP DBMS_OUTPUT.PUT_LINE(F.NOMBRE||' '||F.APELLIDO1||' '||F.APELLIDO2); END LOOP; END;

Podemos ver como el uso de FOR… LOOP es mucho más simple que el uso de FETCH.

******ebook converter DEMO Watermarks*******


12.5 USO DE ALIAS EN LA DEFINICIÓN DE CURSORES Podemos encontrarnos con la necesidad de tener que declarar una expresión dentro de la consulta SELECT asociada al cursor, como por ejemplo la siguiente consulta: SELECT IDPROYECTO AS "Código de Proyecto", COUNT(CODTAREA) AS "Número de Tareas" FROM PROYECTOS_TAREAS GROUP BY IDPROYECTO;

En estos casos, debemos asignar un alias a la expresión declarada en la sentencia SELECT para poder hacer referencia a dicha expresión en las operaciones que realizaremos mediante el cursor. La consulta anterior la asignamos a un cursor y nos quedaría un bloque anónimo como el siguiente: DECLARE CURSOR C IS SELECT IDPROYECTO, COUNT(CODTAREA) N_TAREAS FROM PROYECTOS_TAREAS GROUP BY IDPROYECTO; BEGIN FOR F IN C LOOP DBMS_OUTPUT.PUT_LINE(F.IDPROYECTO||' '||F.N_TAREAS); END LOOP; END;

Vemos como para hacer referencia a la expresión COUNT(CODTAREA) lo hacemos mediante el alias definido, N_TAREAS.

******ebook converter DEMO Watermarks*******


12.6 CURSORES PARA ACTUALIZACIÓN DE FILAS Podemos usar también un cursor para realizar operaciones de actualización de datos, para este tipo de operaciones disponemos de los cursores FOR UPDATE. Para declarar un cursor de este tipo, usamos la siguiente sintaxis: CURSOR <Nombre_Cursor> IS <Sentencia_Select> FOR UPDATE;

El uso de este tipo de cursores en idéntico al visto hasta ahora, con la diferencia de que debemos indicar la cláusula WHERE CURRENT OF <Nombre del cursor> al final de la sentencia UPDATE. Un ejemplo para este tipo de cursor sería el siguiente: CREATE OR REPLACE PROCEDURE ACTUALIZAR_PRESUPUESTO IS CURSOR C IS SELECT PRESUPUESTO FROM PROYECTOS_PROYECTOSTIC FOR UPDATE; P C%ROWTYPE; BEGIN FOR P IN C LOOP IF P.PRESUPUESTO > 2500 THEN UPDATE PROYECTOS_PROYECTOSTIC SET PRESUPUESTO=PRESUPUESTO-100 WHERE CURRENT OF C; END IF; END LOOP; END;

******ebook converter DEMO Watermarks*******


12.7 CURSORES PARA BORRADO DE FILAS Siguiendo el mismo procedimiento que hemos explicado en el punto anterior, podemos usar un cursor tipo FOR UPDATE para realizar operaciones de borrado de datos. Vamos a definir a continuaciรณn un procedimiento que realiza una operaciรณn de borrado sobre la tabla proyectos_tareas: CREATE OR REPLACE PROCEDURE BORRAR_TAREAS IS CURSOR C IS SELECT FECHA_INICIO FROM PROYECTOS_TAREAS FOR UPDATE; P C%ROWTYPE; BEGIN FOR P IN C LOOP IF P.FECHA_INICIO = '12/12/2015 THEN DELETE PROYECTOS_TAREAS WHERE CURRENT OF C; END IF; END LOOP; END;

******ebook converter DEMO Watermarks*******


CONCLUSIÓN Con este capítulo hemos entrado en conceptos más avanzados del lenguaje PL/SQL, hemos definido los cursores y cómo podemos usarlos en nuestros programas. Los cursores son unos grandes aliados a la hora de realizar operaciones complejas sobre nuestra Base de Datos. En los siguientes capítulos continuaremos profundizando en aspectos avanzados de PL/SQL, pero antes vamos a tratar el tema de las excepciones.

******ebook converter DEMO Watermarks*******


CAPÍTULO 13 GESTIÓN DE EXCEPCIONES Las excepciones son una serie de técnicas que se usan en programación para controlar los errores que se producen durante la ejecución de un programa. Como todos los lenguajes de programación, PL/SQL nos proporciona características para controlar estas excepciones. Si no definimos un bloque de excepciones que controla las situaciones que puedan producir errores en la ejecución de un programa, es Oracle quién generará el mensaje de error. Una excepción no controlada en un programa crea una sensación de poca profesionalidad sobre el programador. Por ello, antes de poner un programa en producción, es necesario someterlo a un proceso de validación. Vamos a ver a continuación como gestionamos el tema de las excepciones en la Base de Datos Oracle.

******ebook converter DEMO Watermarks*******


13.1 EXCEPCIONES EN PL/SQL En el lenguaje PL/SQL, una excepción se considera como cualquier error que se pueda generar en la ejecución de un programa. Podemos capturar este tipo de situación para modificar el comportamiento en el momento en que se produce la excepción. Las excepciones pueden ser errores de ejecución u otro tipo de sucesos. Como ya hemos comentado anteriormente, dentro de un bloque anónimo, función o procedimiento existe lo que denominamos la sección de excepciones. La sección de excepciones tiene el siguiente formato: EXCEPTION WHEN <EXCEPTION_1> THEN Intrucciones; WHEN <EXCEPTION_2> THEN Intrucciones; [WHEN OTHERS THEN Intrucciones;] END;

Durante la ejecución de un programa PL/SQL, cuando se produce una excepción, el control es pasado a la sección de excepciones. Por cada una de las sentencias WHEN definidas, se comprueba si la excepción generada coincide con alguna. Si hay coincidencia, se ejecutarán las instrucciones correspondientes y finaliza el bloque. Si la excepción generada no coincide con las definidas, se ejecutarán las instrucciones correspondientes al bloque WHEN OTHERS.

******ebook converter DEMO Watermarks*******


13.2 EXCEPCIONES PREDEFINIDAS EN ORACLE En Oracle, existen excepciones predefinidas que se generan al producirse determinados errores durante la ejecución de un programa. Cuando se produce una excepción del tipo predefinidas, Oracle devuelve un código de error tipo ORA-… Vamos a ver a continuación una tabla con los tipos de errores más comunes.

Este tipo de excepciones no necesitan ser declaradas, solo debemos hacer referencias a ellas en la sección de excepciones a continuación de la palabra WHEN. Veamos un ejemplo a continuación: CREATE OR REPLACE PROCEDURE NOMBRE_SERVICIO (COD VARCHAR2) IS VNOMBRE PROYECTOS_SERVICIOS.NOMBRE%TYPE; BEGIN SELECT NOMBRE INTO VNOMBRE FROM PROYECTOS_SERVICIOS WHERE CODSERVICIO = COD; DBMS_OUTPUT.PUT_LINE(VNOMBRE); EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE('ERROR, NO HAY DATOS SELECCIONADOS');

******ebook converter DEMO Watermarks*******


WHEN TOO_MANY_ROWS THEN DBMS_OUTPUT.PUT_LINE('ERROR, Mร S DE UNA FILA SELECCIONADA'); WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('ERROR'); END;

Para generar una de las excepciones definidas en la secciรณn de excepciones escribimos por ejemplo: BEGIN NOMBRE_SERVICIO(' '); END;

******ebook converter DEMO Watermarks*******


13.3 EXCEPCIONES DEFINIDAS POR USUARIOS Un usuario puede considerar determinados errores que se producen en la ejecución de un programa como excepciones. Para definir una excepción personalizada debemos: Declarar la excepción en la sección de declaraciones. <Nombre Excepción> EXCEPTION;

Generar la excepción dentro del código PL/SQL mediante la instrucción: RAISE <Nombre Excepción>;

Tratar la incidencia en la sección EXCEPTION: WHEN <Nombre Excepción> THEN <Instrucciones>;

En el siguiente ejemplo mostramos una serie de excepciones definidas para tratar valores igual a 0 y valores menores a 0: CREATE OR REPLACE PROCEDURE COMPROBAR_PRESUPUESTO (CODIGO NUMBER) IS VPRE PROYECTOS_PROYECTOSTIC.PRESUPUESTO%TYPE; PRESUPUESTO_NULO EXCEPTION; PRESUPUESTO_NEGATIVO EXCEPTION; BEGIN SELECT PRESUPUESTO INTO VPRE FROM PROYECTOS_PROYECTOSTIC WHERE CODPROYECTO = CODIGO; IF VPRE = 0 THEN RAISE PRESUPUESTO_NULO; ELSIF VPRE < 0 THEN RAISE PRESUPUESTO_NEGATIVO; END IF;

******ebook converter DEMO Watermarks*******


DBMS_OUTPUT.PUT_LINE(VPRE); EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE('NO HAY DATOS'); WHEN PRESUPUESTO_NULO THEN DBMS_OUTPUT.PUT_LINE('EL PRESUPUESTO ES 0'); WHEN PRESUPUESTO_NEGATIVO THEN DBMS_OUTPUT.PUT_LINE('EL PRESUPUESTO ES NEGATIVO'); END;

******ebook converter DEMO Watermarks*******


CONCLUSIÓN En este capítulo, hemos tratado y definido un tema que quedaba pendiente desde que comenzamos a hablar de subprogramas. En los ejemplos tratados en los capítulos anteriores, no hemos considerado la generación de excepciones. Con lo visto en el capítulo 13, ya estamos en condiciones de escribir programas en PL/SQL que realicen todo tipo de operaciones y controlen las diferentes situaciones que pueden generas errores. Recuerda lo que hemos comentado en la introducción del capítulo, no es muy agradable ver una excepción no controlada en un programa.

******ebook converter DEMO Watermarks*******


CAPÍTULO 14 TIPOS DE DATOS COMPUESTOS Nos toca ya hablar sobre temas avanzados del lenguaje PL/SQL. El uso de los tipos de datos compuestos, registros y colecciones, requiere ya de un cierto conocimiento de PL/SQL. Así que no nos extendemos más en la introducción del capítulo y comenzados a trabajar en la materia, hay mucho de qué hablar.

******ebook converter DEMO Watermarks*******


14.1 REGISTROS Un registro es una agrupación de campos, cada uno de estos campos posee su tipo y nombre. Mediante el atributo %ROWTYPE podemos crear un registro que representará una fila de una tabla concreta de una Base de Datos. El atributo%ROWTYPE toma los tipos de datos de la tabla. Existe un tipo de dato denominado RECORD que crea un registro con tipos de datos para cada uno de los campos. Para declarar el tipo RECORD usamos la siguiente sintaxis: TYPE <Nombre_Tipo> IS RECORD (<Declaración_Campo> [,<Declaración_Campo>]...);

Dónde Declaración_Campo es: <Nombre_Campo> <Tipo_Dato> [[NOT NULL] {:= | DEFAULT} Expresión]

Podemos usar %TYPE y %ROWTYPE para especificar el tipo de dato de los campos definidos en un registro. El único tipo no permitido es REF CURSOR. A continuación un ejemplo de registro: DECLARE TYPE coche IS RECORD ( marca varchar2(100), color varchar2(80), modelo varchar2(80)); ...

En la sección declare podemos realizar las asignaciones o declaraciones de valores en los registros. Para hacer referencia a un campo dentro de un registro usamos la notación: registro.campo

******ebook converter DEMO Watermarks*******


Para llamar a una función que devuelve un tipo RECORD, en la definición de la función debemos indicar que devuelve un tipo de dato RECORD. La notación usada es la siguiente: Nombre_Función Nombre_parámetros.Nombre_Campo

Podemos definir nuestros propios tipos de registros con sus tipos de datos, independientes, asociados a tablas u a otros registros. Un ejemplo de registro sería el siguiente: DECLARE TYPE REMPLEADO IS RECORD ( NOMBRE VARCHAR2(20) NOT NULL, APELLIDO1 VARCHAR2(20), APELLIDO2 VARCHAR2(20), EDAD NUMBER, SEXO CHAR(5) ); VEMPLEADO REMPLEADO; BEGIN VEMPLEADO.NOMBRE:='PEPE' VEMPLEADO.APELLIDO1:='PEREZ' VEMPLEADO.APELLIDO2:='CASTRO' VEMPELADO.EDAD:='28' VEMPLEADO.SEXO:='V'; ... END;

Como hemos comentado anteriormente, podemos declarar un registro basándonos en una colección de columnas de una tabla, vista o incluso un cursor, para ello usamos el atributo %ROWTYPE.

******ebook converter DEMO Watermarks*******


Un ejemplo de esto último sería el siguiente: DECLARE RDEPARTAMENTOS PROYECTOS_DEPARTAMENTOS%ROWTYPE; BEGIN RDEPARTAMENTOS.CODDEPARTAMENTO := '020'; RDEPARTAMENTOS.NOMBRE := 'PRUEBA'; RDEPARTAMENTOS.DESCRIPCION := 'ESTO ES UNA DESCRIPCIÓN'; INSERT INTO PROYECTOS_DEPARTAMENTOS VALUES RDEPARTAMENTOS; UPDATE PROYECTOS_DEPARTAMENTOS SET ROW = RDEPARTAMENTOS WHERE CODDEPARTAMENTO = '002SIS'; END;

Algunos puntos que debemos de tener en cuenta: ROW debe aparecer en la parte izquierda en la asignación de SET. ROW no está permitido en subconsultas. Si usamos una variable tipo RECORD en una sentencia SELECT, en la cláusula VALUES solo puede aparecer la variable tipo RECORD. Solo puede aparecer una cláusula SET en una sentencia UPDATE si se utiliza ROW.

******ebook converter DEMO Watermarks*******


14.2 COLECCIONES Una colección es un grupo de elementos que tienen un mismo tipo, cada elemento dispone de un subindice único que determina la posición del elemento en la colección. El lenguaje PL/SQL ofrece dos tipos de colecciones, son: TABLE. Son tablas anidadas o tablas indexadas que tienen un tamaño variable. La diferencia principal entre una tabla anidada y una tabla indexada es que una tabla anidada puede almacenar columnas de una Base de Datos y la tabla indexada no puede. En las tablas anidadas almacenadas en la Base de Datos podemos aplicar las sentencias SELECT, DELETE, UPDATE e INSERT, pero no sobre las tablas indexadas. Las tablas anidadas permiten también inicializar a NULL y nos permiten aplicar la condición IS NULL, cosa que no podemos en las tablas indexadas. VARRAY. Es un ARRAY tradicional de los lenguajes de programación, asigna un índice consecutivo por cada elemento y hay que definir el tamaño en la declaración, es decir, tienen un tamaño fijo. Las principales diferencias entre una tabla anidada y un VARRAY son: VARRAY tiene tamaño máximo, no permite borrar un elemento individual y mantiene el orden cuando se almacenan en la Base de Datos. Tabla anidada no tiene tamaño máximo, permite borrar un elemento individual y no mantienen el orden al almacenarse en la Base de Datos. Vamos a hablar a continuación de los diferentes tipos de colecciones que tenemos disponibles en PL/SQL. 14.2.1 TABLAS INDEXADAS A la hora de trabajar con tablas indexadas, debemos de tener en cuenta: Una tabla anidada nos permite localizar elementos mediante el uso de número o

******ebook converter DEMO Watermarks*******


cadenas aleatorias. Cualquier valor o índice nuevo creará un elemento nuevo en la tabla. Si se usa un valor que existe en la tabla, se actualizará el valor al que apunta dicho índice o valor. Debemos usar valores únicos, ya que la tabla está indexada por dicho valor. Las sentencias INSERT y SELECT INTO no pueden ser usadas. Si usamos cadenas de caracteres al indexar una tabla, se generará un error en los métodos NEXT o PRIOR si se cambian los parámetros del grupo de caracteres en la sesión donde la tabla indexada está definida. La sintaxis de definición para una tabla indexada es la siguiente: TYPE <Nombre_Colección> IS TABLE OF <Tipo_Elmento> [NOT NULL] INDEX BY [BINARY_INTEGER | PLS_INTEGER | VARCHAR2]; INDEX BY <Tipo_Dato_Indice>;

El tipo de dato índice puede ser tipo número o tipo varchar, en caso de varchar debemos especificar la longitud. No están permitidos los tipos RAW, LONG RAW, ROWID, CHAR, y CHARACTER. Vamos a ver a continuación un ejemplo de tabla indexada: DECLARE TYPE CIUDADES IS TABLE OF VARCHAR2(50) INDEX BY BINARY_INTEGER; CIUDADES_VISITADES CIUDADES; BEGIN CIUDADES_VISITADES(1) := 'PARIS'; CIUDADES_VISITADES(2) := 'MADRID'; CIUDADES_VISITADES(3) := 'LISBOA'; FOR I IN CIUDADES_VISITADES.FIRST.. CIUDADES_VISITADES.LAST LOOP

******ebook converter DEMO Watermarks*******


DBMS_OUTPUT.PUT_LINE( CIUDADES_VISITADES(I)); END LOOP; END;

14.2.2 TABLAS ANIDADAS La Base de Datos Oracle almacena las tablas anidadas sin ningún orden. Cuando queremos recuperar los elementos de una tabla anidada, accedemos a dichos elementos de la tabla mediante un índice. Podemos pensar en una tabla anidada como una tabla de una sola columna. En general las tablas anidadas tienen una sola dimensión, pero podemos crear tablas anidadas de varias dimensiones anidando varias tablas. Una tabla anidada es similar a una tabla normal, pero existen algunas diferencias como: Las tablas anidadas no tiene límite superior, una tabla normal si lo tiene. En las tablas anidadas podemos borrar elementos y estos elementos, pueden no quedar de forma consecutiva. En las tablas normales todos los elementos son consecutivos. La sintaxis de definición para una tabla anidada es la siguiente: TYPE <Nombre_Colección> IS TABLE OF <Tipo_Elemento> [NOT NULL];

En las tablas anidadas que definimos en PL/SQL, Tipo_Elemento puede ser de cualquier tipo a excepción de REF CURSOR. A continuación vamos a ver un ejemplo de tabla anidada: DECLARE TYPE TNOMBRES IS TABLE OF VARCHAR2(10); TYPE TNOTAS IS TABLE OF INTEGER; NOMBRES TNOMBRES; NOTAS TNOTAS; TOTAL INTEGER;

******ebook converter DEMO Watermarks*******


BEGIN NOMBRES := TNOMBRES('JUAN', 'ANTONIO', 'ANA', 'MARÍA', 'JESÚS','EVA'); NOTAS:= TNOTAS(9, 7, 8, 6, 5, 6); TOTAL := NOMBRES.COUNT; DBMS_OUTPUT.PUT_LINE('NÚMERO TOTAL DE ALUMNOS: '|| TOTAL); FOR I IN 1 .. TOTAL LOOP DBMS_OUTPUT.PUT_LINE('ALUMNO:'||NOMBRES(I)||', NOTA: ' || NOTAS(I)); END LOOP; END;

14.2.3 ARRAYS VARIABLES Los arrays variables nos permiten realizar una serie de operaciones que debemos conocer cuando trabajamos con ellos, son: Nos permiten manipular toda la colección de forma simultánea. Podemos asociar a un identificador una serie de elementos. El número de elementos es variable. Desde 0, en el momento de la creación, hasta el máximo, especificado en la definición. La sintaxis de definición es la siguiente: TYPE <Nombre_Colección> IS ARRAY (Tamaño) OF <Tipo_Elemento> [NOT NULL];

Dónde tamaño es el número máximo que puede tener el VARRAY. A continuación mostramos un ejemplo: DECLARE TYPE NOMBRES IS VARRAY(5) OF VARCHAR2(50); V_LISTA NOMBRES:= NOMBRES('JUAN', 'PEDRO', 'VANESA',''); V VARCHAR2(8); TOTAL NUMBER;

******ebook converter DEMO Watermarks*******


BEGIN V_LISTA(4) := 'ANTONIO'; V := V_LISTA(3); DBMS_OUTPUT.PUT_LINE(V); TOTAL := V_LISTA.COUNT; FOR I IN 1 .. TOTAL LOOP DBMS_OUTPUT.PUT_LINE(V_LISTA(I)); END LOOP; END;

14.2.4 OPERACIONES CON COLECCIONES En este punto vamos a estudiar los diferentes tipos de operaciones que podemos realizar con las colecciones. INICIALIZAR COLECCIONES Las tablas anidadas o VARRAY por defecto están vacías hasta que se inicializan, es decir, tienen valor nulo. Para inicializar una tabla anidada o un VARRAY se usa un constructor. Un constructor es una función con el mismo nombre del tipo de colección, que devuelve una nueva instancia del tipo de colección definido y establece los valores de sus atributos. Ejemplo de inicialización de una tabla anidada: DECLARE TYPE ALUMNOS IS TABLE OF VARCHAR2(80); CLASE ALUMNOS; BEGIN CLASE := ALUMNOS ('ANTONIO ROMERO', 'JUAN PÉREZ', 'MARÍA ARROYO'); END;

******ebook converter DEMO Watermarks*******


Ejemplo de inicialización de un VARRAY: DECLARE TYPE NOTAS IS VARRAY(10) OF NUMBER(2); VNOTAS NOTAS; BEGIN VNOTAS := NOTAS (1,2,3,4,5,6,7,8,9,10); END;

En este ejemplo hemos definido una longitud de 10, por lo que no podemos guardar más de 10 elementos. Podemos usar NULL e inicializar también una declaración vacía de la siguiente forma: TYPE ALUMNOS IS TABLE OF VARCHAR2(80); CLASES ALUMNOS:= ALUMNOS();

Y usar la siguiente condición: IF CLASES IS NOT NULL THEN ... END IF;

REFERENCIAR COLECCIONES Podemos referenciar un elemento de una colección usando la siguiente sintaxis: Nombre_Colección(índice);

En el siguiente código vemos un ejemplo de referencia de colección: DECLARE TYPE EQUIPOS IS TABLE OF VARCHAR2(50); EQUIPOS_FUTBOL EQUIPOS:= EQUIPOS('REAL MADRID', 'F.C BARCELONA', 'REAL BETIS', 'VALENCIA', 'ATLÉTICO DE MADRID'); BEGIN FOR V IN EQUIPOS_FUTBOL.FIRST .. EQUIPOS_FUTBOL.LAST LOOP

******ebook converter DEMO Watermarks*******


IF EQUIPOS_FUTBOL(V) = 'VALENCIA' THEN DBMS_OUTPUT.PUT_LINE('EQUIPO NÚMERO: ' || V); END IF; END LOOP; END;

ASIGNACIÓN Y COMPARACIÓN DE COLECCIONES Podemos asignar una colección a otra colección mediante una sentencia DML desde una llamada a un subprograma o una asignación de sentencia. Vamos a ver un ejemplo de asignación: DECLARE TYPE HOMBRE IS VARRAY(3) OF VARCHAR2(80); TYPE MUJER IS VARRAY(3) OF VARCHAR2(80); EQUIPO1 HOMBRE := HOMBRE ('ISAAC','PEPE', 'JUAN'); EQUIPO2 HOMBRE := HOMBRE ('ANTONIO','JOSE','MIGUEL'); EQUIPO3 MUJER:= MUJER('ANA', 'MARIA', 'EVA'); BEGIN EQUIPO2 := EQUIPO1; END;

Si hacemos la asignación: EQUIPO3 := EQUIPO2;

Se generaría un error, puesto que no son del mismo tipo. ASIGNACIÓN DE ELEMENTOS A UNA COLECCIÓN Podemos también asignar un valor de expresión determinada a un elemento de una colección, para ello usamos la siguiente sintaxis: <Nombre_Colección>(índice):=<expresión>;

Hay tener en cuenta que se pueden generar ciertos errores en caso de que no hagamos la

******ebook converter DEMO Watermarks*******


asignación de forma correcta. Estos errores son: VALUE_ERROR. En caso de que el índice sea nulo o no es un índice del tipo correcto. SUBSCRIPT_BEYOND_COUNT. Si el índice apunta a un elemento no inicializado. COLLECTION_IS_NULL. Si la colección es nula. A continuación un ejemplo de asignación de elementos a una colección: DECLARE TYPE LISTA IS TABLE OF INTEGER; N LISTA; BEGIN N := LISTA(100,1000,10000); N(1) := ASCII('B'); N(2) := 5 * N(1); END;

Continuando con el ejemplo, se generarían excepciones con las siguientes líneas de código: N(1) := 9000; --ORA-06531: REFERENCIA A UNA RECOPILACIÓN NO INICIALIZADA N('B') := 30; --ORA-06502: PL/SQL: ERROR : ERROR DE CONVERSIÓN DE CARÁCTER A NÚMERO NUMÉRICO O DE VALOR, VALUE_ERROR N(4) := 40; --ORA-06531: REFERENCIA A UNA RECOPILACIÓN NO INICIALIZADA COMPARACIÓN COMPLETA DE COLECCIONES Cuando estemos trabajando con colecciones, posiblemente nos surja la necesidad de realizar una comparación entre colecciones. Debemos saber que las colecciones no se

******ebook converter DEMO Watermarks*******


pueden comparar de forma global usando la igualdad (=) o desigualdad (<, >, <=, =>, <>, !=). Vamos a verlo sobre un ejemplo: DECLARE TYPE LISTA IS TABLE OF INTEGER; MILISTA1 LISTA := LISTA(...); MILISTA2 LISTA := LISTA(...); BEGIN IF MILISTA1 = MILISTA2 THEN --ESTA LÍNEA PRODUCE UN ERROR DE COMPILACIÓN ... END IF; END;

Esta limitación se produce desde la versión 10g de Oracle. 14.2.5 COLECCIONES MULTINIVEL Además de las colecciones que hemos visto en los puntos anteriores, también podemos crear colecciones cuyos elementos sean otras colecciones. Por ejemplo, podemos crear tablas anidadas de VARRAYS, un VARRAY de VARRAYS, un VARRAYS de tablas anidadas, etc. Vamos a ver a continuación unos ejemplos sobre esto. EJEMPLO DE VARRAY MULTINIVEL DECLARE TYPE T1 IS VARRAY(10) OF INTEGER; TYPE NT1 IS VARRAY(10) OF T1; -- MULTILEVEL VARRAY TYPE VA T1 := T1(2,3,5); -- INITIALIZE MULTILEVEL VARRAY NVA NT1 := NT1(VA, T1(55,6,73), T1(2,4), VA); I INTEGER;

******ebook converter DEMO Watermarks*******


VA1 T1; BEGIN -- MULTILEVEL ACCESS I := NVA(2)(3); -- I WILL GET VALUE 73 DBMS_OUTPUT.PUT_LINE(I); -- ADD A NEW VARRAY ELEMENT TO NVA NVA.EXTEND; NVA(5) := T1(56, 32); -- REPLACE AN INNER VARRAY ELEMENT NVA(4) := T1(45,43,67,43345); -- REPLACE AN INNER INTEGER ELEMENT NVA(4)(4) := 1; -- REPLACES 43345 WITH 1 -- ADD A NEW ELEMENT TO THE 4TH VARRAY ELEMENT -- AND STORE INTEGER 89 INTO IT. NVA(4).EXTEND; NVA(4)(5) := 89; END;

EJEMPLO DE TABLA MULTINIVEL DECLARE TYPE TB1 IS TABLE OF VARCHAR2(20); TYPE NTB1 IS TABLE OF TB1; -- TABLE OF TABLE ELEMENTS TYPE TV1 IS VARRAY(10) OF INTEGER; TYPE NTB2 IS TABLE OF TV1; -- TABLE OF VARRAY ELEMENTS VTB1 TB1 := TB1('ONE', 'THREE'); VNTB1 NTB1 := NTB1(VTB1); VNTB2 NTB2 := NTB2(TV1(3,5), TV1(5,7,3)); -- TABLE OF VARRAY ELEMENTS BEGIN VNTB1.EXTEND;

******ebook converter DEMO Watermarks*******


VNTB1(2) := VNTB1(1); -- DELETE THE FIRST ELEMENT IN VNTB1 VNTB1.DELETE(1); -- DELETE THE FIRST STRING FROM THE SECOND TABLE IN THE NESTED TABLE VNTB1(2).DELETE(1); END;

Ejemplos tomados de la documentación oficial de Oracle https://docs.oracle.com 14.2.6 MÉTODOS PARA COLECCIONES PL/SQL nos proporciona una serie de métodos que nos hacen más fácil el uso de colecciones. Estos métodos son EXIST, LIMIT, COUNT ,FIRST, LAST, PRIOR, NEXT, EXTEND, TRIM Y DELETE. Un método en una colección es una función o procedimiento que opera sobre dicha colección. Para llamar a una colección usamos la siguiente sintaxis: <Nombre_Colección>.<Nombre_Método>[(parámetros)];

Un método de una colección, no pueden ser invocados desde sentencias SQL. Vamos a ver a continuación cada uno de estos métodos: Método EXIST(N). Devuelve TRUE si existe un elemento en la n-ésima posición de la colección, en caso contrario devuelve FALSE. IF C.EXIST(I) THEN C.(I):= VALOR; END IF;

Método COUNT. Devuelve el número de elementos que tiene la colección. IF C.COUNT = 10 THEN ... END IF;

******ebook converter DEMO Watermarks*******


FOR I IN 1.. C.COUNT LOOP ... END LOOP;

Método LIMIT. Para las tablas anidadas y VARRAYS asociativos que no tienen un tamaño máximo, devuelve NULL. Para el caso de VARRAYS, devuelve el número máximo de elementos que puede contener. IF C.LIMIT = 10 THEN ... END IF; IF (C.COUNT + 10) < C.LIMIT THEN ... END IF;

Métodos FIRST y LAST. El método FIRST devuelve el primer índice numérico de una colección y LAST devuelve el último índice. En caso de que la colección este vacía, ambos métodos devuelven NULL. IF C.FIRST = C.LAST THEN DBMS_OUTPUT.PUT_LINE('LA COLECCIÓN TIENE UN SOLO ELEMENTO'); END IF; FOR I IN C.FIRST..C.LAST LOOP ... END LOOP;

Métodos PRIOR(N) y NEXT(N). El método PRIOR devuelve el índice que antecede al índice n de la colección sobre la que estamos trabajando, y el método NEXT devuelve el número índice que sucede al índice n en la colección. I := C.FIRST; WHILE I IS NOT NULL LOOP I := C.NEXT(I); END LOOP;

******ebook converter DEMO Watermarks*******


Método EXTEND. El método EXTEND se usa para incrementar el tamaño de la colección. Este método dispone de tres formas de uso: EXTEND agrega un elemento nulo al final de la colección. EXTEND(N) agrega n nulos a la colección. EXTEND(n,i) agrega n copias del i-ésimo elemento a una colección. DECLARE TYPE EQUIPOS IS TABLE OF VARCHAR2(10); EQUIPOS_FUTBOL EQUIPOS; BEGIN EQUIPOS_FUTBOL := EQUIPOS('VALECIA', 'SEVILLA'); EQUIPOS_FUTBOL.EXTEND; -- AGREGA UN ELEMENTO VACIO AL FINAL EQUIPOS_FUTBOL(EQUIPOS_FUTBOL.LAST):='BETIS'; -- ASIGNA UN VALOR AL ULTIMO LUGAR END;

Método TRIM. Tiene dos formas de uso: TRIN. Elimina un elemento del final de la colección. TRIM(N). Elimina n elementos desde el final de la colección. DECLARE TYPE EQUIPOS IS TABLE OF VARCHAR2(15); EQUIPOS_FUTBOL EQUIPOS; BEGIN EQUIPOS_FUTBOL := EQUIPOS ('SEVILLA', 'VALENCIA', 'REAL MADRID', 'BETIS'); EQUIPOS_FUTBOL.DELETE(EQUIPOS_FUTBOL.LAST); EQUIPOS_FUTBOL.TRIM(EQUIPOS_FUTBOL.COUNT); DBMS_OUTPUT.PUT_LINE(EQUIPOS_FUTBOL(1)); END;

******ebook converter DEMO Watermarks*******


Método DELETE. Dispone de tres formas de uso: DELETE. Elimina todos los elementos de una colección. DELECT(N). Elimina el elemento n de una matriz asociativa con una clave numérica o una tabla anidada. Si el array asociativo tiene una clave de cadena, el elemento correspondiente al valor de la clave se elimina. Si n es nulo, DELETE (n) no hace nada. DELETE (m,n). Elimina todos los elementos del rango m..n de una matriz asociativa o de una tabla anidada. Si m es mayor que n o si m o n son nulos, no borra nada. Delete no puede ser usado en los VARRAYS para borrar elementos de forma individual. ... BEGIN EQUIPOS.DELETE(2); EQUIPOS.DELETE(7,7); EQUIPOS.DELETE(6,3); EQUIPOS.DELETE(3,6); ALUMNOS.DELETE; EMPLEADOS.DELETE('JUAN'); EMPLEADOS.DELETE('EVA','JOSE'); END;

******ebook converter DEMO Watermarks*******


CONCLUSIÓN Finalizamos el tema de tipos de datos compuestos, en el capítulo hemos hablado sobre registros y tipos de colecciones, conceptos avanzados del lenguaje PL/SQL. A modo de resumen, podemos decir que los tipos de datos colección se usan en ciertas operaciones que ejecutan funcionalidades importantes del lenguaje PL/SQL, que se asocian normalmente a la optimización del rendimiento de la Base de Datos Oracle. Otra funcionalidad importante que nos ofrecen, tal como hemos visto en algunos ejemplos anteriores, es la posibilidad de trabajar con registros de datos que no se encuentran almacenados en la Base de Datos. También podemos ejecutar ciertas operaciones con registros almacenadnos en tablas, siguiendo criterios que no podríamos establecer con sentencias SQL simples. En los siguientes capítulos, vamos a continuar profundizando en conceptos avanzados de PL/SQL.

******ebook converter DEMO Watermarks*******


CAPÍTULO 15 CURSORES VARIABLES En el capítulo 12 hemos hablado sobre cursores que son tipos de objetos estáticos, en este capítulo vamos a hablar sobre cursores que son punteros a un cursor estático. Por si no lo sabes, un puntero en una variable que almacenan la dirección de memoria de un dato u otra variable. Veamos pues que es esto de los cursores variables.

******ebook converter DEMO Watermarks*******


15.1 CURSORES VARIABLES EN PL/SQL Básicamente un cursor variable es una referencia a otro cursor. La diferencia principal entre un cursor estático y un cursor variable, es que un cursor variable es dinámico y no tiene asociada ninguna consulta específica. En el lenguaje PL/SQL el tipo de dato para un cursor variable es REF CURSOR. Los cursores variables son usados generalmente para pasar los resultados de una consulta entre subprogramas almacenados y varios clientes.

******ebook converter DEMO Watermarks*******


15.2 VENTAJAS DEL USO DE CURSORES VARIABLES El beneficio mรกs importante que presenta un cursor variable es que proporciona un mecanismo para pasar los resultados de las consultas (las filas devueltas) entre diferentes programas PL/SQL. Con los cursores variables, simplemente pasamos la referencia a ese cursor. Esto mejora el rendimiento y simplifica el cรณdigo. Algunos beneficios mรกs del uso de cursores variables son: Encapsulamiento. La consulta abierta por el cursor en centralizada en los procedimientos. Mantenimiento mรกs sencillo. En caso de requerir modificaciones, los cambios solo se realizan en el procedimiento almacenado. Mayor seguridad. El usuario debe disponer de permisos de ejecuciรณn sobre el procedimiento almacenado que abre el cursor, pero no es necesario que disponga de permisos de lectura sobre las tablas a las cuales accede el cursor.

******ebook converter DEMO Watermarks*******


15.3 DEFINICIÓN DE CURSORES VARIABLES Para definir un cursor variable, debemos realizar dos pasos:

1. Crear un cursor referenciado TYPE 2. Declarar variable o variables de cursor basadas en este tipo Las sintaxis de creación de un cursor variable es la siguiente: TYPE <Nombre_Cursor> IS REF CURSOR [ RETURN <return_type>];

Un ejemplo de declaración sería el siguiente: TYPE CDEP IS REF CURSOR RETURN PROYECTOS_DEPARTAMENTOS%ROWTYPE;

Los tipo REF CURSOR pueden ser fuertes (restrictivos), ejemplo anterior, o débiles (no restrictivos). Una definición tipo REF CURSOR fuerte específica un tipo de retorno, una definición débil no. Un ejemplo de definición REF CURSOR débil sería el siguiente: TYPE CDEP IS REF CURSOR;

******ebook converter DEMO Watermarks*******


15.4 DECLARACIÓN DE VARIABLES DE CURSOR Una vez definido el cursor, podemos declarar variables de cursor de ese tipo en cualquier bloque o subprograma PL/SQL. Ejemplo de declaración de variables de cursor: TYPE CDEP IS REF CURSOR RETURN PROYECTOS_DEPARTAMENTOS%ROWTYPE; VDEP CDEP; --variable de cursor

Debemos tener en cuenta que al declarar una variable cursor se crea un puntero, no un elemento, las variables de cursor no se pueden almacenar en la Base de Datos. Podemos usar %ROWTYPE para especificar un tipo de registro que representará una fila devuelta por una variable de cursor. Del mismo modo, podemos también usar %TYPE para proporcionar el tipo de datos de una variable de registro. En el siguiente fragmento de código, vemos un ejemplo de declaración de variables de cursor: TYPE RDEP IS RECORD ( CODDEPARTAMENTO VARCHAR2(10), NOMBRE VARCHAR2(80), DESCRIPCION VARCHAR2(255)); TYPE CDEP IS REF CURSOR RETURN RDEP; VDEP CDEP;

******ebook converter DEMO Watermarks*******


15.5 CONTROL DE VARIABLES DE CURSOR Existen tres instrucciones para controlar una variable de cursor, son OPEN-FOR, FETCH y CLOSE. Vamos a hablar de cada una de ellas en los siguientes puntos: 15.5.1 APERTURA DE VARIABLES DE CURSOR La sentencia OPEN-FOR asocia una variable de cursor con una consulta de varias filas, ejecuta la consulta e identifica el conjunto de resultados: La sintaxis de uso es la siguiente: OPEN {cursor_variable | :host_cursor_variable} FOR {Consulta_SQL | dynamic_string [USING bind_argument[, bind_argument]...] };

A diferencia de los cursores, las variables de cursor no toman parámetros. Las variables también pueden pasar consultas completas a una variable de cursor. La consulta puede referenciar variables de host y variables de PL/SQL, parámetros y funciones. Podemos aplicar los atributos de cursor %FOUND, %NOTFOUND, %ISOPEN y %ROWCOUNT a una variable de cursor. Hay que tener en cuenta que otra sentencia OPEN-FOR puede abrir la misma variable del cursor para diferentes consultas y no es necesario cerrar una variable de cursor antes de volver a abrirla. Cuando abrimos una variable de cursor para una consulta diferente, se pierde la consulta anterior. Se suele abrir una variable de cursor pasándola a un procedimiento almacenado que declara una variable de cursor como uno de sus parámetros. En el siguiente ejemplo vemos como en el cuerpo del paquete PEMP, el procedimiento abre la variable de cursor vemp: CREATE PACKAGE PEMP AS ... TYPE CEMP IS REF CURSOR RETURN PROYECTOS_EMPLEADOS%ROWTYPE; PROCEDURE OPEN_CEMP (VEMP IN OUT CEMP);

******ebook converter DEMO Watermarks*******


END PEMP; CREATE PACKAGE BODY PEMP AS ... PROCEDURE OPEN_CEMP (VEMP IN OUT CEMP) IS BEGIN OPEN VEMP FOR SELECT * FROM EMP; END OPEN_CEMP; END PEMP;

Cuando declaramos una variable de cursor como el parรกmetro formal de un subprograma que abre la variable de cursor, debemos especificar el modo IN OUT. Otra opciรณn es usar un procedimiento independiente para la variable de cursor, como se puede ver en el siguiente ejemplo: CREATE PACKAGE PTIPOS AS TYPE GENERICO IS REF CURSOR; TYPE E IS REF CURSOR RETURN PROYECTOS_EMPLEADOS%ROWTYPE; TYPE D IS REF CURSOR RETURN PROYECTOS_DEPARTAMENTOS%ROWTYPE; ... END PTIPOS;

A continuaciรณn vamos a ver un ejemplo donde se puede apreciar cรณmo se pasa una variable de cursor y un selector a un procedimiento que ejecuta consultas con diferentes tipos de devoluciรณn: CREATE OR REPLACE PACKAGE PDATOS AS TYPE CGENERICO IS REF CURSOR; PROCEDURE COPEN (GENERIC_CV IN OUT CGENERICO, P INT); END PDATOS; CREATE OR REPLACE PACKAGE BODY PDATOS AS PROCEDURE COPEN (VGEN IN OUT CGENERICO, P INT) IS BEGIN

******ebook converter DEMO Watermarks*******


IF P = 1 THEN OPEN VGEN FOR SELECT * FROM PROYECTOS_EMPLEADOS; ELSIF P = 2 THEN OPEN VGEN FOR SELECT * FROM PROYECTOS_DEPARTAMENTOS; ELSIF P = 3 THEN OPEN VGEN FOR SELECT * FROM PROYECTOS_PROYECTOSTIC; END IF; END; END PDATOS;

15.5.2 OBTENCIร N DE UNA VARIABLE DE CURSOR Con la instrucciรณn FETCH recuperamos filas del conjunto de resultados de una consulta de varias filas. Las sintaxis de uso es la siguiente: FETCH {cursor_variable_name | :host_cursor_variable_name} [BULK COLLECT] INTO {variable_name[, variable_name]... | record_name};

Mediante la clรกusula BULK COLLECT, podemos buscar filas de una variable de cursor en una o mรกs colecciones. Por ejemplo: DECLARE TYPE TCEMP IS REF CURSOR RETURN PROYECTOS_EMPLEADOS%ROWTYPE; TYPE LISTANOMBRES IS TABLE OF PROYECTOS_EMPLEADOS.NOMBRE%TYPE; TYPE LISTADNI IS TABLE OF PROYECTOS_EMPLEADOS.DNI%TYPE; CEMP TCEMP; VNOMBRES LISTANOMBRES; VDNI LISTADNI; BEGIN

******ebook converter DEMO Watermarks*******


OPEN CEMP FOR SELECT NOMBRE, DNI FROM PROYECTOS_EMPLEADOS; FETCH CEMP BULK COLLECT INTO VNOMBRES, VDNI; ... END;

Debemos de tener en cuenta que cualquier variable en la consulta asociada se evalúa solo cuando se abre la variable cursor. Para cambiar el conjunto de resultados o valores de las variables en la consulta, debemos volver a abrir la variable cursor con las variables establecidas en sus nuevos valores. Es posible usar una cláusula INTO diferente en las recuperaciones, haciéndolo de forma separada con la misma variable de cursor. Cada una de las extracciones recupera otra fila del mismo conjunto de resultados. El lenguaje PL/SQL asegura que el tipo de retorno de una variable cursor es compatible con la cláusula INTO de la sentencia FETCH. Para cada valor devuelto por la consulta asociada con la variable de cursor, debe haber una variable o campo correspondiente que sea compatible con el tipo en la cláusula INTO. El número de campo o variable ha de ser igual al número de valores de columna. 15.5.3 CIERRE DE UNA VARIABLE DE CURSOR Con la sentencia CLOSE cerramos (o deshabilitamos) una variable de cursor. Las sintaxis de uso es: CLOSE {cursor_variable_name | :host_cursor_variable_name);

El siguiente ejemplo muestra el proceso: LOOP FETCH CEMP INTO VEMP; EXIT WHEN CEMP%NOTFOUND; ... END LOOP;

Cuando se procesa la última fila, se cierra la variable cursor cemp. Si intentamos cerrar una variable de cursor ya cerrada, se genera la excepción

******ebook converter DEMO Watermarks*******


INVALID_CURSOR.

******ebook converter DEMO Watermarks*******


15.6 EJEMPLOS DE CURSOR VARIABLE Usualmente se usa un cursor variable pasándole un procedimiento almacenado que hace la declaración del cursor variable como parámetros. Lo vemos en el siguiente ejemplo: CREATE OR REPLACE PACKAGE EMPLEADOS AS TYPE CEMP IS REF CURSOR RETURN PROYECTOS_EMPLEADOS%ROWTYPE; PROCEDURE OPEN_CVEMP (EMP_CV IN OUT CEMP); END EMPLEADOS; CREATE OR REPLACE PACKAGE BODY EMPLEADOS AS PROCEDURE OPEN_CVEMP (EMP_CV IN OUT CEMP) IS BEGIN OPEN EMP_CV FOR SELECT * FROM PROYECTOS_EMPLEADOS; END OPEN_CVEMP; END EMPLEADOS;

En este caso es necesario especificar el modo IN OUT. Podemos usar también un cursor variable y un selector a un procedimiento almacenado, se ejecutarán consultas que retornan tipos diferentes: En el siguiente fragmento de código podemos verlo: CREATE PACKAGE BODY DATOSPROYECTOS AS PROCEDURE OPEN_CVEMP (VGER IN OUT CTGER, P IN NUMBER) IS BEGIN IF P = 1 THEN OPEN VGER FOR SELECT * FROM PROYECTOS_EMPLEADOS; ELSIF P = 2 THEN OPEN VGER FOR SELECT * FROM PROYECTOS_DEPARTAMENTOS; ELSIF P = 3 THEN OPEN VGER FOR SELECT * FROM PROYECTOS_SERVICIOS;

******ebook converter DEMO Watermarks*******


END IF; END OPEN_CVEMP; END DATOSPROYECTOS;

******ebook converter DEMO Watermarks*******


CONCLUSIÓN En este capítulo, el 15, hemos tratado un tema bastante complejo. Los cursores variables son un tema bastante avanzado, en el contenido del capítulo, he intentado simplificar al máximo posible la teoría y apoyarme en los ejemplos para tratar de aclarar los conceptos. Sin duda, los cursores variables son un tema que requiere de tiempo y práctica para que podamos desenvolvernos con cierta soltura en su manejo. Podemos hablar mucho sobre cursores variables, aquí he intentado establecer las bases e iniciar al lector en el tema, filosofía que intento mantener a en el contenido del libro. Ya sabemos que un cursor variable, como lo definimos y para qué podríamos usarlo. Más sobre cursores variables en la documentación oficial de Oracle: https://docs.oracle.com/cd/A97630_01/appdev.920/a96624/06_ora.htm#4641 En el siguiente capítulo, último capítulo del libro, vamos a estudiar un concepto sobre el cual no hemos hablado hasta ahora, SQL Dinámico.

******ebook converter DEMO Watermarks*******


CAPÍTULO 16 SQL DINÁMICO En determinadas situaciones, puede surgir la necesidad de escribir sentencias SQL en el momento de la ejecución, modo dinámico, al contrario de como lo hemos estado haciendo hasta ahora, modo estático. Cuando hablamos de modo estático, hacemos referencia a las sentencias SQL que han sido escritas en el momento en el que se crea la aplicación. En este capítulo vamos a hablar sobre SQL Dinámico.

******ebook converter DEMO Watermarks*******


16.1 USO DE SQL DINÁMICO Hacemos uso del SQL Dinámico para ejecutar algunas de las siguientes operaciones: Comandos DDL (Data Definition Language o Lenguaje de Definición de Datos). Por ejemplo CREATE, DROP, etc. Comandos DCL (Data Control Language o Lenguaje de Control de Datos). Por ejemplo GRANT, REVOKE, etc. Comandos de Control de Sesión. Por ejemplo SET ROLE, ALTER SESSION, etc. También podemos hacer uso de SQL Dinámico para dotar de mayor flexibilidad en el uso de cláusulas WHERE en la ejecución o realizar diferentes SELECT a diferentes esquemas de acuerdo a las opciones o parámetros especificados. Para el uso de SQL Dinámico disponemos de dos opciones: DBMS_SQL. El paquete DBMS_SQL nos proporciona una interfaz para utilizar SQL dinámico para analizar cualquier instrucción de lenguaje de manipulación de datos (DML) o lenguaje de definición de datos (DDL) mediante PL/SQL. EXECUTE IMMEDIATE. Nos permite ejecutar una instrucción SQL dinámica o un bloque PL/SQL anónimo. Podemos usar EXECUTE IMMEDIATE para emitir sentencias SQL que no pueden ser representadas directamente en PL/SQL o para generar sentencias en las que no se conocen todos los nombres de tablas, cláusulas WHERE, etc. Podemos usar ambas opciones, pero EXECUTE IMMEDIATE es más fácil de usar y nos ofrece mejor rendimiento y versatilidad. En la gran mayoría de casos, se utiliza EXECUTE IMMEDIATE a excepción de sentencias SELECT que devuelven varias filas.

******ebook converter DEMO Watermarks*******


16.2 SENTENCIA EXECUTE INMEDIATE Lo primero que debemos de tener en cuenta es que EXECUTE IMMEDIATE solo permite usar sentencias SQL que devuelven una sola fila. Esto es muy importante. EXECUTE IMMEDIATE permite el uso de variables de entradas y variables de salida. Básicamente EXECUTE IMMEDIATE nos permite la ejecución de sentencias SQL o bloques PL/SQL a partir de una cadena de texto dinámica. La desventaja es que genera problemas de seguridad en los ataques inyección SQL. Para evitar esto, usamos las variables bind, en lugar de concatenar cadenas. Las sintaxis para el uso de EXECUTE IMMEDIATE es: EXECUTE IMMEDIATE CONSULTA_SQL [INTO { VARIABLE| REGISTRO}] [USING [IN | OUT | IN OUT] VARIABLE_BIND [, [IN | OUT | IN OUT] VARIABLE_BIND]] [{RETURNING | RETURN} INTO VARIABLE_BIND [,VARIABLE_BIND]...];

Donde: Consulta_SQL, instrucción SQL o bloque PL/SQL Variable, variable donde se almacena el valor devuelto Registro, variable estructura en la que se almacena una fila Variable Bind, valor que se pasa a la sentencia SQL, por defecto es un argumento IN. En caso de usar RETURNING, los parámetros permitidos son de tipo IN. Los valores de salida se colocan a continuación de RETURNING INTO. Se admite cualquier tipo de dato en las variables bind, excepto valores booleanos (TRUE, FALSE o NULL). Vamos a ver continuación un ejemplo sencillo.

******ebook converter DEMO Watermarks*******


En el siguiente ejemplo hacemos uso de sentencias DDL y DML. BEGIN EXECUTE IMMEDIATE 'CREATE TABLE TABLE1 (CAMPO1 VARCHAR2(255), CAMPO2 VARCHAR2(10))'; EXECUTE IMMEDIATE 'INSERT INTO TABLE1 (CAMPO1, CAMPO2) VALUES (:TEXTO1, :TEXTO2)' USING 'CADENA1', 'CADENA2'; EXECUTE IMMEDIATE 'INSERT INTO TABLE1 (CAMPO1, CAMPO2) VALUES (:TEXTO1, :TEXTO2)' USING 'CADENA3', 'CADENA4'; EXECUTE IMMEDIATE 'UPDATE TABLE1 SET CAMPO2 = :TEXTO1 WHERE CAMPO1 = :TEXTO2' USING 'CADENA111', 'CADENA1'; EXECUTE IMMEDIATE 'DELETE FROM TABLE1 WHERE CAMPO2 = :TEXTO1' USING 'CADENA111'; END;

En este ejemplo hacemos uso de la sentencia SELECT… INTO. DECLARE VAR VARCHAR2(20); BEGIN EXECUTE IMMEDIATE 'SELECT CAMPO1 FROM TABLE1 WHERE CAMPO2 = :TEXTO4' INTO VAR USING 'CADENA4'; DBMS_OUTPUT.PUT_LINE( 'CAMPO: ' || VAR); END;

******ebook converter DEMO Watermarks*******


16.3 RECUPERACIÓN DE VARIAS FILAS Para poder recuperar varias filas mediante el uso de SQL Dinámico, debemos recurrir a los cursores variables. El proceso sería: Generar cursor variable mediante la instrucción OPEN-FOR Leer el resultando con FETCH Cerrar el cursor con CLOSE La sintaxis de uso es la siguiente: OPEN {cursor_variable | :host_cursor_variable} FOR SentenciaSQL [USING argumento_bind[, argumento_bind]...];

Una característica a tener en cuenta es que debemos definir el cursor variable como no restrictivo para que podamos asignarle cualquier tipo de consulta SQL. DECLARE TYPE LSERVICIOS IS REF CURSOR; VSERVICIO LSERVICIOS; VCODSERVICIO VARCHAR2(10); VNOMBRE VARCHAR2(100); BEGIN OPEN VSERVICIO FOR 'SELECT CODSERVICIO, NOMBRE FROM PROYECTOS_SERVICIOS WHERE CODSERVICIO > :C' USING VCODSERVICIO; ... END;

Las filas devueltas las leemos usando la sentencia FETCH, para ello usamos la sintaxis: FETCH {cursor_variable | :host_cursor_variable} INTO { variable | registro};

******ebook converter DEMO Watermarks*******


Para el ejemplo anterior, lo haríamos de la siguiente forma: LOOP FETCH vservicio INTO vcodservicio, vnombre; EXIT WHEN vservicio%NOTFOUND; -- process row END LOOP

Para cada valor de columna devuelto por la consulta asociada con la variable cursor, debe haber una variable correspondiente compatible con el tipo de cláusula INTO. Podemos usar una cláusula INTO distinta en transferencias separadas con la misma variable de cursor. Si hacemos una búsqueda desde una variable cerrada o no abierta, se genera la excepción INVALID_CURSOR. Por último, debemos cerrar el cursor variable. Las sintaxis es la siguiente: CLOSE {cursor_variable | :host_cursor_variable};

Continuando con el ejemplo, cuando la última fila es procesada, se cierra la variable de cursor: CLOSE vservicio;

A continuación mostramos un ejemplo que puede buscar filas del conjunto de resultados de una consulta dinámica de varias filas en un registro: DECLARE TYPE CEMP IS REF CURSOR; VEMP CEMP; REMP PROYECTOS_EMPLEADOS%ROWTYPE; VSQL VARCHAR2(200); IDCAT VARCHAR2(15) := '002PS'; BEGIN

******ebook converter DEMO Watermarks*******


VSQL := 'SELECT * FROM PROYECTOS_EMPLEADOS WHERE IDCATEGORIA = :J'; OPEN VEMP FOR VSQL USING IDCAT; LOOP FETCH VEMP INTO REMP; EXIT WHEN VEMP%NOTFOUND; -- PROCESS RECORD END LOOP; CLOSE VEMP; END;

******ebook converter DEMO Watermarks*******


CONCLUSIÓN Genial, hemos finalizado el capítulo 16 y dejamos visto con ello el tema SQL Dinámico, al igual que los dos capítulos anteriores, podríamos decir que este capítulo trata también sobre que podemos denominar como conceptos avanzados de PL/SQL. Espero, que con lo visto en el capítulo, te queda claro que es y cómo usar SQL Dinámico en Oracle. No quiero repetirme de verdad, pero la teoría no sirve de nada sin práctica.

******ebook converter DEMO Watermarks*******


CONCLUSIÓN FINAL Hemos llegado al final, la mayor recompensa tras el trabajo que implica escribir un libro, son muchas horas, es que para ti lector, la documentación escrita te resulte de utilidad y te ayude a introducirte y mejorar tu nivel de conocimientos sobre el lenguaje PL/SQL. Este es el tercer libro de la serie de libros Diario de un Autodidacta, en mi página de autor puedes encontrar todos los libros que voy publicando: https://www.amazon.com/ISAAC-NARANJO-GARCÍA/e/B01LYGLS7G

Añadir también, tal como dije en la página sobre el autor, que para cualquier duda o consulta puedes escribirme a diariodeunautodidacta@gmail.com, intentaré ayudarte en todo lo posible con las dudas que tienen que ver con la materia estudiada en los libros publicados, ten paciencia, intentaré responder lo antes posible. Por otro lado, te pediría lector como favor personal, que cualquier error o errata que encuentres, tanto ortográfico como en la explicación de contenidos, me lo notificarás mediante el Email anterior. Intentaré corregir todos los errores encontrados en la mayor brevedad posible. Nadie está libre de errores en la autopublicación de libros. Te animo también a dejar tu valoración sobre el libro en Amazon, me encantaría conocer tu opinión. Para mi es fundamental conocer la opinión de los lectores, me anima a seguir escribiendo libros y me ayuda a mejorar y corregir las cosas que puede que no esté haciendo correctamente. Para finalizar, quiero de nuevo darte las gracias por acompañarme en esta aventura.

******ebook converter DEMO Watermarks*******


ANEXO FORMATOS DE CONVERSIÓN PARA FECHAS

******ebook converter DEMO Watermarks*******


DIRECTORIO DE RECURSOS Este libro dispone un Directorio de Recursos dónde podemos encontrar todo el material de apoyo necesario. Dicho Directorio lo tenemos alojado en la URL: https://drive.google.com/file/d/0B4NbqCMuiQUWeC1yYVQ2MnF0ZlE/view? usp=sharing Contraseña para el archivo: PLSQL2016 Dentro del Directorio de Recursos, puedes encontrar una Carpeta para cada Capítulo del libro. Dentro de estas Carpetas, tenemos todos los recursos correspondientes al Capítulo y las imágenes incluidas dentro del Capítulo. Referente a las imágenes, comentar que todas las imágenes incluidas en un ebook deben estar optimizadas y en algunos dispositivos no se aprecian con el nivel de detalle requerido. Si se da el caso, dentro de la carpeta que corresponde a cada Capítulo, tienes una carpeta imagen que incluye todas las figuras del Capítulo a una resolución adecuada para su correcta visualización.

******ebook converter DEMO Watermarks*******


BIBLIOGRAFÍA Para adquirir conocimientos es necesario aprender de los que más saben, rodearte de gente que sabe mucho más que tú en la materia en la cual estés interesado, te ayuda a mejorar. Gracias a los grandes profesionales de Oracle he aprendido mucho. Aquí te dejo algunos libros que yo he usado y me han ayudado a mejorar mis conocimientos en PL/SQL, y por supuesto me han servido de inspiración para la escritura de este libro. Oracle 11g Curso Práctico, Teaching Soft Group. Ra-Ma 2011. Oracle 11g, SQL, PL/SQL, SQL*Plus. Eni Ediciones 2011. Manual Gestión de Bases de Datos. Espacio de Formación 2012. Documentación Curso Oracle Database 12c Lenguaje de programación PL/SQL, GEAMIND Formación IT.

******ebook converter DEMO Watermarks*******


WEBGRAFÍA Además de los libros, existen también numerosos sitios web que recomiendo visites. A continuación indico toda la webgrafía que he consultado para documentarme: Oracle Data Base Online Documentation, https://docs.oracle.com Oracle Learning Library, http://www.oracle.com/technetwork/tutorials/index.html Oracle Community Directory, https://community.oracle.com/welcome

******ebook converter DEMO Watermarks*******


Turn static files into dynamic content formats.

Create a flipbook
Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.