Sunteți pe pagina 1din 59

Introduccin a Oracle SQL y PL/SQL

Introduccin
Se transforma requerimientos del negocio dentro de una base de datos operacional.
Estrategia y anlisis Diseo Construccin y documentacin Transicin
Produccin
Una BD es una coleccin de informacin organizada, hay 4 tipos jerrquica, red,
relacional y relacional de objetos
Concepto de BD relacional
Coleccin de objetos o relaciones
Un grupo de operadores pueden actuar en las relaciones para producir otras relaciones
Integridad de los datos para exactitud y consistencia
Definicin de una BD relacional
Es una coleccin de relaciones o tablas en dos dimensiones
Modelos de datos
Son la piedra angular del diseo ayudan a entender lo que quiere el cliente.
Modelos ER
Los datos son divididos dentro de categoras discretas o entidades, un modelo de
relacin entre entidades es una ilustracin de varias entidades en el negocio y la
relacin entre estas, los modelos separan la informacin requerida por los negocios de
las actividades de estos.
Componentes
Entidad : Objeto que representa la informacin que se necesita
Atributo : Describe o califica la entidad
Relacin : Asociacin entre entidades mostrando opcionalidad y grado(cardinalidad).
Identificadores nicos
Son una combinacin de atributos o relaciones o ambos, este hace que cada
ocurrencia de una entidad sea nica Smbolo #, secundario (#)
Relacionando mltiples tablas
Cada tabla contiene datos que describen exactamente una entidad, las categoras de
los datos son listados en los atributos y los casos individuales en las filas.
Las llaves forneas son basadas en valores de datos y son puramente lgicos, no
fsicos, apuntadores.
Propiedades de una BD relacional
Puede ser accedida y modificada con sentencias structured query language (SQL) el
cual permite comunicarse con el servidor
Contiene una coleccin de tablas
Usa un grupo de operadores
Sistema de BD relacional
Se puede almacenar y administrar datos con todas las ventajas de la estructura
relacional PL/SQL
Oracle 8 : Sistema de administracin de BD relacionales de objetos
Provee una nueva mquina que trae programacin orientada a objetos, tipos de datos
complejos, objetos de negocio complejos y total compatibilidad con el mundo
relacional.
Usuario define tipos de datos y objetos
Soporta objetos grandes y multimeda

2
Oracle 8i : BD en plataforma internet
Contiene herramientas avanzadas para administrar todos los tipos de datos en web
sites.
iFS Internet File System combina el poder de Oracle 8i con el fcil uso de un FS, los
usuarios pueden fcilmente acceder a los archivos y folders en un iFS usando una
variedad de protocolos como HTML, FTP, IMAP4 .
Oracle 8i incluye una robusta, integrada y escalable mquina virtual de java dentro
del servidor Jserver
O8i provee full integracin con Microsoft Transaction Server (MTS)
Plataforma de internet Oracle
Para e-commerce y data warehousing es construida en 3 piezas principales
1. Clientes Browser based para procesar presentacin
2. Servidores de aplicacin para ejecutar lgica de los negocios y lgica de la
presentacin para clientes browser-based
3. Bases de datos para ejecutar lgica de negocios intensiva y servicio de datos
Sentencias SQL
SELECT

Recuperacin de datos

INSERT
UPDATE
DELETE

DML

CREATE
ALTER
DROP
RENAME
TRUNCATE

DDL

COMMIT
ROLLBACK
SAVEPOINT

Control transaccional

GRANT
REVOKE

Lenguaje de control de datos (DCL)

Hacerca de PL/SQL Es una extencin de SQL , la manipulacin de datos y las


sentencias de consulta de SQL son incluidas dentro de unidades de cdigo
procedimentales
Ambiente PL/SQL Un bloque PL/SQL es procesado por la mquina PL/SQL la cual
puede residir dentro de la herramienta o dentro del servidor.
Cuando se invoca PL/SQL desde un programa, SQL *Plus o server manager, lo
procesa el servidor , este separa las sentencias SQL y las envia individualmente al
ejecutor de sentencias SQL

Mquina PL/SQL
PL/SQL
BLOCK

PL/SQL
BLOCK

Ejecutor de sentencias
procedimentales

EJECUTOR DE SENTENCIAS SQL


Servidor Oracle

Captulo 1 escribiendo sentencias SQL bsicas


Capacidades de las sentencias SQL
Se recupera informacin usando SELECT haciendo.
Seleccin : Para elegir filas de una tabla
Proyeccin : Elegir columnas
Join : Trae datos almacenados en diferentes tablas
SELECT [DISTINCT] (*, column [alias])
FROM table;
Escribiendo sentencias SQL
Sentencia SQL pueden ser entradas en una o ms lneas
Las palabras clave no pueden ser divididas a travs de lneas
Dentro de SQL*Plus una sentencia SQL es entrada en el prompt, y las lneas
siguientes son numeradas , esto se llama SQL buffer
Para seleccionar todas las filas con * o enuncindolas todas en el SELECT.
Encabezados por default de las columnas
Justificacin : Fecha y carcteres a la izquierda, Nmeros a la derecha
Default : Maysculas
Expresiones aritmticas Pueden contener operadores aritmticos + - / *
Nota : SQL*Plus ignora espacios en blanco antes y despus del operador
Precedencia de operadores * / + - , operadores de la misma precedencia son
evaluados de izquierda a derecha, los parntesis alteran la precedencia.
Definiendo valores NULL Es diferente de cero (nmero ) espacio (carcter) , es
unavailable, unassigned, unknow, en expresiones aritmticas toda se vuelve NULL.
Definiendo alias Renombra el encabezado de la columna, sigue al nombre de la
columna AS es opcional, se requiere comillas dobles si tiene espacios o carcteres
especiales, Para que el alias no salga en maysculas encerrarlo en comillas dobles.
Operador de concatenacin | | Se combinan las columnas para que haya una sola
salida.
SELECT ename||job AS Employes
FROM emp;
Strings de carcteres literales Un literal es un carcter, nmero o fecha incluido en
el SELECT.
Deben ser encerrados en comillas simples
Cada literal sale una vez por cada fila retornada
SELECT ename | | is a | | job AS Emplye Details
FROM emp;
Eliminar filas duplicadas DISTINCT , UNIQUE
Interaccin de SQL y SQL*Plus
SQL es un lenguaje de comandos para comunicarse con el servidor, cuando se entra
una sentencia, esta se almacena como parte de la memoria llama SQL buffer y ah se
mantiene mientras no se entre otra sentencia.
SQL*Plus Es una herramienta que reconoce y ejecuta sentencias SQL, acepta
entradas SQL de archivos, provee un editor para modificar sentencias SQL, controla
el ambiente.

4
SQL

SQL*Plus

Lenguaje
Es ANSI

Reconoce sentencias SQL


Interfaz propietaria de
Oracle para ejecutar sentencias SQL
No manipula valores en la BD
Es entrado lneas a lneas al tiempo, no

Manipula datos y definiciones de tablas


Queda en un buffer SQL
es
No tiene carcter de continuacin
No puede ser abreviado
Usa carcter de terminacin
Usa funciones para formatear datos

Almacenado en el SQL buffer


Si tiene (-)
Si puede ser abreviado
Se ejecuta inmedatamente
Usa comandos para formatear

SQL*Plus
Categora
Environment
Format
File Manipulatin
Executin
Edit
Interaccin
Miscellaneous

Propsito
Afecta en general todas las sentencias SQL para la sesin
Formatea resultados de la consulta
Saves, Loads y corre archivos de scripts
Envia sentencias SQL del buffer al servidor
Modifica sentencias SQL en el buffer
Permite que se pase y se cree variables para sentencias SQL
Contiene varios comandos para conectarse a la BD, manipular
el ambiente y desplegar definiciones de columnas

DESC[RIBE] tablename
Comandos de edicin de SQL*Plus
Comando
A[PPEND] text
C[HANGUE] text/old/new
C[HANGUE] /text/
CL[EAR] BUFF[ER]
DEL
I[NPUT]
I[NPUT] text
L[IST]
L[IST] n
L[IST] m n
N
n text
0 text

Descripcin
Adiciona texto al final de la lneas corriente
Cambia texto viejo por nuevo en la lneas corrienta
Borra texto de la lneas corriente
Borra todas las lneas del SQL buffer
Borra la lneas corriente
Inserta un nmero indefinido de lneas
Inserta una lneas con el texto
Lista todas las lneas en el SQL buffer
Lista la lneas n
Lista las lneas entre m y n
Especifica la lneas a ser la lneas corriente
Reemplaza la lneas n con el texto
Inserta una lneas antes de la lneas 1

Command
SAV[E] filename [.ext]
[REP[LACE]APP[END]]
GET filename[.ext]
STA[RT] filename[.ext]
@filename
ED[IT]
EDIT [Filename[.ext]]
SPO[OL] [filaname[.ext]]
OFF|OUT
EXIT

Descripcin
Salva las lneas corrientes del SQL buffer a un archivo
Trae un archivo salvado al SQL buffer

Invoca al editor y salva el buffer corriente en afiedt.buf

Captulo 2 Restringiendo y ordenando datos


Se usa la clausula WHERE para restringir datos, Comparando valores de columnas,
literales, expresiones aritmticas y funciones.
Fechas y cadenas de carcteres
Son encerrados en columnas simples, los carcteres son sensitivos, el formato por
default de las fechas es DD-MON-YYYY
SELECT ename
FROM emp
WHERE ename = JAMES;
BETWEEN : Desplegar un rango de valores
IN : Para comparar con una lista
LIKE : Comparar con un patrn de carcteres, usar comodines %, _ , se pueden
combinar los comodines. Se puede usar la opcin de ESCAPE.
SELECT * FROM dept WHERE dname LIKE %\_% ESCAPE \ ;
IS NULL : Para encontrar valores NULL, no se pueden encontrar con =
Operadores lgicos
AND : NULL and FALSE = FALSE
OR : NULL and TRUE = TRUE
NOT : NULL and TRUE = NULL
Reglas de precedencia
1 todos los operadores de comparacin, 2 NOT , 3 AND y 4 OR, se alteran con
parntesis.
ORDER BY : Para ordenar ASC, DESC, si no se usa el orden es indefinido, se
pueden organizar resultados por ms de una columna.

Captulo 3 Funciones de una sola fila


Aceptan argumentos y siempre retornan valores.
Hay 2 tipos
1. De una sola fila : Operan en una sola fila y retornan un solo valor por fila
Carcter : Aceptan carcteres y retornan valores de carcteres o nmeros
Numricas : Aceptan nmeros y retornan nmeros
Fechas : Aceptan fechas retornan fechas excepto MONTHS_BETWEEN
Conversin : Convierten un valor de un tipo a otro
General : NVL, DECODE
2. De multiples filas : Manipulan un grupo de filas y dan un resultado por cada
grupo
Manipulan items de datos, los argumentos pueden ser Constantes, Variables,
Columnas, Expresiones. Actuan en cada fila del query, pueden retornar valores de un
tipo diferente al referenciado
Function_name (column | expression, [arg1, arg2...])
Funciones de carcter
Hay 2 tipos : De conversin, De manipulacin de caracteres
LOWER (column | expresin )
course
UPPER (column | expresin)
COURSE
INITCAP (column | expresin)
Course
CONCAT (column | expresin, column | expresin ...)
SUBSTR (column | expresin,m,n)
LENGHT (column | expresin ) : Retorna el nmero de carcteres
INSTR (column | expresin,m) : Retorna la posicin numrica del carcter enunciado
LPAD (column | expresin , n ,string) : Pega en n posicones un carcter
justificando a la derecha
TRIM (leading | trailing | both, trim_character FROM trim_source )
TRIM (S FROM SSMITH) = MITH
Funciones numricas
ROUND (column | expresin , n ) : Redondea el valor a n lugares decimales
TRUNC (column | expresin , n ) : Trunca la columna a n valores decimales, si n es
omitido quita los decimales ( Si es negativo los nmeros a la izquierda del decimal
son convertidos a cero (0) )
MOD (m , n ) : Retorna el residuo de la divisin de m entre n
ROUND (45.923 , 2 ) = 45.92
ROUND (45.923 , 0 ) = 46
ROUND (45.923 , -1 ) = 50
TRUNC (45.923 , 2 ) = 45.92
TRUNC (45.923 , 0 ) = 45
TRUNC (45.923 , -1 ) = 40
ROUND y TRUNC pueden ser usadas con funciones de fechas
Trabajando con fechas
Oracle almacena las fechas en un formato interno numrico, siglo, ao, mes, da,
horas, minutos, segundos
El formato default es DD MON YY
SYSDATE funcin que retorna la fecha y el tiempo corrientes
DUAL es una tabla de SYS para cumplir con la sintaxis debido a que el SELECT y el
FROM son obligatorios.

7
Aritmtica con fechas
Operacin
Date + number
Date date
Date + number/24

Result
Date
Nmero das
Date

Descripcin
Adiciona un nmero de das
Sustrae una fecha e otra
Adiciona nmero de horas

Funciones de fecha
MONTHS_BETWEEN(date1,date2) : Meses entre las dos fechas negativo o positivo
(01-SEPT-95,11-JAN-94) = 19.6774194
ADD_MONTHS(date,n): n positivo o negativo
(11-JAN-94,6) = 11-JUL-94
NEXT_DAY(date, char) : Encuentra la fecha de el prximo da especificado de la
semana.
(01-SEPT-95,FRIDAY) = 08-SEPT-95
LAST_DAY(date) : Encuentra el ultimo da del mes
(01-SEPT-95) = 30-SEPT-95
ROUND(date[,fmt]) : Retorna la fecha en la unidad especificada en el format model,
si el format model es omitido la fecha es redondeada al da mas cercano.
ROUND(25-JUL-95,MONTH) 01-AUG-95
ROUND(25-JUL-95,YEAR) 01-JAN-96
TRUNC(date[,fmt]) : Retorna la fecha con el tiempo de la porcin del da truncada
TRUNC(25-JUL-95,MONTH) = 01-JUL-95
TRUNC(25-JUL-95,YEAR) = 01-JAN-95
Conversin de tipos de datos implcita
Para evaluacin de expresiones
VARCHAR2 o CHAR
NUMBER
VARCHAR2 o CHAR
DATE
---NUMBER
VARCHAR2
DATE
VARCHAR2
Conversin explicita
TO_CHAR(number | date,[fmt],[nlsparams]) : nlsparams especifica carcter decimal,
separador de grupo, smbolo de moneda local, smbolo de moneda internacional o las
abreviaciones para el da el mes , tiene un elemento fm para remover blancos o
suprimir ceros
TO_NUMBER(char,[fmt],[nlsparams]) : Convierte un string de caracteres que
contienen dgitos a un nmero en el formato especificado.
TO_DATE(char,[fmt],[nlsparams]) : Si fmt es omitido se usa el default DD-MONYY
Elementos del modelo del formato de fecha
YYY
YEAR
MM Mes en dos dgitos
MONTH Nombre completo del mes
DY Abreviacin de tres letras para el da de la semana
DAY
SCC o CC Siglos S prefijo BC con
IYYY,IYY,IY,I 4, 3 ,2 1 digito del ao basado en el estndar ISO
RM mes en nmeros romanos
WW o W semana del ao o del mes
DDD o DD o D da del ao, mes o semana
J da juliano
HH24:MI:SS AM
DD of MONTH

15:45:32 PM
12 of OCTOBER

8
Nmero de sufijos para nmeros
Ddspth fourteenth
AM o PM
Indicador de meridiano
A.M o P.M Indicador de meridiano con periodos
HH o HH12 o HH24
Hora del da u hora (1-12) u hora (0-23)
MI
Minuto de 0-59
SS
Segundo de 0-59
SSSS
Segundos pasados la media noche (0-86399)
/. , Puntuacin es reproducida en el resultado
TH
Nmero ordinario (Ej DDTH para 4TH)
SP
Ej DDSP para FOUR
SPTH o THSP Ej DDSPTH para FOURTH
Usando funcin TO_CHAR con fechas
SELECT ename, TO_CHAR(hiredate, fmDD Month YYYY)
FROM emp
KING

17 November 1981

Usando funcin TO_CHAR con nmeros


TO_CHAR(number,fmt)
9
Determina longitud del nmero
0
Despliega ceros
$
Signo flotante de dlar
L
Smbolo de moneda local flotante
.
,
MI
Signo menos a la derecha
PR
Parntesis para nmeros negativos
EEEE Notacin cientfica
V
Multiplicar por 10 n veces
(n nmero de 9s despus de la V)
B
Desplegar valores de ceros como
Blancos, no 0

9999 1234
0999 001234
$999 $1234
L999 FF1234
9.999 1.234
9,999 9,999
99MI 123499PR <1234>
99.999EEEE 1.234E+03
9V99 100
B9999.99

1234.00

SELECT TO_CHAR(sal , $99,999 )


FROM emp
$3,000
Formato de fecha RR
YY y RR son inversos
Ultimos dos dgitos
RR
0-49
Si ao corriente superior despus
50-99
Si ao corriente superior siglo antes

YY
El siglo corriente
El siglo corriente

Funcin NVL
NVL (expr1, expr2 ) convierte a nmeros, fechas y char o varchar2
Funcin DECODE
Fcilita el trabajo condicional como el CASE
DECODE (col/expresin ,

search1 , result1
[ , search2 , result2 , ..... ,]
[ , default ]
Si el default es omitido retorna NULL si la cadena no coincide con ninguna condicin

9
SELECT

job, sal,
DECODE( job,

ANALYST , SAL*1.1,
CLERK , SAL*1.15,
SAL )

FROM emp;
Funciones anidadas
Funciones de una sola fila pueden ser anidadas a cualquier nivel , y son evaluadas
desde la ms profunda a la menos profunda. o sea de adentro hacia fuera

10

Captulo 4 desplegando datos de mltiples tablas


Se trabaja haciendo JOIN entre las tablas, generalmente si se tienen n tablas se
necesitan n-1 joins para la consulta, esto no es cierto todo el tiempo Ej. Si la llave
primaria es compuesta.
Producto cartesiano
Se da cuando una condicin de JOIN es omitida, es invalida, todas las filas de la
primera tabla son cruzadas con todas las filas de la segunda tabla emp 14 dept 4 = 56
Tipos de joins
Equijoin : La columna debe ser igual en las dos tablas
Se utiliza el nombre de la tabla como prefjo table.columna, esto mejora performance,
y evita ambigedad si hay columnas con el mismo nombre en tablas diferentes. Se
usan en SELECT, WHERE y ORDER BY.
Para condiciones adicionales se utiliza los operadores como AND.
Usando alias para las tablas
Mximo 30 carcteres
Non-equijoin : Cuando la columna de una tabla no corresponde directamente a la
columna de otra Ej. BETWEEN, <=, >=
Outer-join : Se coloca a un lado de la expresin, no en los dos, se coloca al lado
donde no hay informacin (+), no puede usar el operador IN.
Self-join : Cruzar una tabla consigo misma

11

Captulo 5 Agregando datos usando funciones de


grupo
Funciones de grupo operan en juegos de filas para dar un resultado por grupo, estas
filas pueden ser toda la tabla o divididas por grupos.
Tipos de funciones de grupo
AVG(DISTINCT | ALL | n ) Promedio de n ignorando valores NULL, nmeros
COUNT({* | [ DISTINCT | ALL ] expr} ) Incluye nulos
MAX( [ DISTINCT | ALL ] expr ) Ignora nulos, todos los tipos de datos
MIN ([ DISTINCT | ALL ] expr ) Ignora nulos, todos los tipos de datos
STDDEV ( [ DISTINCT | ALL ]x) Desviacin standar de n ignora nulos, nmeros
SUM ( [DISTINCT | ALL ] n )
VARIANCE ( [DISTINCT | ALL ]x ) Varianza de n, ignora nulos
El servidor Oracle implcitamente ordena los resultados ascendentemente cuando usa
GROUP BY, para cambiar el orden usar ORDER BY.
Funciones de grupo y valores NULL
Todas las funciones de grupo ignoran valores NULL en la columna excepto COUNT.
Para incluir valores NULL se usa NVL.
SELECT (AVG(NVL(comm,0)))
FROM emp;

Para crear grupo GROUP BY


SELECT column , group_function(column)
FROM table
[WHERE condition ]
[GROUP BY group_by_expression ]
[ORDER BY column ]
Clausula GROUP BY
No se puede usar los alias de las columnas
Todas las columnas que no estan en una funcin de grupo deben estar en la clausula
GROUP BY.
Las columnas del GROUP BY pueden no estar en la lista del select.
Se puede agrupar por mas de una columna, grupos dentro de los grupos.
No se puede usar WHERE para restringir grupos para esto se usa HAVING, filas son
agrupadas, se aplica funcion de grupo, se despliega las que coincidan con HAVING.
Las funciones de grupo pueden ser anidadas a una profundidad de 2.

12

Captulo 6 subqueries
Se pueden colocar en : WHERE , HAVING, FROM
SELECT select_list
FROM table
WHERE exp operator
( SELECT select list
FROM table);
Los operadores de comparacin caen en dos clases una sola fila ( <, >,=,< >,<=,>= ) y
multiples filas (IN, ALL, ANY )
El sub query se ejecuta primero y su salida completa el query total.
No adicionar una clausula ORDER BY a un subquery.
Tipos de subqueries : De una sola fila, multiples filas, multiples columnas
Se pueden usar funciones de grupo en los subqueries
SELECT ename, job
FROM emp
WHERE sal = ( SELECT MIN(sal) FROM emp );
SELECT deptno , MIN(sal)
FROM emp
GROUP BY deptno
HAVING MIN(sal) > (SELECT MIN(sal) FROM emp WHERE deptno = 20);
Subqueries de multiples filas
Operador
IN
ANY
ALL

Significado
Igual a cualquier miembro de la lista
Compara el valor con cada valor retornado de la lista
Compara el valor con todos los valores de la lista

SELECT empno
FROM emp
WHERE sal < ANY ( SELECT sal FROM emp WHERE job= CLERK)
AND job <> CLERK;
SELECT empno
FROM emp
WHERE sal > ALL ( SELECT AVG(sal) FROM emp GROUP BY deptno);
El operador NOT puede ser usado con ANY, IN , ALL

13

Captulo 7 Subqueries de multiples columnas


SELECT column, ...
FROM table
WHERE (column, column, ... ) IN ( SELECT column, column, ...
FROM table
WHERE condition );
Las comparaciones pueden ser pairwise o nonpairwise
SELECT column, ...
FROM table
WHERE column1 IN ( SELECT column FROM table WHERE condition )
AND column2 IN ( SELECT column FROM table WHERE condition );
El SELECT no retorna filas si se utiliza NOT IN y en el subquery hay un NULL
debido a que NOT IN es eqwuivalente a =ALL.
IN es equivalente =ANY
Usando un subquery en la clausula FROM
SELECT a.ename, a.sal, b.salvg
FROM emp a, (SELECT deptno, avg(sal) salvg FROM emp GROUP BY deptno )
WHERE a.deptno = b.deptno

14

Captulo 8 Produciendo salidas legibles con SQL *


Plus
Con & se almacenan valores temporalmente.
&user_variable Indica una variable en una sentencia SQL, si la variable no existe
SQL*Plus se la pide al usuario
SET VERIFY ON|OFF Se usa para confirmar los cambios en la sentencia SQL , este
forza a SQL*Plus a desplegar texto antes y despues de reemplazar las variables con
los valores.
Las variables de fecha o carcter deben ser encerradas entre comillas simples.
Se puede especificar variables para columnas, como condicin en el ORDER BY , en
el from.
La variable &&
Para utilizar la reusar la variable sin tener que preguntar, SQL*Plus almacena el valor
usndole comando DEFINE, una vez el valor es colocado se necesita UNDEFINE
para resetear la variable.
Para definir variables se utiliza
DEFINE variable = value el cual crea una variable char y asigna el valor a esta.
DEFINE variable muestra la variable su valor y su tipo de dato
DEFINE despliega todas las variables del usuario
ACCEPT variable [datatype] [FORMAT format] [PROMPT text ] [HIDE]
Lee la lneas de la entrada por el usuario y almacena esto en una variable en donde
Datatype : es NUMBER, CHAR o DATE (CHAR tiene una longitud mxima de 240
bytes
Format : Especifica el formato Ej. A10 o 9.999
Hide : esconde la entrada del usuario por seguridad
En el comando ACCEPT no se le coloca & a la variable
Tips
DEFINE y ACCEPT crrean la variable si esta no existe
Se debe definir explcitamente un NUMBER o FECHA para variables de este tipo
DEFINE y UNDEFINE
Las variables permanecen mientras no se les de UNDEFINE o se salga de SQL*Plus,
se puede verificar los cambios con DEFINE, para definir variables para cada sessin,
se debe modificar el archivo login.sql asi las variables son creadas en el startup
Personalizando EL ambiente de SQL*Plus
Con comandos SET
SET system_variable value
Para verificar los valores seteados se usa SHOW
SQL>SET ECHO ON
SQL>SHOW ECHO
Echo ON
Para ver todas las variables
SHOW ALL
ARRAY [SIZE] {20 | n }El tamao para el fetch de los datos
COLSEP {_ | text }Setea el texto a ser impreso entre columnas default es el espacio
FEDD[BACK] {6 | n | OFF | ON } Despliega el nmero de registros devueltos por
una consulta cuando selecciona por los menos n registros
HEA[DING] {ON | OFF } Determina el encabezado
LIN[SIZE] {80 | n} El nmero de carcteres por lneas
LONG {80 | n} Setea el mximo para desplegar valores LONG
PAGES[IZE] {24 | n} Nmero de lneas por pagina
PAU[SE] {OFF | ON | text} controla el scroll de la terminal

15
TERM[OUT] {OFF | ON } Determina si la salida es desplegada enla pantalla
El archivo login.sql contiene los SET estandar y otros comandos SQL*Plus que se
implementan en el login.
COL[UMN] [column option ] Controla el formato de las columnas
TTI[TLE] [text |OFF | ON ] Especifica el encabezado de cada pagina
BTI[TLE] [text |OFF | ON ] Especifica el pie de cada pagina
BRE[AK] [ON report_element ]
Si se da un alias a la columna este debe ser especificado, no el nombre de la columna
El comando COLUMN
COL[UMN] [ {column | alias } [ option ] ]
CLE[AR] limpia cualquier formato de columna
FOR[MAT] format Cambia el despliegue de una columna usando el formato
HEA[DING] text Setea el encabezado de la columna ( una barra vertical (|) forza un
line feed )
JUS[TIFY] {aling} Justifica el encabezado de la columna derecha, izq o centro
NOPRI[NT] no imprime la columna
NUL[L] text Especifica el texto a ser desplegado para valores NULL
PRI[NT] muestra la columna
TRU[NCATED] Trunca el string al final de la primera lneas desplegada
WRA[PPED]
COLUMN ename HEADING Employee|name FORMAT A15
COLUMN sal JUSTIFY LEFT FORMAT $99,999.00
COLUMN mgr FORMAT 9999999 NULL no manager
COL[UMN] ename Despliega los valores corrientes para una columna
COL[UMN] ename CLE[AR] Limpia los valores seteados para la columna
CLE[AR] COL[UMN] Limpia los valores seteados para todas las columnas
Si se tiene un comando muy largo se puede continuar colocando (-)
Modelos de formato de columnas
An
despliega un ancho n
9
Solo digitos 9999 1234
0
Fuerza al cero lider 099999 01234
$
Smbolo de dlar $9999 $1234
L
Moneda local L9999 L1234
.
,
El servidor Oracle despliega (#) si el nmero excede el tamao dado en el formato,
tambien si el valor e alfanumerico mientras el actual es numerico
BREAK ON ename ON job Suprime duplicados para asegurar que trabaja
correctamente usar ORDER BY.
BREAK ON ename SKIP 4 ON job SKIP 2
BREAK on column [ |alias|row ] [skip n | dup | page ] on .. [on report ]
Donde
page Tira una nueva pagina cuando el valor del break cambia
skip n
Salta un nmero de lneas cuando el valor cambia
break se activa con columna, fila , pagina, reporte
duplicate despliega valores duplicados
Para limpiar todos los juegos de BREAK usar CLEAR
CLEAR BREAK

16

Captulo 9 Manipulando datos


Una transaccin consiste en un grupo de sentencias DML que forman una unidad
lgica de trabajo.
Para insertar nulos implcitamente omitir la columna, explcitamente colocar NULL
y Para carcteres y fechas.
Para insertar valores especiales como fechas el formato DD-MON-YYYY debe ser
usado de lo contrario se cambia con la funcion TO_DATE. Y el tiempo default es
00:00:00. Si se setea el formato RR el siglo puede no ser el corriente.
Se puede insertar valores usando variables de sustitucin.
INSERT INTO dept (deptno, dname )
VALUES ( &department, &name );
Estos le sern pedidos al usuario al momento de ejecutar la sentencia. Se puede usar
ACCEPT.
Se puede hacer INSERT en una tabla de datos de otra con un subquerie.
Para actualizar datos con UPDATE.
Para actualizar datos con subqueries de multiples columnas.
UPDATE emp
SET (job, deptno ) = ( SELECT job, deptno FROM emp WHERE empno = 7988 )
WHERE empno = 7698;
Se puede borrar filas de una tabla basado en valores de otra.
DELETE FROM employ
WHERE deptno = ( SELECT deptno FROM dept WHERE dname = SALES);
Transacciones de BD
Consiste de .
Grupo de DMLs
Un DDL
Un DCL
Las transacciones dan mas flexibilidad y control y aseguran consistencia en el caso de
que el proceso el sistema fallen.
Controlando transacciones
COMMIT, SAVEPOINT name, ROLLBACK [TO SAVEPOINT name]
Procesamiento implicito de transacciones
Un COMMIT se da cuando hay DDL, DCL o se sale normalmente de SQL*Plus.
Un ROLLBACK se da cuando hay una salida anormal de SQL*Plus o falla el sistema
Existe el comando AUTOCOMMIT OFF|ON.
Antes de COMMIT o ROLLBACK, las filas afectadas son bloqueadas para que no
sean cambiadas.
Despus del COMMIT las filas bloqueadas son liberadas, todos los savepoints son
borrados.
Se puede hacer marcas SAVEPOINT para el ROLLBACK. Si se crea un segundo
SAVEPOINT con el mismo nombre el primero es desacrtado.
El servidor Oracle implementa un SAVEPOINT implcito.

17
Si un DDL falla, el usuario no puede volver a los datos anteriores porque este tiene
autocommit.
Consistencia de lectura
Garantiza una vista consistente de los datos todo el tiempo.
Cambios hechos por un usuario no tienen conflicto con los cambios hechospor otro
usuario.
El propsito es asegurar que cada usuario mire los datos como estaban con el ultimo
COMMIT, antes de que la operacin DML arrancara.
El LOCKING es efectivo debido a que previene acciones destructivas entre
operaciones concurrentes.
No requiere accin de l usuario
Usa el nivel mas bajo de restriccin.
Permanece por el tiempo que dure la transaccin.
Tiene dos modos Exclusive : Previene que un recurso sea compartido la primera
transaccin bloquea el recurso exclusivamente y Shared

18

Captulo 10 Creando y administrando tablas


Tabla
Vista
Secuencia
Index
Sinnimo

Unidad bsica de almacenamiento


Representan un subgrupo de datos de una o mas tablas
Genera valores para PK
Mejora performance
Da nombres alternativos a los objetos

El tamao de una tabla es definido por la cantidad de espacio asignado. El nombre


debe comenzar por una letra, 1-30 carcteres , A-Z, a-z, 0-9, _,$ y #
Create table
Se debe tener el privilegio CREATE TABLE, es un DDL estos tienen un efecto
inmedato en la BD y graban informacin en el diccionario de datos.
CREATE [ GLOBAL TEMPORARY ] TABLE [schema.]table
(column datatype [DEFAULT expr ] [, .... ]);
GLOBAL TEMPORARY : La tabla es temporal y su definicin es visible para todas
las sesiones, los datos de esta son visibles solo para la sesin que inserta datos.
DEFAULT expr : Especifica el valor por default si este es omitido en el INSERT,
expr puede ser un valor literal, expresin o una funcin SQL.
Hiredate DATE DEFAULT SYSDATE, ....
Un esquema es una coleccin de objetos, los objetos son estructuras lgicas que se
refieren directamente a datos en la BD, si la tabla no pertenece al usuario debe llevar
el prefijo del dueo.
Tablas en la BD Oracle
USER_
ALL_
DBA_
V$_ Vistas de performance dinamicas
Para las tablas del usuario USER_TABLES, objetos USER_OBJECTS, tablas, vistas,
sinnimos y secuencias USER_CATALOG CAT
Tipos de datos
LONG Longitud variable mximo 2G
CLOB Carcter single-byte maximo 4G
RAW y LONG RAW Datos binarios raw max 2000B
BLOB Datos binarios maximo 4G
BFILE Datos binarios max 4G
CREATE TABLE [ ( column1, column2, ... ) ]
AS subquery
Cuando se utilize una expresin se da un alias a la columna.
ALTER TABLE ADD|MODDIFY|DROP (column datatype [DEFAULT expr], ... )
Solo una columna puede ser borrada al tiempo.
ALTER TABLE table SET UNUSUED (column);
O
ALTER TABLE table SET UNUSUED column, column;
ALTER TABLE table DROP UNUSUED COLUMNS;

19
DROP TABLE table;
Los sinonimos permanecen pero son invalidos, cualquier transaccin pendiente es
commited, lo puede hacer el dueo o usuarios con grant DROP ANY TABLE.
Para cambiar el nombre de una tabla, vista, secuencia o sinnimo.
RENAME old_name TO new_name;
Truncando una tabla
Libera el espacio de almacenamiento usado por la tabla, DELETE no. No se puede
hacer ROLLBACK, lo hace el dueo o un usuario con el grant DELETE TABLE.
Adicionando comentarios
COMMENT ON TABLE table | COLUMN IS xxxxxxx; para consultar
ALL_COL_COMMENTS, USER_COL_COMMENTS, ALL_TAB_COMMENTS,
USER_TAB_COMMENTS.

20

Captulo 11 Incluyendo constraints


Forzan las reglas a nivel de tabla
Previenen el borrado de una tabla con dependencias
NOT NULL
UNIQUE
PRIMARY KEY
FOREIGN KEY
CHECK

:
: Especifica una columna o columnas cuyo valor debe ser unico

: Especifica una condicin que debe ser verdadera.

El nombre del constraint es por default SYS_Cn, se puede crear con la tabla o
despus, se hace a nivel de tabla o columna, son almacenados en diccionario de datos,
USER_CONSTRAINTS.
CREATE TABLE [schema.]table
(column datatype [DEFAULT expr]
[column constraint ],
....
[ table_constraint ] [, ... ]);
column_name datatype CONSTRAINT const_name NOT NULL...
UNIQUE KEY permite nulos a menos que se le especifique NOT NULL se puede
definir a nivel de tabla o columna, Oracle crea un indice unico
CREATE TABLE deptno ( deptno
NUMBER(2),
Dname
VARCHAR2(14),
CONSTRAINT dept_name_uk UNIQUE (dname));
CREATE TABLE deptno ( deptno
NUMBER(2),
Dname
VARCHAR2(14),
CONSTRAINT dept_name_pk PRIMARY KEY (deptno));
CREATE TABKE emp
(....
deptno NUMBER (2) CONSTRAINT emp_deptno_fk FOREIGN KEY (deptno )
REFERENCES dept(deptno),
.....
);
ON DELETE CASCADE permite el borrado en la tabla padre y las filas dependientes
en las tablas hijas.
CHECK no se puede usar CURRVAL, NEXTVAL, LEVEL y ROWNUM ni
llamadas a SYSDATE, UID, USER y USERENV, se pueden definir mas de uno por
columna a nivel de columna o de tabla.
ALTER TABLE table ADD [ CONSTRAINT constraint ] type (column );
Para adicionar constraint NOT NULL con MODIFY.
ALTER TABLE table DROP PRIMARY KEY | UNIQUE (column) |
CONSTRAINT constraint [CASCADE];
ALTER TABLE table DISABLE CONSTRAINT constraint [CASCADE];
Se puede deshabilitar un constraint en la creacin de una tabla o con un ALTER.
ALTER TABLE table ENABLE CONSTRAINT constraint;

21
Se se habilita UNIQUE o PRIMARY KEY un indice se crea automaticamente, un
constraint se puede habilitar en la creacin de la tabla o con ALTER.
CASCADE CONSTRAINTS
Se usa con DROP COLUMN, borra todos los constraints dependientes, borra
constraints multicolumnas.
USER_CONSTRAINTS, USER_CONS_COLUMNS.

22

Captulo 12 Creando vistas


Es una tabla lgica basada en una tabla o en otra vista, no contiene datos , se usan
para restringir acceso a los datos, para hacer consultas complejas fciles.
Hay 2 clasificaciones de vistas simples y complejas.
CREATE VIEW [OR REPLACE] [FORCE | NOFORCE] VIEW view
[ (alias, ....) ]
AS subquery
[WITH CHECK OPTION [CONSTRAINT constraint]]
[WITH READ ONLY ];
El subquery puede ser complejo, no puede contener ORDER BY.
FORCE crea la vista indiferentemente si existe o no la tabla.
WITH CHECK OPTION Especifica que solo filas accequibles por la tabla pueden ser
actualizadas o insertadas.
Se pueden usar alias en el subquery.
En USER_VIEWS , la sentencia SELECT esta en una columna LONG.
Se puede hacer operaciones DML en vistas simples, no se puede remover una fila si
contiene : funciones de grupo, GROUP BY , DISTINCT, ROWNUM.
No se puede modificar una vistas si cumple con lo anterior, columnas definidas por
expresiones.
No se puede adicionar si cumple con lo anterior, hay columnas NOT NULL en las
tablas base que no son seleccionadas por la vista.
Usando WITH CHECK OPTION
Asegura que los DML en la vista permanezcan dentro del dominio de la vista
Se puede forzar constraints a nivel de BD.
DROP VIEW view;
Solo el dueo o quien tenga DROP ANY VIEW.
Inline views
Es una subconsulta con un alias que se pued usar dentro de la sentencia SQL, no es
un objeto del esquema.
SELECT a.ename, b.maxsal
FROM emp a,(SELECT deptno, max(sal) maxsal FROM emp GROUP BY deptno) b
WHERE a.deptno = b.deptno
Analisis TOP-N
SELECT [column_list], ROWNUM
FROM (SELECT [column_list] FROM table ORDER BY top_N_column)
WHERE ROWNUM<= N;
ROWNUM asigna un valor a cada columna iniciando con 1.
En la clausula WHERE la cual especifica n filas a ser retornadas, debe usar < o <=.

23

Captulo 13 Otros objetos de BD


Que es una secuencia
Automticamente genera nmeros unicos, es compartida, se usa generalmente para
crear valores de llave primaria, reemplaza cdigo de la aplicacin, veloz acceso
cuando esta en cache.
CREATE SQUENCE squence
[INCREMENT BY n ]
[START WITH n ]
[{MAXVALUE n | NOMAXVALUE}]
[{MINVALUE n | NOMINVALUE} ]
[{CYCLE | NOCYCLE}]
[{CACHE n | NOCACHE}]
CACHE n | NOCACHE : Especifica cuantos valores sern preasignados y colocados
en memoria (Por default 20 valores ).
USER_SECUENCES, la columna LAST_NUMBER despliega el proximo nmero
disponible de la secuencia.
Sequence.NEXTVAL : Retorna el proximo nmero disponible, retorna un unico valor
cada vez que es llamado, sequence.CURRVAL :Retorna el vlor corriente de la
secuencia NEXTVAL debe ser usado antes de que CURRVAL contenga un valor.
Pueden ser usados :
En la lista de un SELECT que no es parte de un subquery
En la lista de un SELECT de un subquery de un INSERT
En la clausula VALUES
En la clusula SET de un UPDATE
No se pueden usar :
Una lista de un SELECT de un vista
Un SELECT con DISTINCT
Un SELECT con GROUP BY, HAVING o ORDER BY
Un subquery de un SELECT, DELETE o UPDATE
Una expresin por default en CREATE TABLE o ALTER TABLE
Saltos en la secuencia se pueden dar cuando hay ROLLBACK, falla del sistema la
secuencia es usada en otra tabla.
Se puede ver el proximo valor disponible de la secuencia en USER_SEQUENCES si
fue creada NOCACHE.
Modificando una secuencia
Se puede cambiar el valor de incremento, mximo, minimo, ciclo y cache.
ALTER SEQUENCE squense
[INCREMENT BY n]
[{MAXVALUE n | NOMAXVALUE}]
[{MINVALUE n | NOMINVALUE}]
[{CYCLE | NOCYCLE}]
[{CACHE n | NOCACHE}]
Se debe ser el dueo o tener el GRANT ALTER ANY SEQUENCE.
DROP SEQUENCE sequence; El dueo o tener DROP ANY SEQUENCE.

24
Que es un indice
Es un objeto, acelera la recuperacin de filas, reduce I/O utilizando un metodo de
acceso de camino rapido, es independiente de la tabla, es mantenido por el servidor.
Automticos : PK, UNIQUE
Manuales : no unicos creados por el usuario
CREATE INDEX index ON table (column,[column,...]);
Se crea cuando la columna es frecuentemente usada en el WHERE, la columna
cintiene un amplio rango de valores, contiene un gran nmero de valores NULL, la
tabla es grande y la mayoria de los querys esperan del 2-4% de las filas.
No se deben usar cuando la tabla es actualizada frecuentemente y las inversas de lo
anterior.
USER_INDEXES, USER_IND_COLUMNS.
Indices basados en funcin.
Es un indice basado en expresiones, la expresin se construye con columnas,
constantes, funciones SQL y funciones definidas por el usuario.
CREATE INDEX index ON table (expr)
Para asegurarse de que se usa el indice debe aasegurarse que el valor de la funcin es
NOT NULL.
SELECT * FROM emp WHERE UPPER(ename) IS NOT NULL;
DROP INDEX; El dueo o tener DROP ANY INDEX;
Sinonimos
Simplifica el acceso a los objetos, el objeto no puede estar contenido en un paquete.
CREATE SYNONYM [PUBLIC] FOR object;
DROP SYNONYM synonym;
Solo el DBA borra sinonimos publicos.

25

Captulo 14 Controlando acceso a los usuarios


Se tiene seguridad del sistema y seguridad de los datos.
Los privilegios del sistema dan acceso a la BD. Hay mas de 80.
CREATE USER, DROP USER, DROP ANY TABLE, BACKUP ANY TABLE.
CREATE USER user IDENTIFIED BY password;
GRANT privilege [, privilege, ... ] TO user;
Un desarrollador puede tener CREATE SESSION para conectarse, CREATE
TABLE, CREATE SEQUENCE, CREATE VIEW, CREATE PROCEDURE.
Role
Grupo de privilegios relativos que pueden ser concedidos al usuario.
CREATE ROLE role;
ALTER USER user IDENTIFIED BY new_pwd; Se debe tener el privilegio ALTER
USER.
Un grant para el sinonimo es convertido en un grant para la tabla base referenciada
por el sinonimo.
GRANT object_priv [(columns)] ON object TO [USER | role | PUBLIC]
[WITH GRANT OPTION];
WITH GRANT OPTION se revoca en cascada

ROLE_SYS_PRIVS
Privilegios del sistema concedidos a los roles
ROLE_TAB_PRIVS
Privilegios de las tablas concedidos a los roles
USER_ROLE_PRIVS
Roles accesibles por el usuario
USER_TAB_PRIVS_MADE Privilegios de objeto concedidos a los objetos del
usuario
USER_TAB_PRIVS_RECD Privilegios de objeto concedidos al usuario
USER_COL_PRIVS_MADE Privilegios de objeto concedido a las columna de los
objetos del usuario
USER_COL_PRIVS_RECD Privilegios de objeto concedidos al usuario en columnas
especificas
REVOKE {privilege [, privilege ...] | ALL} ON object FROM {user [,user...] | role |
PUBLIC} [ CASCADE CONSTRAINTS ];
CASCADE CONSTRAINTS : Remueve cualquier constraint de integridad
referencial hechos al objeto por medio de REFERENCES

26

Captulo 16 Declarando variables


PL/SQL es una extensin de SQL con carctersticas de lenguaje de programacin,
brinda integracin, mejora performance, PL/SQL puede ser usado como un grupo de
sentencias SQL dentro de un solo bloque y lo envian al servidor en una sola llamada,
reduciendo tambien trafico en la red.
PL/SQL puede cooperar con herramientas de desarrollo como Developer, Forms y
Reports, adicionando procesamiento procedimental.
Estructura de bloque PL/SQL que es estructurado por bloques.
DECLARE
xxxxxxxxxxxxxxxxx
BEGN
xxxxxxxxxxxxxxxxx
EXCEPTION
xxxxxxxxxxxxxxxxx
END;
Tipos de bloques
Annimos : no tienen nombre, se puede envolver un bloque annimo dentro de un
programa precompilado y dentro de SQL*Plus o server manager. Triggers en Oracle
Developer.
Subprogramas : Procedimientos y funciones, toman parametros y pueden ser
invocados
Funcin o procedimiento de aplicacin : Bloque PL/SQL con nombre almacenado
en una aplicacin desarrollada por Oracle o en una librera compartida que puede
aceptar parmetros y puede ser invocada repetidamente.
Uso de variables : Para almacenamiento temporal, manipulacin de valores,
reusabilidad y fcil mantenimiento %ROWTYPE, %TYPE
Las variables se declaran en la seccin declarativa, se asignan en la seccin
ejecutable, se pueden pasar a los procedimientos como IN, OUT, IN OUT
Tipos de variables :
Scalar : Sostienen un solo valor
Tipos de datos compuestos : Registros
Tipos de datos de referencia
Lob
Variables de tipo no PL/SQL incluyen variables del host declaradas en programas
precompilados. Campos de pantalla en formas y variables del host en SQL*Plus.

Identifier [CONSTANT] datatype [NOT NULL] [ := | DEFAULT expr]


Una constante debe ser inicializada en su declaracin.
Las variables no deben llevar el mismo nombre de las columnas de un tabla.
SELECT empno
INTO empno
FROM emp;
Las variables se asiganan con := , INTO o FETCH
G_mgr NUMBER(4) DEFAULT 1334;

27
V_location VARCHAR2(13) NOT NULL := CHICAGO;

Tipos de datos escalares


Tienen un solo valor y no tienen componentes internos, pueden ser clasificados en 4
categorias nmero (integer, positive), carcter, boolean y date
Varchar2
32,767B
Date
4712 B.C 9999 A.D
Long
Carcter
Long Raw
Datos binarios no es interpretada por PL/SQL
Binary_integer
%TYPE declara la variable de acuerdo a una columna u otra variable previamente
declarada. Es fcil de mantener si se hacen cambios a nivel de BD.
V_ename
V_balan
V_min

emp.ename%TYPE;
NUMBER(7,2);
v_balan%TYPE;

NOT NULL no aplica a variables declaradas con %TYPE.


Eb variables booleanas expresiones aritmticas pueden ser usadas para retornar un
valor booleano.
V_com BOOLEAN := (v_sal1 < v_sal2);
Tipos de datos compuestos : TABLE referencia y manipula colecciones de datos
como un objeto, RECORD trata tipos de datos relacionados pero disimilares como
una unidad lgica, NESTED TABLE y VARRAY
LOB : Almacena bloques de datos sin estructura 4GB
CLOB almacena grandes bloques de carcteres single-byte
BLOB objetos binarios on-line/off-line
BFILE
NCLOB single-byte o fixed-width multibyte in line o out of line.
Variables BIND
Se declara en el ambiente del host y se usa para pasar valores runtime, para ser
pasadas a uno o mas programas PL/SQL a menos que sean procedimientos, funciones
o paquetes, esto incluye variables decalradas en programas precompilados , campos
de pantalla
Para declararlas en el ambiente SQL*Plus
VARIABLE ret NUMBER
VARIABLE ret VARCHAR2(30)
Para desplegarlas
PRINT ret (no pude ser usado en un bloque PL/SQL)
Para referenciarlas
Con (:) como prefijo asi.
VARIABLE g_mon NUMBER
DECLARE
BEGN
:g_mon := 12;
END;

28
DBMS_OUTPUT.PUT_LINE alternativa para desplegar datos en un bloque
PL/SQL, se debe habilitar SQL*Plus con SET SERVER OUTPUT ON
mbito y visibilidad de variables
La variable ser local para el bloque en el que ha sido declarada y global para los
bloque hijos de ste, mientras que las variables declaradas en los bloque hijos no son
globales a los bloques padre.

<<l_Outer>>
DECLARE
v_AvailableFlag BOOLEAN;
v_SSN
NUMBER(9);
BEGIN
1
DECLARE
v_SSN
CHAR(11);
v_StartDate DATE;
BEGIN
2

v_AvailableFlag y
v_SSN son visibles

v_AvailableFlag, v_SSN CHAR(11) y


V_StartDate son visibles. Si queremos
acceder a v_SSN NUMBER(9) debemos
usar l_Outer.v_SSN.

END;
3
END;

v_AvailableFlag y
v_SSN son visibles

Subtipos definidos por el usuario


Un subtipo es un tipo PL/SQL que se basa en otro tipo existente. Los subtipos pueden
emplearse para dar nombres alternativos a un tipo. La sintaxis es:
SUBTYPE nuevo_tipo IS tipo_original;
donde nuevo_tipo es el nombre del nuevo subtipo y tipo_original designa el tipo
base. ste puede ser un tipo predefinido o un subtipo o una referencia %TYPE. Por
ejemplo:
DECLARE
SUBTYPE t_LoopCounter IS NUMBER; -- Define el nuevo subtipo
v_LoopCounter
t_LoopCounter;
-- Declara una variable
subtipo

del

SUBTYPE t_NameType IS students, first_name%TYPE;


La definicin del subtipo no puede ser restringida de modo directo. El siguiente
bloque sera ilegal:
DECLARE
SUBTYPE t_LoopCounter IS NUMBER(4);

-- Restriccin incorrecta

Sin embargo, hay una forma de evitar esta limitacin, declarando una variable ficticia
del tipo deseado (con la restriccin) y utilizando %TYPE en la definicin del subtipo:
DECLARE
v_DummyVar
NUMBER(4);
--Variable ficticia que no se usa
SUBTYPE t_LoopCounter IS v_DummyVar%TYPE;
-- Devuelve
NUMBER(4)
v_Counter
t_LoopCounter;
-- Declara una variable del subtipo

29
Las declaraciones de variables de un subtipo no restringido tambin pueden
restringir el tipo:
DECLARE
SUBTYPE t_Numeric IS NUMBER;
restringido
v_Counter is t_Numeric(5);

--

Define

un

subtipo

-- y una variable restringida

Los subtipos se consideran de la misma familia que el tipo base.

no

30

Captulo 17 Escribiendo sentencias ejecutables


Las unidades lxicas pueden estar separados por Espacios, delimitadores (+,-,=..),
identificadores, literales y comentarios.
Identificadores
Pueden contener 30 letras, deben comenzar con una letra, no palabaras reservadas a
menos que se encierren entre comillas, no puede tener el mismo nombre de una
columna de una tabka de la BD.
Literales Es un nmero, carcter, cadena o valor booleano no representado por un
identificador
Carcteres y fechas deben ir encerrados entre comillas
Nmeros pueden ir solos o en notacin cientfica (2E5)
Un bloque PL/SQL termina con /
Para comentar una sola lneas ( - -) varias lneas (/* */)
Funciones SQL en PL/SQL
Numricas de una sola fila
De carcter de una sola fila
Conversin
Date
PL/SQL funciones
Reporte de errores
miscellaneous
No disponibles DECODE o funciones de grupo (SUM,MAX,MIN ....)
CHR(10) Convierte el cdigo ASCII a su correspondiente carcter
Bloques anidados
Sentencias pueden estar anidadas donde quiera que una sentencia es permitida
Un bloque anidado comienza con una sentencia
La seccin de excepciones puede contener bloques anidados
El alcanc de un objeto es la regin donde puede ser referenciado, aplica a todos los
objetos declarados incluyendo variables, cursores, excepciones definidas por el
usuario y constantes.
Operadores en PL/SQL
Las operaciones se hacen en orden de acuerdo a la precedencia tenemos operadores
Lgicos
Aritmticos
Concatenacin
Parntesis
Operador exponencial (**)
Guias de programacin
Identar cdigo
Documentar con comentarios
Convenciones de nombres para identificadores y otros objetos

31

Captulo 18 Interactuando con el servidor Oracle


Sentencias SQL en PL/SQL
Usando SELECT solo un grupo de valores puede ser retornado, se hace cambios en
las filas con DML, control de transacciones con COMMIT, ROLLBACK o
SAVEPOINT.
PL/SQL no es una unidad transaccional, no soporta DDL, DCL tal como GRANT o
REVOKE.
SELECT select_list
INTO {variable_name [ , variable_name, ...]
| record_name }
FROM table
WHERE condition;
INTO es obligatoria para variables de PL/SQL o del host.
Funciones de grupo no pueden ser usadas en PL/SQL solo en SQL.
Para manipular datos con DML en PL/SQL con DELETE, INSERT, UPDATE,
COMMIT o ROLLBACK.
Insertando datos no hay posibilidad de ambigedad con los identificadores y los
nombres de las columnas, cualquier identificador en el INSERT debe ser un nombre
de una columna de la BD.
La asignacin en PL/SQL siempre con := en SQL =.
Para evitar ambigedad en el WHERE columnas e la BD e identificadores deben
tener nombres diferentes, los errores de sintaxis pueden darse debido a que PL/SQL
chequea primero la BD para ver si es una columna.
No hay posibilidad de ambigedad en el SELECT ni en el FROM.
COMMIT y ROLLBACK
La transaccin inicia con el primer comando DML despus de un COMMIT o un
ROLLBACK.
COMMIT o ROLLBACK se usan para terminar explcitamente la transaccin.
COMMIT [WORK];
SAVEPOINT savepoint_name;
ROLLBACK [WORK];
ROLLBACK [WORK] TO [SAVEPOINT] savepoint_name;
Cursores SQL : Es un rea privada de memoria hay 2 tipos implcitos utilizados por
el servidor para parsear y ejecutar SQL y explcitos creados por el programador.
Usando atributos de cursor SQL , se puede verificar la salida.
SQL%ROWCOUNT Nmero de filas afectadas
SQL%FOUND atributo booleano especifica que fueron afectadas filas
SQL%NOTFOUND
SQL%HISOPEEN siempre es falso debido a que PL/SQL cierra los cursores
implcitos inmedatamente despus de haber sido ejecutados.
Ejecutando SQL dentro de bloques PL/SQL
PL/SQL es un lenguaje de programacin de base de datos. Casi todos los programas
que escribiremos en PL/SQL leern desde, o escribirn en, una base de datos Oracle
utilizando SQL. Aunque estas series asumen que se conoce SQL, debemos estar
conscientes de la forma en que llamamos a las sentencias desde un bloque PL/SQL.

32
Y aqu hay algunas buenas noticias: Oracle hace que sea muy fcil escribir y
ejecutar sentencias SQL en PL/SQL. La mayor parte de las veces, simplemente
escribiremos las sentencias SQL directamente en nuestro bloque PL/SQL y despus
agregaremos el cdigo necesario para la interfaz entre las sentencias SQL y el cdigo
PL/SQL.
Supongamos, por ejemplo, que tenemos una tabla llamada empleados, con una
columna clave primaria id_empleado, y una columna apellido. Podemos ver el
apellido del empleado con ID 138, como sigue:
SELECT apellido
FROM empleados
WHERE id_empleado = 138

Ahora querramos ejecutar esta misma consulta dentro de nuestro bloque PL/SQL y
desplegar el nombre. Para hacer esto, necesitaremos copiar el apellido desde la
tabla a una variable local, lo cual podemos hacer con la clusula INTO:
DECLARE
v_apellido empleados.apellido%TYPE;
BEGIN
SELECT apellido
INTO v_apellido
FROM empleados
WHERE id_empleado = 138;
DBMS_OUTPUT.put_line(v_apellido);
END;

Primero declaramos una variable local, y haciendo esto introducimos otra


carcterstica elegante de PL/SQL: la capacidad de fijar el tipo de datos de nuestra
variable en funcin del tipo de datos de una columna en una tabla (esto ser
profundizado ms adelante en esta serie)
Despus ejecutamos una consulta contra la base, obteniendo el apellido del empleado
y asignndolo directamente en la variable v_apellido.
Por supuesto, querremos hacer ms que ejecutar sentencias SELECT en PL/SQL,
tambin querremos insertar, modificar y eliminar datos desde PL/SQL. Aqu hay
ejemplos de cada uno de esos tipos de sentencias DML:
Eliminamos todos los empleados en el departamento 10 y mostramos cuntas tuplas
fueron eliminadas:
DECLARE
v_id_departamento empleados.id_departamento%TYPE := 10;
BEGIN
DELETE FROM empleados
WHERE id_departamento = v_id_departamento;
DBMS_OUTPUT.put_line(SQL%ROWCOUNT);
END;

Referenciamos la variable PL/SQL directamente dentro de la sentencia DELETE.


Cuando el bloque se ejecuta, la variable se reemplaza con el valor actual, 10, y el
DELETE es ejecutado por el motor de SQL. SQL%ROWCOUNT es un atributo
especial de cursor que retorna el nmero de tuplas modificadas por la ltima
sentencia DML ejecutada en nuestra sesin.
Modificar todos los empleados en el departamento 10 con un 20% de incremento
salarial.
DECLARE

33
v_id_departamento empleados.id_departamento%TYPE := 10;
BEGIN
UPDATE empleados
SET salario = salario * 1.2
WHERE id_departamento = v_id_departamento;
DBMS_OUTPUT.put_line(SQL%ROWCOUNT);
END;

Insertar un nuevo empleado en la tabla.


BEGIN
INSERT INTO empleados (id_empleado
, apellido
, id_departamento
, salario)
VALUES (100
, 'Feuerstein'
, 10
, 200000);
DBMS_OUTPUT.put_line(SQL%ROWCOUNT);
END;

En este bloque, provemos los valores de las columnas como literales, en lugar de
variables, directamente dentro de la sentencia SQL.

34

Captulo 19 Escribiendo estructuras de control


Se puede controlar el flujo lgico de las sentencias usando condicionales IF y LOOP
IF THEN END IF
IF THEN ELSE END IF
IF THEN ELSIF END IF
IF condicin THEN
Sentencias;
[ELSIF condicin THEN
sentencias;]
[ELSE
sentencias;]
END IF;
Condicin : Es una variable o expresin booleana.
THEN : Asocia la condicin con la secuencia de sentencias que la siguen
Si la condicin es falsa o NULL no se ejecutan las sentencias.
En IF anidados, estos deben terminar con su correspondiente END IF;
Es preferible usar ELSIF que IF anidados.
Se puede manejar valores NULL con IS NULL
Una expresin aritmtica que contenga nulos se vuelve nula.
En la concatenacin el null es tratado como un espacio vacio.
NULL AND FALSE = FALSE
NULL OR TRUE = TRUE
NOT NULL = NULL
Sentencias LOOP
LOOP basico
For loop : control iterativo basado en un contador
While loop : control iterativo basado en una condicin
Exit : Termina un loop
LOOP
Sentencias;
EXIT [WHEN condicin];
END LOOP;
LOOP FOR
FOR contador in [REVERSE]
Lower_bound..upper_bound LOOP
Ssentencias;
END LOOP;
El rango pueden ser literales, variables, expresiones.
Se referencia el contador dentro del loop solo si es indefinido fuera de este.
WHILE LOOP
WHILE condicin LOOP
Sentencias;
END LOOP;
Se repite mientras la condicin sea TRUE. Si la condicin es NULL el loopes pasado.

35
Los loops se pueden anidar , se puede usar labels para distiguir entre loops
(<<label>>) se colocan antes de LOOP, se puede salir del loop con EXIT
referenciando el label, el label se puede incluir en el END LOOP por claridad
BEGIN
<<outer_loop>>
LOOP
EXIT WHEN v_count > 10
<<inner_loop>>
LOOP
EXIT outer_loop WHEN total = YES
EXIT inner_loop WHEN inner_done = YES
END LOOP inner_loop;
END LOOP outer_loop;
END;

36

Captulo 20 Trabajando con tipos de datos


compuestos
Registros PL/SQL
Tablas PL/SQL
Nested tables
Varray
Contienen componentes internos son reusables, es utiliza el RECORD para tratar
datos dissimilares como una unidad lgica, se usa TABLE para referenciar y
manipular colecciones de datos como un objeto.
Un registro es un grupo de datos relacionados almacenados en campos, que tienen su
nombre y su tipo de datos, una tabla contiene columnas y su llave primaria.
Son convenientes para sacar filas de datos de una tabla para procesamiento.
A los registros se les pueden asignar valores iniciales o definirlos como NOT NULL,
hay registros anidados.
TYPE type_name IS RECORD
{ field_declaration [,field_declaration...]};
Field_declaration field_name { field_type | variable%TYPE | table.column%TYPE |
table%ROWTYPE }
[ [NOT NULL] {:= DEFAULT } expr ]
Para referenciar los campos de un registro: record_name.field_name, su alcanze es
en el bloque o subprograma donde fue definido.
El atributo %ROWTYPE
Declara una variable de acuerdo a una coleccin de columnas en una tabla o vista de
la BD
DECLARE
Emp_record emp%ROWTYPE;
Ventajas de usar ROWTYPE
Desconocimiento de los campos de una tabla
Los campos cambian runtime
DECLARE
emp_rec emp%ROWTYPE;
BEGIN
SELECT * INTO emp_rec
FROM emp;
END;
Tablas PL/SQL
Tienen dos componentes * PK de tipo de datos BINARY_INTEGER, * columnas
escalaras o tipo de dato de registro.
Se incrementa dinmicamente. Son similares a un arreglo
TYPE type_name IS TABLE OF
{column_type | variable%TYPE | table.column%TYPE} [NOT NULL]
[INDEX BY BINARY_INTEGER]
TYPE ename_table_type IS TABLE OF emp.ename%TYPE
INDEX BY BINARY_INTEGER;
Ename_table ename_table_type;
No pueden ser incializadas en su declaracin. Se referencian
pl_sql_table_name(primary_key_values), la PK puede ser negativa

37
Usando metodos de tablas PL/SQL
Table_name.method_name[(parameters)]
EXISTS(n)
COUNT
FIRST
LAST
PRIOR(n)
NEXT(n)
EXTEND(n,i) *

TRIM *
DELETE

Retorna TRUE si el elemento en la posicin existe


Nmero de elementos de una tabla PL/SQL
Retorna el primero y el ultimo nmero de indice, NULL si esta
vacia
Retorna nmero de indice que precede al indice n
Retorna nmero de indice que sucede al indice n
Incrementa el tamao de la tabla
EXTEND agrega un elemento nulo
EXTEND(n) agrega n elementos nulos
EXTEND(n,i) agrega n copias de el elemento i
remueve un elemento del final
TRIM(n) remueve n elementos del final
Remueve todos los elementos de la tabla
DELETE(n) remueve el elemento n
DELETE(m,n) Remueve elemenetos en el rango m..n

Para referirse a los elementos de una tabla


Table(index).campo

38

Captulo 21 Escribiendo cursores explcitos


El servidor implcitamente abre un cursor para procesar sentencias SELECT no
asociadas con un cursor explcito.
Cursores Implcitos
Los cursores implcitos se utilizan para realizar consultas SELECT que devuelven
un nico registro.
Deben tenerse en cuenta los siguientes puntos cuando se utilizan cursores
implcitos:

Con cada cursor implcito debe existir la palabra clave INTO.


Las variables que reciben los datos devueltos por el cursor tienen que contener
el mismo tipo de dato que las columnas de la tabla.
Los cursores implcitos solo pueden devolver una nica fila. En caso de que se
devuelva ms de una fila (o ninguna fila) se producir una excepcin. No se
preocupe si an no sabe que es una excepcin, le valdr conocer que es el
medio por el que PL/SQL gestiona los errores.

El siguiente ejemplo muestra un cursor implcito:


declare
vdescripcion VARCHAR2(50);
begin
SELECT DESCRIPCION
INTO vdescripcion
from PAISES
WHERE CO_PAIS = 'ESP';
dbms_output.put_line('La lectura del cursor es: ' ||
vdescripcion);
end;

La salida del programa generara la siguiente lnea:


La lectura del cursor es: ESPAA

Excepciones asociadas a los cursores implcitos.


Los cursores implcitos slo pueden devolver una fila, por lo que pueden producirse
determinadas excepciones. Las ms comunes que se pueden encontrar son
no_data_found y too_many_rows. La siguiente tabla explica brevemente estas
excepciones.
Excepcin
Explicacin
NO_DATA_FOUND Se produce cuando una sentencia SELECT intenta recuperar datos
pero ninguna fila satisface sus condiciones. Es decir, cuando "no hay
datos"
TOO_MANY_ROWS Dado que cada cursor implcito slo es capaz de recuperar una fila ,
esta excepcin detecta la existencia de ms de una fila.

Cursores explcitos
Procesa cada fila retornada por un SELECT de multiples filas. El grupo de filas
retornado es llamdo grupo activo, se guarda un rastro de cual es la fila corriente, el
programador lo controla manualmente.
Se usa OPEN ejcuta el query asociado, identifica el grupo activo y la posicin del
cursor , FETCH recupera la fila corriente y avanza el cursor a la proxima fila,
CLOSE deshabilita el cursor y libera lass filas.
CURSOR cursor_name IS
Select_statement;

39
Abriendo el cursor
OPEN cursor_name;
Dinamicamente asigna memoria para el rea de contexto, Parsea el SELECT, obtiene
posiciones de memoria de las variables de entrada, identifica el grupo activo,
posiciona el puntero justamente antes de la primera fila.
Si no retorna filas no se da una excepcin , perso se puede probar la salida con los
atributos del cursor.
Para cursores declarados FOR UPDATE, se bloquean las filas.
FETCH cursor_name INTO [variable1, ... | record_name ];
Recupera la fila corriente dentro de variables, incluye el mismo nmero de variables,
se debe probar el curosr para ver si contiene filas.
...
Open defined_cursor;
LOOP
FETCH defined_cursor INTO defined_variables;
EXIT WHEN ....;
END LOOP;
...
CLOSE cursor_name;
Se debe cerrar para liberar recursos, esta ligado con el parmetro OPEN_CURSORS.
Atributos : %ISOPEN , %NOTFOUND, %FOUND, %ROWCOUNT nmero de
filas que trae el cursor.
Toman los valores TRUE, FALSE o NULL dependiendo de la situacin:
Atributo
%NOTFOUND
%FOUND
%ISOPEN
%ROWCOUNT

Antes de abrir
ORA-1001
ORA-1001
FALSE
ORA-1001

Al
abrir
NULL
NULL
TRUE
0

Durante la
recuperacin
FALSE
TRUE
TRUE
*

Al finalizar la
recuperacin
TRUE
FALSE
TRUE
**

Despus de
cerrar
ORA-1001
ORA-1001
FALSE
ORA-1001

* Nmero de registros que ha recuperado hasta el momento


** Nmero de total de registros

Para procesar diferentes filas de un cursor de usa un LOOP.


FETCH emp_cursor INTO v_empno;
EXIT WHEN emp_cursor%NOTFOUND OR emp_cursor%NOTFOUND IS NULL;
IS NULL es para asegurarse asi si el FETCH nunca se ejecuta no habra problemas.
Se puede crear registros basados en las filas de un cursor.
DECLARE
CURSOR em IS
SELECT empno, ename
FROM emp;
Emp_record em%ROWTYPE;
BEGIN
OPEN em;
FETCH em INTO emp_record;
END;
Cursor para LOOPS
FOR record_name IN cursor_name LOOP
Sentencias;
END LOOP;

40
Hay implicitamente OPEN, FECTH y CLOSE. y el cursor es implcitamente
declarado.
Cursores en LOOPS que usan subqueries
No se necesita declarar el cursor, y no puede usar los atributos de cursor.
BEGIN
FOR em IN ( SELECT empno FROM emp )
LOOP
Sentencias;
END LOOP;
END;
El siguiente ejemplo ilustra el trabajo con un cursor explcito. Hay que tener en
cuenta que al leer los datos del cursor debemos hacerlo sobre variables del mismo
tipo de datos de la tabla (o tablas) que trata el cursor.
DECLARE
CURSOR cpaises
IS
SELECT CO_PAIS, DESCRIPCION, CONTINENTE
FROM PAISES;
co_pais VARCHAR2(3);
descripcion VARCHAR2(50);
continente VARCHAR2(25);
BEGIN
OPEN cpaises;
FETCH cpaises INTO co_pais,descripcion,continente;
CLOSE cpaises;
END;

Podemos simplificar el ejemplo utilizando el atributo de tipo %ROWTYPE sobre


el cursor.
DECLARE
CURSOR cpaises
IS
SELECT CO_PAIS, DESCRIPCION, CONTINENTE
FROM PAISES;
registro cpaises%ROWTYPE;
BEGIN
OPEN cpaises;
FETCH cpaises INTO registro;
CLOSE cpaises;
END;

El mismo ejemplo, pero utilizando parmetros:


DECLARE
CURSOR cpaises (p_continente VARCHAR2)
IS
SELECT CO_PAIS, DESCRIPCION, CONTINENTE
FROM PAISES
WHERE CONTINENTE = p_continente;
registro cpaises%ROWTYPE;
BEGIN
OPEN cpaises('EUROPA');
FETCH cpaises INTO registro;
CLOSE cpaises;
END;

Cuando trabajamos con cursores debemos considerar:

Cuando un cursor est cerrado, no se puede leer.


Cuando leemos un cursor debemos comprobar el resultado de la lectura
utilizando los atributos de los cursores.

41

Cuando se cierra el cursor, es ilegal tratar de usarlo.


Es ilegal tratar de cerrar un cursor que ya est cerrado o no ha sido abierto

Cursores de actualizacin
Los cursores de actualizacin se declaran igual que los cursores explcitos,
aadiendo FOR UPDATE al final de la sentencia select.
CURSOR nombre_cursor IS
instruccin_SELECT
FOR UPDATE

Para actualizar los datos del cursor hay que ejecutar una sentencia UPDATE
especificando la clusula WHERE CURRENT OF <cursor_name>.
UPDATE <nombre_tabla> SET
<campo_1> = <valor_1>
[,<campo_2> = <valor_2>]
WHERE CURRENT OF <cursor_name>

El siguiente ejemplo muestra el uso de un cursor de actualizacin:


DECLARE
CURSOR cpaises IS
select CO_PAIS, DESCRIPCION, CONTINENTE
from paises
FOR UPDATE;
co_pais VARCHAR2(3);
descripcion VARCHAR2(50);
continente VARCHAR2(25);
BEGIN
OPEN cpaises;
FETCH cpaises INTO co_pais,descripcion,continente;
WHILE cpaises%found
LOOP
UPDATE PAISES
SET CONTINENTE = CONTINENTE || '.'
WHERE CURRENT OF cpaises;
FETCH cpaises INTO co_pais,descripcion,continente;
END LOOP;
CLOSE cpaises;
COMMIT;
END;

Cuando trabajamos con cursores de actualizacin debemos tener en cuenta las


siguientes consideraciones:

Los cursores de actualizacin generan bloqueos en la base de datos.

42

Captulo 23 Manejando excepciones


Manejando excepciones con PL/SQL
Una excepcin es un identificador que se alcanza durante la ejecucin cuando ocurre
un error Oracle o cuando se alcanza explcitamente terminando asi las acciones en el
cuerpo principal, se puede manejar atrapndola en un manejador realizando las
acciones finales o propagandola al ambiente llamado.
Se puede alcanzar la excepcin explcitamente usando RAISE.
Al atrapar una excepcin el procesamiento pasa al manejador de excepciones, si se
maneja exitosamente la excepcin, entonces la excepcin no se propaga y el bloque
PL/SQL termina con xito. Si no el bloque PL/SQL falla y la excepcin es propagada
al ambiente que fue llamada.
Tipos de excepciones
Predefinidas por Oracle : Aproximadamente 20 errores
No predefinidas por Oracle : Cualquier otro error estandar de Oracle
Definidas por el usuario : Condicin que el desarrollador define como anormal
Atrapando excepciones
EXCEPTION
WHEN exception1 [OR exception2 ... ] THEN
Sentencias;
[ WHEN exception3 [ OR exception4 ... ] THEN
sentencias;
]
[ WHEN OTHERS THEN
sentencias;
]
Se puede atrapar cualquier error incluyendo la rutina correspondiente en el
manejador de excepciones, cada manejador consiste de una clausula WHEN.
OTHERS atrapa las excepciones no definidas y por esto es la ultima excepcin
definida en el manejador. Solo un manejador es procesado antes de salir del bloque.
Atrapando errores predefinidos
Referenciar el nombre estndar en la rutina de manejo de excepciones.
La siguiente es la lista de las excepciones predeterminadas por PL/SQL y una breve
descripcin de cundo son accionadas:
Excepcion
ACCESS_INTO_NULL
COLLECTION_IS_NULL

CURSOR_ALREADY_OPEN

DUP_VAL_ON_INDEX

INVALID_CURSOR
INVALID_NUMBER

Se ejecuta ...
SQLCODE
El programa intent asignar valores a los
-6530
atributos de un objeto no inicializado
El programa intent asignar valores a una
-6531
tabla anidada an no inicializada
El programa intent abrir un cursor que ya se
encontraba abierto. Recuerde que un cursor de
-6511
ciclo FOR automticamente lo abre y ello no
se debe especificar con la sentencia OPEN
El programa intent almacenar valores
duplicados en una columna que se mantiene
-1
con restriccin de integridad de un ndice
nico (unique index)
El programa intent efectuar una operacin
-1001
no vlida sobre un cursor
En una sentencia SQL, la conversin de una
cadena de carcteres hacia un nmero falla
-1722
cuando esa cadena no representa un nmero

43
vlido
El programa intent conectarse a Oracle con
LOGIN_DENIED
un nombre de usuario o password invlido
Una sentencia SELECT INTO no devolvi
valores o el programa referenci un elemento
NO_DATA_FOUND
no inicializado en una tabla indexada
El programa efectu una llamada a Oracle sin
NOT_LOGGED_ON
estar conectado
PL/SQL tiene un problema interno
PROGRAM_ERROR
Los elementos de una asignacin (el valor a
asignar y la variable que lo contendr) tienen
tipos incompatibles. Tambin se presenta este
ROWTYPE_MISMATCH
error cuando un parmetro pasado a un
subprograma no es del tipo esperado
El parmetro SELF (el primero que es pasado
SELF_IS_NULL
a un mtodo MEMBER) es nulo
La memoria se termin o est corrupta
STORAGE_ERROR
El programa est tratando de referenciar un
elemento de un arreglo indexado que se
SUBSCRIPT_BEYOND_COUNT
encuentra en una posicin ms grande que el
nmero real de elementos de la coleccin
El programa est referenciando un elemento
de un arreglo utilizando un nmero fuera del
SUBSCRIPT_OUTSIDE_LIMIT
rango permitido (por ejemplo, el elemento 1)
La conversin de una cadena de carcteres
hacia un tipo rowid fall porque la cadena no
SYS_INVALID_ROWID
representa un nmero
Se excedi el tiempo mximo de espera por
TIMEOUT_ON_RESOURCE
un recurso en Oracle
Una sentencia SELECT INTO devuelve ms
TOO_MANY_ROWS
de una fila
Ocurri un error aritmtico, de conversin o
truncamiento. Por ejemplo, sucede cuando se
VALUE_ERROR
intenta calzar un valor muy grande dentro de
una variable ms pequea
El programa intent efectuar una divisin por
ZERO_DIVIDE
cero

-1017
100
-1012
-6501

-6504

-30625
-6500
-6533

-6532

-1410
-51
-1422

-6502

-1476

Atrapando excepciones no predefinidas por el servidor


Se la declara, o usando OTHERS, en pl/sql pragma EXCEPTION_INIT llama al
compilador asociando el nombre de la excepcin con un nmero de error Oracle.
PRAGMA significa que la sentencia es una directiva de compilador.

DECLARE
E_emps EXCEPTION;
PRAGMA EXCEPTION INIT ( e_emps, -2292);
BEGN
....
EXCEPTION
WHEN e_emps THEN
....
END;
Funciones para atrapar excepciones

44
SQLCODE retorna el valor numerico del error 0 no hay excepcin, 1 excepcin
definida por el usuario, +100 NO_DATA_FOUND, nmero negativo otro error
Oracle
SQLERRM retorna el mensaje asociado
DECLARE
V_error_code NUMBER;
V_error_message VARCHAR2(255);
BEGN
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
V_error_code := SQLCODE;
V_error_message := SQLERRM;
END;
DECLARE
err_num NUMBER;
err_msg VARCHAR2(255);
result NUMBER;
BEGIN
SELECT 1/0 INTO result
FROM DUAL;
EXCEPTION
WHEN OTHERS THEN
err_num := SQLCODE;
err_msg := SQLERRM;
DBMS_OUTPUT.put_line('Error:'||TO_CHAR(err_num));
DBMS_OUTPUT.put_line(err_msg);
END;
Tambin es posible entregarle a la funcin SQLERRM un nmero negativo que represente un error
de Oracle y sta devolver el mensaje asociado.

DECLARE
msg VARCHAR2(255);
BEGIN
msg := SQLERRM(-1403);
DBMS_OUTPUT.put_line(MSG);
END;

Atrapando excepciones definidas por el usuario


DECLARE
RAISE
REFERENCE
DECLARE
E_invalid EXCEPTION;
BEGN
UPDATE product
SET descrip = nnnnn
WHERE prodid = 5;
IF SQL%NOTFFOUND THEN
RAISE e_invalid;
END IF;
EXCEPTION
WHEN e_invalid THEN
ROLLBACK;
END;

45
DECLARE
-- Declaramos una excepcion identificada por VALOR_NEGATIVO
VALOR_NEGATIVO EXCEPTION;
valor NUMBER;
BEGIN
-- Ejecucion
valor := -1;
IF valor < 0 THEN
RAISE VALOR_NEGATIVO;
END IF;
EXCEPTION
-- Excepcion
WHEN VALOR_NEGATIVO THEN
dbms_output.put_line('El valor no puede ser negativo');
END;

RAISE_APPLICATION_ERROR
En ocasiones queremos enviar un mensaje de error personalizado al producirse una
excepcin PL/SQL.
Para ello es necesario utilizar la instruccion RAISE_APPLICATION_ERROR;
La sintaxis general es la siguiente:
RAISE_APPLICATION_ERROR(<error_num>,<mensaje>);

Siendo:

error_num es un entero negativo comprendido entre -20001 y -20999


mensaje la descripcion del error

DECLARE
v_div NUMBER;
BEGIN
SELECT 1/0 INTO v_div FROM DUAL;
EXCEPTION
WHEN OTHERS THEN
RAISE_APPLICATION_ERROR(-20001,'No se puede dividir por cero');
END;

Ambientes llamados
SQL*Plus Despliega el nmero del error y el mensaje en la pantalla
Procedure builder
Oracle Developer Forms utiliza ERROR_CODE y ERROR_TEXT
Aplicacin precompilada accede al nmero de la excepcin atravez de SQLCA
Bloque PL/SQL atrapa la excepcin en el manejador de excepciones
RAISE_APPLICATION_ERROR (error_number, message[ , {TRUE | FALSE}]);
Permite usar mensajes de error definidos por el usuario
Error_number 20000 a 20999
TRUE | FALSE si TRUE los errores en la pila de los errores previos, FALSE el error
default reemplaza los errores previos. Se puede usar en la seccin ejecutable y la
seccin de excepciones.
DECLARE
fecha DATE;
FUNCTION fn_fecha RETURN DATE
IS
fecha DATE;
BEGIN
SELECT SYSDATE INTO fecha
FROM DUAL
WHERE 1=2;
RETURN fecha;
EXCEPTION

46
WHEN ZERO_DIVIDE THEN
dbms_output.put_line('EXCEPCION ZERO_DIVIDE CAPTURADA
EN fn_fecha');
END;
BEGIN
fecha := fn_fecha();
dbms_output.put_line('La fecha es '||TO_CHAR(fecha,
'DD/MM/YYYY'));
EXCEPTION
WHEN NO_DATA_FOUND THEN
dbms_output.put_line('EXCEPCION NO_DATA_FOUND CAPTURADA EN
EL BLOQUE PRINCIPAL');
END;

47

Captulo 24 Ejemplos de PL/SQL Bsico


PL/SQL bsico
El clsico Hola Mundo! es un bloque con una seccin ejecutable que llama al
procedimiento DBMS_OUTPUT.PUT_LINE para mostrar texto en pantalla:
BEGIN
DBMS_OUTPUT.put_line('Hola Mundo!');
END;

Las funciones y procedimientos tipos de bloques con un nombre son discutidos


con mayor detalle ms adelante en este artculo, as como los paquetes. En pocas
palabras, sin embargo, un paquete es un contenedor de mltiples funciones y
procedimientos. Oracle extiende PL/SQL con muchos paquetes incorporados en el
lenguaje.
El siguiente bloque declara una variable de tipo VARCHAR2 (un string) con un largo
mximo de 100 bytes para contener el string Hola Mundo!. Despus, el
procedimiento DBMS_OUTPUT.PUT_LINE acepta la variable, en lugar del literal,
para desplegarlo:
DECLARE
l_mensaje VARCHAR2(100) := 'Hola Mundo!';
BEGIN
DBMS_OUTPUT.put_line(l_mensaje);
END;

Note que he llamado a la variable l_mensaje. Normalmente uso el prefijo l_ para


variables locales variables definidas dentro del cdigo de un bloque y el prefijo
g_ para variables globales definidas en un paquete.
El siguiente ejemplo de bloque agrega una seccin de manejo de excepciones que
atrapa cualquier excepcin (WHEN OTHERS) que pueda ser lanzada y muestra el
mensaje de error, que es retornado por la funcin SQLERRM (provista por Oracle).
DECLARE
l_mensaje VARCHAR2(100) := 'Hola Mundo!';
BEGIN
DBMS_OUTPUT.put_line(l_mensaje);
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line(SQLERRM);
END;

El siguiente ejemplo de bloque demuestra la habilidad de PL/SQL de anidar bloques


dentro de bloques as como el uso del operador de concatenacin (||) para unir
mltiples strings.
DECLARE
l_mensaje VARCHAR2(100) := 'Hola';
BEGIN
DECLARE
l_mensaje2 VARCHAR2(100) := l_mensaje || ' Mundo!';
BEGIN
DBMS_OUTPUT.put_line(l_mensaje2);
END;
EXCEPTION
WHEN OTHERS
THEN

48
DBMS_OUTPUT.put_line(DBMS_UTILITY.format_error_stack);
END;

Se
ejecuta
la
funcin
pExeSuiComercial
del
paquete
olbgenerainfosuicomer_48765. Se enva un mensaje de terminacin correcta y de
no ser as se enva el cdigo y mensaje de error respectivo.
BEGIN
olbgenerainfosuicomer_48765.pExeSuiComercial(7,
To_Date('01-04-2013','DD-MM-YYYY'),
To_Date('30-04-2013','DD-MM-YYYY'));
Dbms_Output.put_line('Proceso Ok');
EXCEPTION
WHEN Others THEN
Dbms_Output.put_line(SQLCODE || ':' || SQLERRM);
END;

Ejecutando el PL/SQL
Una vez que hemos escrito un bloque de cdigo PL/SQL ste se puede ejecutar.
Existen muchas herramientas para ejecutar cdigo PL/SQL. La ms bsica es
SQL*Plus, una interfaz de lnea de comandos para ejecutar sentencias SQL as como
bloques PL/SQL. La Figura 1 muestra un ejemplo de ejecucin del ms simple de los
bloques de ejemplo de nuestro Hola Mundo! en SQL*Plus.

Figura 1: Ejecutando Hola Mundo! en SQL*Plus

La primera cosa que hacemos despus de conectarnos a la base medante SQL*Plus


es habilitar la salida del servidor, por lo que las llamadas a
DBMS_OUTPUT.PUT_LINE resultarn en la visualizacin de texto en la pantalla.
Luego escribimos el cdigo que constituye nuestro bloque. Finalmente, ingresamos
una barra (/) para decirle a SQL*Plus que ejecute ese cdigo.
SQL*Plus entonces ejecuta el bloque y muestra el Hola Mundo! en la pantalla.
SQL*Plus es provisto por Oracle como una especie de lnea base de entorno donde se
pueden ejecutar sentencias SQL y bloques PL/SQL. Mientras que algunos
desarrolladores siguen utilizando nicamente SQL*Plus, la mayora utiliza un
entorno de desarrollo integrado (IDE). Entre los ms populares de estos entornos de
desarrollo (basado en encuestas informales que he tomado en mis sesiones de
entrenamiento) son

SQL Tools
Oracle SQL Developer, de Oracle
Toad y SQL Navigator, de Quest Software
PL/SQL Developer, de Allround Automations

49
Cada herramienta ofrece, con algunas diferencias, ventanas y pasos para crear,
guardar, y ejecutar bloques PL/SQL, as como habilitar y deshabilitar la salida del
servidor.
Otra opcin de ejecucin es SQL Tools:

Figura 1: Ejecutando pExeSuiComercial en SQL Tools

50

Captulo 25 Subprogramas: procedimientos y


funciones
Pngale nombre a los bloques!
Todos los bloques que hemos visto hasta el momento son annimos, no tienen
nombres. Si los bloques annimos fueran la nica manera de organizar el cdigo,
sera muy difcil usar PL/SQL para crear una aplicacin grande y compleja. Por esto,
PL/SQL soporta la definicin de bloques nombrados (named blocks), tambin
conocidos como subprogramas. Los subprogramas pueden ser procedimientos o
funciones. Generalmente, un procedimiento se utiliza para realizar una accin y una
funcin se utiliza para calcular y devolver un valor. Voy a tratar sobre subprogramas
con mucho ms detalle en un prximo artculo de esta serie. Por ahora, vamos a
asegurarnos de que se comprendan los conceptos bsicos detrs de la creacin del
subprograma.
Supongamos que necesitamos mostrar "Hola Mundo!" desde mltiples lugares en
nuestra aplicacin. Queremos evitar la repeticin de la misma lgica en todos esos
lugares. Por ejemplo, qu pasa cuando tenemos que cambiar el mensaje, tal vez para
"Hola Universo!"? Vamos a tener que encontrar todos los lugares en nuestro cdigo
donde esta lgica aparece.
En su lugar, vamos a crear un procedimiento denominado hola_mundo medante la
ejecucin de la siguiente sentencia DDL (Data Definition Language):
CREATE OR REPLACE PROCEDURE hola_mundo IS
l_mensaje VARCHAR2(100) := 'Hola Mundo!';
BEGIN
DBMS_OUTPUT.put_line(l_mensaje);
END hola_mundo;

Con esto hemos extendido PL/SQL. Adems de llamar a los programas creados por
Oracle e instalados en la base de datos (como DBMS_OUTPUT.PUT_LINE),
podemos llamar a nuestro propio subprograma dentro de un bloque PL/SQL:
BEGIN
hola_mundo;
END;

Hemos escondido todos los detalles de cmo decir hola al mundo dentro del cuerpo
(body), o implementacin, de nuestro procedimiento. Ahora podemos llamar a este
procedimiento hola_mundo y mostrar el mensaje deseado sin tener que escribir la
llamada a DBMS_OUTPUT.PUT_LINE o averiguar la forma correcta de darle
formato al texto. Podemos llamar a este procedimiento desde cualquier lugar en
nuestra aplicacin. As que si alguna vez necesitamos cambiar ese texto, lo vamos a
hacer en un solo lugar, el nico punto de definicin de ese texto.
El procedimiento hola_mundo es muy simple. Tus procedimientos tendrn mucho
ms cdigo, y casi siempre tambin tendrn parmetros. Los parmetros pasan
informacin a los subprogramas, cuando stos son llamados, y es lo que permite crear
subprogramas ms flexibles y genricos. Se pueden usar en muchos contextos
diferentes.
He mencionado antes que algn da puede ser que desee mostrar "Hola Universo!"
en lugar de "Hola Mundo!". Podra hacer una copia de nuestro procedimiento
hola_mundo y cambiar el texto que se muestra:
CREATE OR REPLACE PROCEDURE hola_universo IS
l_mensaje VARCHAR2(100) := 'Hola Universo!';
BEGIN
DBMS_OUTPUT.put_line(l_mensaje);
END hola_universo;

51
Podramos, sin embargo, terminar con las decenas de variantes del mismo
procedimiento hola, que hara muy difcil mantener nuestra aplicacin. Un enfoque
mucho mejor es analizar el procedimiento e identificar qu partes se mantienen
incambiadas (son estticas) cuando el mensaje tiene que cambiar y qu partes
cambian. Luego podemos pasar las partes que cambian como parmetros y tener un
procedimiento nico que se puede utilizar en diferentes circunstancias.
As que vamos a cambiar hola_mundo (y hola_universo) a un nuevo procedimiento,
hola_lugar:
CREATE OR REPLACE PROCEDURE hola_lugar (lugar_in IN VARCHAR2) IS
l_mensaje VARCHAR2(100);
BEGIN
l_mensaje := 'Hola ' || place_in;
DBMS_OUTPUT.put_line(l_mensaje);
END hola_lugar;

Justo despus del nombre del procedimiento, aadimos entre parntesis de apertura y
cierre, un nico parmetro. Podemos tener varios parmetros, pero cada parmetro de
la misma forma bsica:
nombre_de_parametro

modo_de_parametro

tipo_de_datos

En otras palabras, debemos proveer un nombre para el parmetro, el modo o forma en


que ste ser usado (IN = slo lectura), y el tipo de dato que ser pasado al
subprograma a travs de este parmetro.
En este caso, vamos a pasar un texto de slo lectura al procedimiento hola_lugar.
Y ahora podemos saludar a nuestro mundo y a nuestro universo como sigue:
BEGIN
hola_lugar('Mundo!');
hola_lugar('Universo!');
END;

Ms adelante en esta serie vamos a explorar el concepto de reutilizacin y la manera


de evitar la repeticin, pero debes ser capaz de ver en este ejemplo, el poder de
ocultar la lgica detrs de un bloque con nombre.
Ahora supongamos que no slo queremos mostrar nuestros mensajes "Hola". A veces
tenemos que mantener los mensajes en una tabla en la base de datos; en otras
ocasiones, tenemos que pasar el texto de nuevo al entorno del cliente para su
visualizacin en un navegador Web. En otras palabras, necesitamos separar la forma
en que se construy el mensaje "Hola" de la forma en que se utiliza (se visualiza, se
guarda, se enva otro programa, etc). Podemos alcanzar este nivel deseado de
flexibilidad moviendo el cdigo que construye el mensaje a su propia funcin:
CREATE OR REPLACE FUNCTION
hola_mensaje(lugar_in IN VARCHAR2) RETURN VARCHAR2 IS
BEGIN
RETURN 'Hola ' || place_in;
END hola_mensaje;

Este subprograma se diferencia del procedimiento original en lo siguiente:


El tipo de programa es ahora FUNCTION y no PROCEDURE.
El nombre del subprograma ahora describe los datos que se devuelven, no las
acciones tomadas.
El cuerpo o la implementacin del subprograma contiene ahora una clusula
RETURN que construye el mensaje y lo devuelve al bloque llamador.
La clusula RETURN despus de la lista de parmetros establece el tipo de datos
devuelto por la funcin.

52
Teniendo el cdigo necesario para construir el mensaje dentro de la funcin
hola_mensaje, podemos utilizar este mensaje de mltiples maneras. Podemos, por
ejemplo, llamar a la funcin para obtener el mensaje y asignrselo a una variable:
DECLARE
l_mensaje VARCHAR2(100);
BEGIN
l_mensaje := hola_mensaje('Universo');
END;

Nota que llamamos a la funcin hola_mensaje como parte de una sentencia PL/SQL
(en este caso, la asignacin de un texto a una variable). La funcin hola_mensaje
devuelve un string, por lo que se puede utilizar en lugar de un string en cualquier
sentencia ejecutable.
Tambin podemos volver a nuestro procedimiento hola_lugar y reemplazar el cdigo
utilizado para crear el string con una llamada a la funcin:
CREATE OR REPLACE PROCEDURE
hola_lugar(place_in IN VARCHAR2) IS
BEGIN
DBMS_OUTPUT.put_line(hola_mensaje(place_in));
END hola_lugar;

Tambin podemos llamar la funcin desde una sentencia SQL. En el siguiente


bloque, insertamos el mensaje en una tabla de la base:
BEGIN
INSERT INTO tabla_mensaje(fecha_mensaje, texto_mensaje)
VALUES (SYSDATE, hola_mensaje('Montevideo'));
END;

Aunque la lgica del mensaje hola es muy simple, demuestra el poder de asignar
nombres a una o ms sentencias ejecutables (un algoritmo) y luego referenciar el
algoritmo simplemente especificando el nombre y los parmetros requeridos.
Los bloques PL/SQL con nombre, permiten construir aplicaciones complejas que
pueden ser comprendidas y mantenidas con relativa fcilidad.
Sobre los nombres en una base Oracle
Ahora que ya se aprecia la importancia de asignar nombres a la lgica, es tiempo de
hablar sobre las reglas para los nombres (o, para ser ms precisos, identificadores)
tanto en PL/SQL como, de forma ms general, en una base Oracle.
Estas son las reglas para construir identificadores vlidos en una base Oracle:
El largo mximo es de 30 carcteres.
El primer carcter debe ser una letra, pero cada carcter despus del primero puede
ser una letra, un nmero (0 a 9), un signo de pesos ($), un guin bajo (_), o un
numeral (#). Todos los siguientes son identificadores vlidos:
hola_mundo
hola$mundo
hola#mundo
pero estos son invlidos:
1hola_mundo
hola%mundo
PL/SQL es case-insensitive (no es sensitivo a maysculas y minsculas) con
respecto a los identificadores. PL/SQL trata todos los siguientes como el mismo

53
identificador:
hola_mundo
Hola_Mundo
HOLA_MUNDO
Para ofrecer ms flexibilidad, Oracle permite evitar las restricciones de la segunda y
tercera regla, encerrando al identificador entre comillas dobles. Un quoted identifier
(identificador encerrado entre comillas) puede contener cualquier secuencia de
carcteres imprimibles excluyendo las comillas dobles; las diferencias entre
maysculas y minsculas sern adems preservadas. As, todos los siguientes
identificadores son vlidos y distintos:
"Abc"
"ABC"
"a b c"
Es muy raro encontrar identificadores entre comillas en cdigo PL/SQL; algunos
grupos de desarrollo los usan para conformar con sus convenciones de nombres o
porque encuentran que una mezcla de maysculas y minsculas resulta ms fcil de
leer.
Estas mismas reglas aplican a los nombres de los objetos de base de datos como
tablas, vistas y procedimientos, con una regla adicional: a menos que se encierren
entre comillas los nombres de estos objetos, Oracle los mantendr en maysculas.
As que cuando creamos un procedimiento como el que sigue:
CREATE OR REPLACE PROCEDURE hola_mundo IS
BEGIN
DBMS_OUTPUT.put_line('Hola Mundo!');
END hola_mundo;

la base de datos Oracle lo mantendr con el nombre HOLA_MUNDO.


En el bloque siguiente, llamaremos este procedimiento tres veces, y aunque el
nombre luzca diferente cada vez, siempre se ejecutar el mismo procedimiento:
BEGIN
hola_mundo;
HOLA_MUNDO;
"HOLA_MUNDO";
END;

Por otro lado, la base Oracle no ser capaz de ejecutar el procedimiento si lo


llamamos como sigue:
BEGIN
"hola_mundo";
END;

Esto buscar dentro de la base un procedimiento llamado hola_mundo en lugar de


HOLA_MUNDO.
Si no se quiere que los nombres de los subprogramas se mantengan en maysculas,
los nombres se deben encerrar entre comillas cuando se crea el subprograma:
CREATE OR REPLACE PROCEDURE "Hola_Mundo" IS
BEGIN
DBMS_OUTPUT.put_line('Hola Mundo!');
END "Hola_Mundo";

54

Captulo 26 Procedimientos
Procedimientos almacenados
Un procedimiento es un subprograma que ejecuta una accin especfica y que no
devuelve ningn valor. Un procedimiento tiene un nombre, un conjunto de
parmetros (opcional) y un bloque de cdigo.
La sintaxis de un procedimiento almacenado es la siguiente:
CREATE [OR REPLACE]
PROCEDURE <procedure_name> [(<param1> [IN|OUT|IN OUT] <type>,
<param2> [IN|OUT|IN OUT] <type>, ...)]
IS
-- Declaracion de variables locales
BEGIN
-- Sentencias
[EXCEPTION]
-- Sentencias control de excepcion
END [<procedure_name>];

El uso de OR REPLACE permite sobreescribir un procedimiento existente. Si se


omite, y el procedimiento existe, se producir, un error.
La sintaxis es muy parecida a la de un bloque annimo, salvo porque se reemplaza
la seccion DECLARE por la secuencia PROCEDURE ... IS en la especificacin del
procedimiento.
Debemos especificar el tipo de datos de cada parmetro. Al especificar el tipo de
dato del parmetro no debemos especificar la longitud del tipo.
Los parmetros pueden ser de entrada (IN), de salida (OUT) o de entrada salida
(IN OUT). El valor por defecto es IN, y se toma ese valor en caso de que no
especifiquemos nada.
CREATE OR REPLACE
PROCEDURE Actualiza_Saldo(cuenta NUMBER,
new_saldo NUMBER)
IS
-- Declaracion de variables locales
BEGIN
-- Sentencias
UPDATE SALDOS_CUENTAS
SET SALDO = new_saldo,
FX_ACTUALIZACION = SYSDATE
WHERE CO_CUENTA = cuenta;
END Actualiza_Saldo;

Tambin podemos asignar un valor por defecto a los parmetros, utilizando la


clausula DEFAULT o el operador de asigancin (:=). Si un parmetro tiene un valor
predeterminado, no tiene por qu ser pasado desde el entorno que realiza la llamada.
CREATE OR REPLACE
PROCEDURE Actualiza_Saldo(cuenta NUMBER,
new_saldo NUMBER DEFAULT 10 )
IS
-- Declaracion de variables locales
BEGIN
-- Sentencias
UPDATE SALDOS_CUENTAS
SET SALDO = new_saldo,
FX_ACTUALIZACION = SYSDATE
WHERE CO_CUENTA = cuenta;
END Actualiza_Saldo;

55
Una vez creado y compilado el procedimiento almacenado podemos
ejecutarlo. Si el sistema nos indica que el procedimiento se ha creado con errores de
compilacin podemos ver estos errores de compilacion con la orden SHOW
ERRORS en SQL *Plus.
Existen dos formas de pasar argumentos a un procedimiento almacenado a la hora
de ejecutarlo (en realidad es vlido para cualquier subprograma). Estas son:

Notacin posicional: Se pasan los valores de los parmetros en el mismo


orden en que el procedure los define.

BEGIN
Actualiza_Saldo(200501,2500);
COMMIT;
END;

Notacin nominal:Se pasan los valores en cualquier orden nombrando


explicitamente el parmetro.

BEGIN
Actualiza_Saldo(cuenta => 200501,new_saldo
COMMIT;
END;

=> 2500);

Opcionalmente se produce el mismo resultado.


BEGIN
Actualiza_Saldo(new_saldo
COMMIT;
END;

=> 2500,cuenta => 200501);

Para eliminar un procedimiento usamos:


DROP PRODEDUE

nombre_prodecimiento;

Para dar privilegios de ejecucin sobre un procedimiento o funcin usamos:


GRANT EXECUTE ON nombre_prodecimiento TO UsuarioB;

56

Captulo 27 Funciones
Funciones en PL/SQL
Una funcin es un subprograma que devuelve un valor.
La sintaxis para construir funciones es la siguiente:

CREATE [OR REPLACE]


FUNCTION <fn_name>[(<param1> IN <type>, <param2> IN <type>, ...)]
RETURN <return_type>
IS
result <return_type>;
BEGIN
return(result);
[EXCEPTION]
-- Sentencias control de excepcion
END [<fn_name>];

El uso de OR REPLACE permite sobreescribir una funcin existente. Si se omite, y


la funcin existe, se producir, un error.
La sintaxis de los parmetros es la misma que en los procedimientos almacenado,
exceptuando que solo pueden ser de entrada.
Ejemplo:
CREATE OR REPLACE
FUNCTION fn_Obtener_Precio(p_producto VARCHAR2)
RETURN NUMBER
IS
result NUMBER;
BEGIN
SELECT PRECIO INTO result
FROM PRECIOS_PRODUCTOS
WHERE CO_PRODUCTO = p_producto;
return(result);
EXCEPTION
WHEN NO_DATA_FOUND THEN
return 0;
END ;

Si el sistema nos indica que el la funcin se ha creado con errores de compilacin


podemos ver estos errores de compilacion con la orden SHOW ERRORS en SQL
*Plus.
Una vez creada y compilada la funcin podemos ejecutarla de la siguiente forma:
DECLARE
Valor NUMBER;
BEGIN
Valor := fn_Obtener_Precio('000100');
END;

Las funciones pueden utilizarse en sentencias SQL de manipulacin de datos


(SELECT, UPDATE, INSERT y DELETE):
SELECT CO_PRODUCTO,
DESCRIPCION,
fn_Obtener_Precio(CO_PRODUCTO)
FROM PRODUCTOS;

57
Para eliminar una funcion usamos:
DROP FUNCTION

nombre_funcion;

Para dar privilegios de ejecucin sobre un procedimiento o funcin usamos:


GRANT EXECUTE ON nombre_funcion TO UsuarioB;

58

Captulo 26 Procedimientos
Por qu anidar bloques?
Podemos poner BEGIN antes de cualquier conjunto de una o ms sentencias
ejecutables seguidas de un END, creando un bloque anidado con esas sentencias. Hay
dos ventajas principales para hacer esto: (1) posponer la asignacin de memoria para
variables que se necesitan nicamente en el bloque anidado, y (2) limitar la
propagacin de una excepcin lanzada por una de las sentencias del bloque anidado.
Consideremos el siguiente bloque:
DECLARE
l_mensaje1 VARCHAR2(100) := 'Hola';
l_mensaje2 VARCHAR2(100) := ' Mundo!';
BEGIN
IF SYSDATE >= TO_DATE('01-JAN-2012')
THEN
l_mensaje2 := l_mensaje1 || l_mensaje2;
DBMS_OUTPUT.put_line(l_mensaje2);
ELSE
DBMS_OUTPUT.put_line(l_mensaje1);
END IF;
END;

El bloque despliega Hola Mundo! cuando la fecha de hoy (retornada por


SYSDATE) es por lo menos el primer da de 2012; en otro caso, nicamente
despliega el mensaje Hola. Aunque este bloque se ejecute en 2011, asigna memoria
para la variable l_mensaje2.
Si reestructuramos este bloque, la memoria para l_mensaje2 ser asignada
nicamente despus del 2011:
DECLARE
l_mensaje1 VARCHAR2(100) := 'Hola';
BEGIN
IF SYSDATE > TO_DATE('01-JAN-2011')
THEN
DECLARE
l_mensaje2 VARCHAR2(100) := ' Mundo!';
BEGIN
l_mensaje2 := l_mensaje1 || l_mensaje2;
DBMS_OUTPUT.put_line(l_mensaje2);
END;
ELSE
DBMS_OUTPUT.put_line(l_mensaje1);
END IF;
END;

De forma similar, podemos agregar una seccin de excepciones a este bloque


anidado, atrapando errores y permitiendo que el bloque exterior contine con su
ejecucin:
DECLARE
l_mensaje1 VARCHAR2(100) := 'Hola';
BEGIN
DECLARE
l_mensaje2 VARCHAR2(5);
BEGIN
l_mensaje2 := ' Mundo!';
DBMS_OUTPUT.put_line(l_mensaje1 || l_mensaje2);
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line(DBMS_UTILITY.format_error_stack);

59
END;
DBMS_OUTPUT.put_line(l_mensaje1);
END;

En este caso, el bloque anidado lanzar una excepcin VALUE_ERROR, porque la


variable l_mensaje2 es muy pequea (mximo de 5 bytes) para el texto Mundo!.La
seccin de excepciones del bloque anidado atrapar y desplegar el error. El bloque
exterior continuar su ejecucin.
Un posterior artculo en estas series se enfocar en cmo funciona el manejo de
excepciones en PL/SQL.
Ms adelante en esta serie de artculos, mostrar cmo controlar el flujo de ejecucin
en nuestros bloques: lgica condicional con IF y CASE; lgica iterativa con FOR,
WHILE y LOOP; as como lanzar y manejar excepciones.

S-ar putea să vă placă și