Professional Documents
Culture Documents
Plsql 9i2005
manual del curso teleformedia. NIVEL II
1
3
ndice
HTML / ndice
ndice de contenido
UNIDAD DIDCTICA 1: PL/SQL PARA ORACLE 9i
INTRODUCCIN
1. BREVE HISTORIA
3. ENTORNO DE PL/SQL
16
16
5. FUNDAMENTOS DE PL/SQL
16
6. BLOQUES
17
7. DECLARACIONES
18
8. EXPRESIONES Y COMPARACIONES
19
9. TIPOS DE DATOS
19
22
24
26
13. CURSORES
37
43
14. EXCEPCIONES
43
15. SUBPROGRAMAS
48
77
80
GLOSARIO
85
/4
u.d. 1
NIVEL II
1. BREVE HISTORIA
PL/SQL, primero, fue introducido en 1991 con Oracle 6.0. Fue proporcionado como la opcin
procedural del lado del servidor. Al mismo tiempo, fue introducido, posteriormente, en el
lado cliente con SQL * versin 3.0, de manera que tena su propio motor PL/SQL. La primera
versin fue PL/SQL 1.0, tena caractersticas procedurales muy limitadas. Pero, uno de sus
puntos fuertes era su capacidad para procesar las sentencias mltiples del SQL, mezcladas
con las construcciones procedurales.
PL/SQL tiene sus races en el ADA, un lenguaje de programacin de alto nivel. El concepto
del bloque PL/SQL se parece al concepto de estructura de bloque en el ADA que usa BEGIN
y END para delimitar dichos bloques. PL/SQL comparte otras caractersticas con el ADA, tal
como la sintaxis = utilizado para la comparacin y:= utilizada para la asignacin, manejo
de excepciones, y la sintaxis declarativa, para definir subprogramas almacenados.
Con el tiempo, Oracle subi con las nuevas versiones de PL/SQL. Con Oracle 7.0, Oracle
lanz PL/SQL 2.0, que convirti a Oracle en una base de datos activa con la capacidad
almacenar la lgica de negocio y lgica de la aplicacin en la base de datos bajo la forma
de procedimientos, funciones, y paquetes almacenados. Tambin defini la capacidad para
declarar registros y arrays, definidos por el programador bajo la forma de tablas PL/ SQL.
PL/SQL 2.1 entr con Oracle 7.1 y permiti el uso de funciones almacenadas en sentencias
SQL. Tambin, el SQL dinmico fue introducido en PL/SQL por primera vez con el paquete
de DBMS_SQL. Oracle 7.2 fue lanzado posteriormente, y junto con l vino PL/SQL 2.2. Tena
la capacidad para definir los wrappers binarios para los subprogramas almacenados de PL/
SQL, de manera que se oculta el cdigo para otros desarrolladores. Tambin fue introducido
el paquete DBMS_JOB, que permiti a lo programadores submitir trabajos dentro de la base
de datos. El lanzamiento siguiente PL/SQL era PL/SQL 2.3, que fue introducido con Oracle
/5
u.d. 1
NIVEL II
7.3. Realz las capacidades de las tablas PL/SQL con la capacidad de definir nuevos mtodos,
y tambin permiti a los programadores tener acceso al sistema de ficheros dentro de la
base de datos. Los ficheros I/O se podan hacer usando el paquete de UTL_FILE.
Oracle 8.x era una brecha importante en la historia de Oracle con la introduccin de objetos,
y Java en la base de datos. PL/SQL 8.x fue lanzado junto con Oracle 8.x y las caractersticas
importantes incluidas, tales como SQL dinmico nativo, procedimientos almacenados en
Java, y triggers a nivel de sistema y de esquema de la base de datos.
Finalmente, Oracle 9i fue lanzado, y junto con l vino PL/SQL 9.2 y 9.0, correspondiendo
a los lanzamientos 2 y 1 de este lanzamiento de Oracle 9i. En esta versin, se introduce
la compilacin nativa del cdigo PL/SQL, mejora de los cursores PL/SQL bajo la forma de
expresiones del cursor, nuevos tipos de datos, funciones canalizadas, herencia de verdad
entre objetos
Portabilidad
Los programas escritos en PL/SQL son independientes del hardware y del sistema operativo.
Son altamente portables, y trabajan bien sobre cualquier plataforma donde estn instalados
un servidor y un entorno integrado de desarrollo (IDE) Oracle.
Modularidad
PL/SQL permite escribir programas como mdulos independientes que se pueden integrar.
Se puede ejecutar esta modularidad, utilizando procedimientos, funciones, y paquetes.
/6
NIVEL II
u.d. 1
Un funcionamiento mejor
PL/SQL ofrece un funcionamiento mejor por tres razones principales:
1. La conversin de tipos de datos no es necesaria en la entrada y salida.
2. Normalmente, las aplicaciones de la base de datos en un entorno cliente-servidor tienen
una arquitectura de dos niveles (Oracle en el servidor y PL/SQL en el cliente) o una estructura de tres capas (una capa del servidor de la base de datos, otra capa del servidor de las
aplicaciones en un servidor de aplicaciones, y una capa de presentacin en un cliente). Con
PL/SQL, se puede agrupar un conjunto de sentencias SQL (junto con la lgica de aplicacin)
en un bloque PL/SQL, y submitirlo al servidor de Oracle, mejorando el trfico de red. El
concepto de estructura de bloque tambin significa que habr pocas llamadas a la base de
datos, lo que da lugar a un mejor funcionamiento.
3. PL/SQL 9i introduce la compilacin nativa del cdigo PL/SQL, la conversin subsecuente
a C y el almacenamiento del cdigo mquina. Esto da lugar a una ejecucin ms rpida.
Antes de Oracle 9i, las versiones interpretadas del cdigo PL/SQL, conocidas como p-cdigo,
mostraban solamente la ejecucin ms rpida del PL/SQL.
Orientacin a objetos
PL/SQL proporciona caractersticas orientadas a objetos, como encapsulacin, abstraccin
(la capacidad de definir tipos de datos abstractos), los datos e informacin se ocultan, reutilidad, herencia, polimorfismo, y envo dinmico de mtodos.
3. ENTORNO DE PL/SQL
Para desarrollar y para ejecutar los programas 3GL, se necesita un entorno de desarrollo
en el que se pueda escribir y ejecutar los programas. A esto se le llama Entorno Integrado
de Desarrollo, o IDE. La mayora de los 3GLs como Java, C proporcionan IDEs, como Visual
Age for Java de IBM, y Visual C++, respectivamente.
Hay tres tipos de entornos necesarios para cualquier lenguaje de programacin, y PL/SQL
no es ninguna excepcin:
Entorno de desarrollo
Entorno de ejecucin
El entorno de ejecucin de
PL/SQL se podra representar
de la siguiente manera:
Imagen1-1-1
/7
u.d. 1
NIVEL II
Imagen1-1-2
Imagen1-1-3
/8
u.d. 1
NIVEL II
parte del programador, y la legibilidad por parte del revisor del cdigo. La sintaxis de la
sentencia CASE es:
CASE SELECT r
WHEN value1 THEN action1;
WHEN value2 THEN action2;
WHEN value3 THEN action3;
... ...
ELSE
actionN;
END CASE;
Donde SELECT r es una variable o una expresin, y value1, value2, y value3 son los valores
del SELECT r. El SELECT r se evala solamente una vez. En el caso de una sentencia CASE,
esto es evidente para el compilador, pues el SELECT r se especifica solamente una vez al
principio. La orden WHEN determina qu acciones se tienen que ejecutar.
Ejemplo:
CASE report_choice
WHEN 1 THEN p_proc_report1;
WHEN 2 THEN p_proc_report2;
WHEN 3 THEN p_proc_report3;
WHEN 4 THEN p_proc_report4;
ELSE dbms_output.put_line(Invalid option.);
END CASE;
Si todo esto se tuviera que hacer con una sentencia IF...ELSEIF... sera:
IF (report_choice=1) THEN
p_proc_report1;
ELSIF (report_choice=2) THEN
p_proc_report2;
ELSIF (report_choice=3) THEN
p_proc_report3;
ELSIF (report_choice=4) THEN
p_proc_report4;
ELSE
dbms_output.put_line(Invalid option.);
Expresin CASE
Se puede utilizar la construccin CASE en una expresin, y asignarla a una variable para
generar un valor. La sintaxis de la expresin CASE es:
var := CASE SELECT r
WHEN value1 THEN assigned_value1
WHEN value2 THEN assigned_value2
WHEN value3 THEN assigned_value3
... ...
ELSE assigned_valueN;
END CASE;
Donde var es una variable declarada que recibe un valor, value1, value2 y value3 son los valores del SELECT r, y assigned_value1, assigned_value2, assigned_value3, y assigned_valueN
son los valores que se asignan a la variable var, dependiendo del valor del SELECT r.
Como ejemplo, veremos un segmento del cdigo siguiente, que es parte de un programa
que convierte dgitos a las palabras:
temp := CASE i
WHEN 0 THEN Zero
WHEN 1 THEN One
WHEN 2 THEN Two
/9
u.d. 1
THEN
THEN
THEN
THEN
THEN
THEN
THEN
NIVEL II
Three
Four
Five
Six
Seven
Eight
Nine
Ejemplo:
CASE
WHEN (report_choice = 1) THEN p_proc_report1;
WHEN (report_choice = 2) THEN p_proc_report2;
WHEN (report_choice = 3) THEN p_proc_report3;
WHEN (report_choice = 4) THEN p_proc_report4;
ELSE dbms_output.put_line(Invalid option.);
END CASE
THEN
THEN
THEN
THEN
THEN
THEN
THEN
THEN
THEN
THEN
Zero
One
Two
Three
Four
Five
Six
Seven
Eight
Nine
Estas expresiones tienen mas alcance que las expresiones normales CASE, porque se pueden
utilizar para evaluar las mltiples condiciones que implican mltiples variables.
/ 10
u.d. 1
NIVEL II
Por ejemplo:
declare
a number := 20;
b number := -40;
string varchar2(50);
begin
string := case
when (a>b) then A es mayor que B
when (a<b) then A es menor que B
else
A es igual que B
end;
dbms_output.put_line(string);
end;
/
/ 11
u.d. 1
NIVEL II
Adems, Oracle 9i tiene tres nuevos tipos de datos especiales SQL, que permiten la encapsulacin dinmica y acceso para escribir descripciones, instancias de datos. Adems, se pueden
utilizar estos tres tipos especiales para crear tipos annimos, incluyendo la coleccin annima. Los tres tipos especiales son SYS.ANYTYPE, SYS.ANYDATA, y SYS.ANYDATASET.
De los paquetes mejorados, el paquete UTL_FILE, que proporciona el API para la entradasalida del archivo (I/O), tiene algunas mejoras con respecto a permitir la abertura, lectura,
y escritura de los archivos en formato Unicode.
El paquete de UTL_HTTP tiene nuevas caractersticas para apoyar la autentificacin, las
cookies, enviar mensajes grandes y conexiones persistentes.
Mejoras varias
Otras nuevas caractersticas son:
Autogeneracin llamadas PL/SQL para procedimientos almacenados en Java. Caractersticas orientadas al objeto exclusivas a PL/a SQL 9i.
/ 12
u.d. 1
NIVEL II
Ser canalizado para poder devolver filas de datos incrementalmente, en vez de esperar
a la funcin para ejecutarse totalmente, y se almacenarn un sistema entero de filas
en memoria. La coleccin entera no necesita ser instanciada en memoria. Esto da
lugar a un tiempo de respuesta mejor y a menos consumo de memoria.
/ 13
u.d. 1
NIVEL II
/ 14
final de leccin
FINAL DE LA LECCIN 1
Notas de trabajo del alumno:
Conclusiones:
Entorno de desarrollo
Entorno de ejecucin
PL/SQL incorpora la estructura de los lenguajes de tercera generacin (3GL), que en SQL
no se puede aplicar, ya que es un lenguaje
de cuarta generacin (4GL); esto significa que
utiliza las construcciones y los elementos que
especifican qu hacer, sin tener que especificar cmo hacerlo.
/ 15
u.d. 1
NIVEL II
El rea de contexto es la memoria designada para procesar una instruccin SQL, que incluye
el nmero de registros procesados, un apuntador a la representacin de la instruccin
SQL analizada y, en el caso de una consulta, el conjunto de registros que regresan de la
consulta.
5. FUNDAMENTOS DE PL/SQL
PL/SQL no es CASE-SENSITIVE
Una lnea en PL/SQL contiene grupos de caracteres conocidos como UNIDADES LEXICAS,
que pueden ser clasificadas como:
Operadores Aritmticos
Operadores Lgicos
Operadores Relacionales
Constantes
Cursores
Variables
Subprogramas
Excepciones
Paquetes
COMENTARIO: Son soportados 2 estilos de comentarios, el de lnea simple y de multilnea, para lo cual son empleados ciertos caracteres especiales, como son:
-- Lnea simple
/*
Conjunto de Lneas
*/
NOTA:
No pueden ser empleados en forma anidada
/ 16
NIVEL II
u.d. 1
6. BLOQUES
A continuacin, se muestra cmo es la estructura general de los bloques de instrucciones
de PL/SQL, que se usarn ms adelante en la creacin de procedimientos, funciones y triggers.
PL/SQL agrega construcciones propias de lenguajes procedurales, obtenindose como resultado un lenguaje estructural ms poderoso que SQL. La unidad de programacin utilizada
por PL/SQL es el bloque. Todos los programas de PL/SQL estn conformados por bloques.
Normalmente, cada bloque lleva a cabo una accin lgica en el programa. Un bloque tendr
siempre la siguiente estructura:
DECLARE
//Seccin declarativa: variables, tipos, y subprogramas
//de uso local
BEGIN
//Seccin ejecutable: las instrucciones procedurales, y de SQL
//aparecen aqu. Es la nica seccin obligatoria en el bloque.
EXCEPTION
//Seccin de manejo de excepciones. Las rutinas de manejo de errores
//aparecen aqu
END;
Solo se requiere que aparezca la seccin ejecutable. Lo dems es opcional. Las nicas instrucciones SQL permitidas en un bloque PL/SQL son INSERT, UPDATE, DELETE y SELECT,
adems de algunas instrucciones para manipulacin de datos, e instrucciones para control
de transacciones. Otras instrucciones de SQL como DROP, CREATE o ALTER no son permitidas. Se permite el uso de comentarios estilo C (/*...*/). PL/SQL no es case sensitive, por lo
que no hay distincin entre nombres con maysculas y minsculas.
Los tipos de bloques que hay son:
Bloque annimo: Es una seccin del cdigo incluida dentro declaraciones BEGIN y
END. No tiene ningn nombre asociado a ella.
Bloque etiquetado (Funcin): Esto es un bloque PL/SQL, identificado por una etiqueta.
Comienza con una etiqueta PL/SQL seguida por un BEGIN y una sentencia END.
Imagen1-2-1
/ 17
u.d. 1
NIVEL II
7. DECLARACIONES
Los programas pueden emplear variables y constantes para almacenar valores, dichos identificadores son colocados en el rea de declaraciones de un bloque, como por ejemplo:
VARIABLES:
fecha
DATE
cuenta
SMALLINT :=0;
clave
VARCHAR2(5) NOT NULL := HZM030297;
CONSTANTES:
limite
VARIANTES y AUXILIARES:
DEFAULT
num_max
SMALLINT DEFAULT 96;
valido BOOLEAN
DEFAULT FALSE;
%TYPE
credito
debito
NUMBER(7,2);
credito%TYPE;
%ROWTYPE
emp_reg
prueba%ROWTYPE;
CURSOR datos IS SELECT clave, nom, edad FROM prueba;
emp_reg2
datos%ROWTYPE;
En la seccin de declaraciones, se indican las variables, que sern usadas dentro del bloque
y sus tipos. Por ejemplo:
DECLARE
myBeer VARCHAR(20);
price NUMBER(6,2);
En algunos casos, es posible que se desee que el tipo de una variable coincida con el tipo
usado para una columna de una tabla determinada; en esos casos, se puede usar la construccin:
DECLARE
myBeer Beers.name%TYPE;
Con lo cual, se logra que la variable myBeer tenga el mismo tipo que la columna name de
la tabla Beers.
Tambin es posible inicializar las variables, mediante el operador:=. Adems, mediante
el uso del mismo operador es posible hacer asignaciones en el cuerpo del programa. Por
ejemplo:
DECLARE
price NUMBER := 300;
BEGIN
price := price + 150;
END;
run
La ejecucin de este bloque no tendr ningn efecto, ya que no se estn haciendo cambios
sobre la base de datos. Adems, es posible usar sentencias condicionales y ciclos dentro
de los bloques de PL/SQL.
/ 18
u.d. 1
NIVEL II
8. EXPRESIONES Y COMPARACIONES
Algunas reglas importantes deben ser tomadas en cuenta al realizar una comparacin; a
continuacin, se listan algunas de ellas:
Las comparaciones que involucren valores NULL, siempre nos devolvern NULL.
Al aplicar el operador NOT a un valor NULL, devolver NULL.
Si una expresin condicional evala NULL, no se ejecutar NADA.
Si un argumento NULL es pasado a una funcin, sta devolver NULL.
Referencia de funciones
9. TIPOS DE DATOS
Cada constante y variable tiene un tipo de dato en el cual se especifica el formato de almacenamiento, restricciones y rango de valores vlidos.
PL/SQL proporciona una variedad predefinida de tipos de datos ESCALARES y COMPUESTOS, que contienen componentes internos que pueden ser manipulados en forma individual.
Casi todos los tipos de datos manejados por PL/SQL son similares a los soportados por
SQL.
/ 19
u.d. 1
NIVEL II
TABLE
Una tabla es un tipo de dato compuesto, donde el tamao es ilimitado, ya que puede ser
incrementado de manera dinmica.
Una tabla esta formada por una columna y una llave primaria, donde la columna puede ser
de cualquier tipo escalar, y la clave primaria deber ser de tipo BINARY_INTEGER.
Debe ser declarada en 2 pasos bsicos:
Definir un TYPE TABLE
Definir el identificador de tipo TABLE
Ejemplo:
TYPE nombres_emp IS TABLE OF prueba.nom%TYPE
INDEX BY BINARY_INTEGER;
nom_tab nombres_emp;
Para hacer referencia a los elementos de una tabla, debe realizarse de la siguiente
manera:
nom_tab(1) := Alberto;
NESTED TABLE
Una tabla anidadas o jerarquizadas es un array unidimensional ilimitado y desordenado
de elementos del mismo tipo de datos. Es similar a Tablas INDEX-BY, salvo que la clusula
INDEX BY BINARY_INTEGER no est en su definicin. Un array de tablas anidadas no tiene
ningn lmite mximo y puede llegar a ser escaso, esto significa que los elementos en
cualquier ndice dinmico pueden ser suprimidos. Por eso, se debe crear una tabla anidada
con todos sus elementos en una orden secuencial. El nmero mximo de elementos en una
tabla anidada es 2GB.
Una tabla anidada es, generalmente, un array unidimensional, a menos que est definida
de otra manera a una coleccin de niveles mltiples; en este caso, simula un array de ms
de una dimensin.
VARRAY
Son los arrays uni-dimensionales que estn limitados por un nmero mximo de elementos.
Se utilizan para almacenar un nmero fijo de elementos en un array definido. Esto ayuda a
materializar colecciones de tamao fijo.
/ 20
u.d. 1
NIVEL II
NOTA:
Los tipos NESTED TABLE y VARRAY se vern ms detalladamente en la unidad de PL/SQL Avanzado.
CLOB
Un CLOB es un objeto grande de carcter, que puede almacenar hasta 4GB de datos tipo
carcter. CLOBs es de dos tipos, CLOB y NCLOB.
CLOB se refiere a datos carcter en el juego de caracteres de la base de datos. NCLOB se
refiere a datos carcter en el conjunto de datos carcter nacional. Los datos en columnas
CLOB o NCLOB pueden tener un ancho fijo o variable, y puede ser single-byte o multiplebyte. Se puede tener varias columnas del tipo CLOB en una sola tabla.
Ejemplo:
CREATE TABLE clob_tab
(id NUMBER PRIMARY KEY,
clob_data CLOB);
BLOB
Es un LOB que puede almacenar hasta 4GB de datos no estructurados o binarios. Se pueden
definir atributos de un tipo de objeto o de columnas de una tabla de la base de datos en
fecha el tipo BLOB. Se pueden tener varias columnas del tipo BLOB en una sola tabla.
Ejemplo:
CREATE TABLE blob_tab
(id NUMBER PRIMARY KEY,
blob_data BLOB);
Cambiar a NULL
BFILE
Un BFILE es un archivo binario grande, que puede almacenar hasta 4GB de datos binarios,
y est situado en el sistema de ficheros del sistema operativo. Solamente se almacena un
puntero externo a este archivo en la base de datos. Se pueden tener varias columnas del
tipo BFILE en una sola tabla.
Ejemplo:
CREATE TABLE bfile_tab
(id NUMBER PRIMARY KEY,
bfile_data BFILE);
/ 21
u.d. 1
NIVEL II
Estructura IF
La sintaxis es:
IF (expresin) THEN
-- Instrucciones
ELSEIF
-- Instrucciones
ELSE
-- Instrucciones
END IF;
Ejemplo:
DECLARE
a number := 50;
b number := -20;
BEGIN
IF (a>b) THEN
dbms_output.put_line(A is greater than B);
ELSIF (a<b) THEN
dbms_output.put_line(A is less than B);
ELSE
dbms_output.put_line(A is equal to B);
END IF;
Estructura CASE:
CASE SELECT r
WHEN value1 THEN action1;
WHEN value2 THEN action2;
WHEN value3 THEN action3;
... ...
ELSE
actionN;
END CASE;
Ejemplo:
CASE report_choice
WHEN 1 THEN p_proc_report1;
WHEN 2 THEN p_proc_report2;
WHEN 3 THEN p_proc_report3;
WHEN 4 THEN p_proc_report4;
ELSE dbms_output.put_line(Invalid option.);
END CASE;
/ 22
u.d. 1
NIVEL II
Estructura LOOP:
Simple:
LOOP
-- Instrucciones
END LOOP;
Compuesto:
LOOP
-- Instrucciones
IF (expresion) THEN
-- Instrucciones
EXIT;
END IF;
END LOOP;
Ejemplo:
DECLARE
line_length NUMBER := 50;
separator VARCHAR2(1) := =;
actual_line VARCHAR2(150);
i NUMBER := 1;
BEGIN
LOOP
actual_line := actual_line || separator;
EXIT WHEN i = line_length;
i:= i + 1;
END LOOP;
DBMS_OUTPUT.PUT_LINE(actual_line);
END;
Estructura WHILE:
WHILE (expresion) LOOP
-- Instrucciones
END LOOP;
Ejemplo:
DECLARE
line_length NUMBER := 50;
separator VARCHAR2(1) := =;
actual_line VARCHAR2(150);
idx NUMBER := 1;
BEGIN
WHILE (idx<=line_length) LOOP
actual_line := actual_line || separator;
idx := idx +1 ;
END LOOP;
DBMS_OUTPUT.PUT_LINE(actual_line);
END;
/
/ 23
u.d. 1
NIVEL II
Ejemplo:
DECLARE
line_length NUMBER := 50;
separator VARCHAR2(1) := =;
actual_line VARCHAR2(150);
BEGIN
FOR idx in 1..line_length LOOP
actual_line := actual_line || separator;
END LOOP;
DBMS_OUTPUT.PUT_LINE(actual_line);
END;
/
INSERT
Aade filas a una tabla. Posee varios formatos posibles:
La sintaxis es:
INSERT INTO <nombre-tabla> VALUES (<serie de valores>)
El orden en el que se asignen los valores en la clusula VALUES tiene que coincidir con el
orden en que se definieron las columnas en la creacin del objeto tabla, dado que los valores
se asignan por posicionamiento relativo.
INSERT INTO <nombre-tabla> (<columna1>, <columna2>.....) VALUES (<valor1>, <valor2>....)
En este caso, los valores se asignarn a cada una de las columnas mencionadas por posicionamiento relativo, siendo necesario que, por lo menos, se asignen valores a todas aquellas
columnas que no admiten valores nulos en la tabla.
Asigna a las columnas los valores recuperados en la sentencia Select. Inserta en la tabla
todas las filas que se recuperen en la Select.
INSERT INTO <nombre-tabla> SELECT * FROM <nombre-tabla-fuente>
En este caso, las estructuras de las tablas tienen que ser iguales.
Si no se inserta ninguna fila, los atributos devuelven los siguientes valores:
/ 24
u.d. 1
NIVEL II
-> TRUE
-> FALSE
-> 0
Si se dan de alta una o mas filas, los atributos devuelven los siguientes valores:
SQL%NOTFOUND
SQL%FOUND
SQL%ROWCOUNT
-> FALSE
-> TRUE
-> Nmero de filas insertadas
UPDATE
Actualiza valores de una o ms columnas para un subconjunto de filas de una tabla.
UPDATE <nombre-tabla>
SET <columna1> = valor1 [, <columna2> = valor2 ...?
[WHERE <condicin>?
Actualiza los campos correspondientes junto con los valores que se le asig nen, en el subconjunto de filas que cumplan la condicin de seleccin. Si no
se pone condicin de seleccin, la UPDATE se da en todas las filas de la tabla.
Si se desea actualizar a nulos, se asignar el valor NULL.
Si no se actualiza ninguna fila, los atributos devuelven los siguientes valores:
SQL%NOTFOUND
SQL%FOUND
SQL%ROWCOUNT
-> TRUE
-> FALSE
-> 0
Si se actualizan una o mas filas, los atributos devuelven los siguientes valores:
SQL%NOTFOUND
SQL%FOUND
SQL%ROWCOUNT
-> FALSE
-> TRUE
-> Nmero de filas actualizadas
DELETE
Borra una o ms filas de una tabla. La sintaxis es la siguiente:
DELETE FROM <nombre-tabla>
[WHERE <condicin>?
-> TRUE
-> FALSE
-> 0
Si se borran una o mas filas, los atributos devuelven los siguientes valores:
SQL%NOTFOUND
SQL%FOUND
SQL%ROWCOUNT
-> FALSE
-> TRUE
-> Nmero de filas borradas
SELECT
La sintaxis bsica de una consulta de seleccin es la siguiente:
SELECT Campos FROM Tabla;
/ 25
u.d. 1
NIVEL II
En donde campos es la lista de campos que se deseen recuperar, y tabla es el origen de los
mismos, por ejemplo:
SELECT Nombre, Telefono FROM Clientes;
Para poder recuperar valores en variables, la consulta slo debe devolver una fila. Las
excepciones predefinidas ms comunes que nos podemos encontrar son:
Si la consulta no devuelve ninguna fila:
Se produce la excepcin predefinida NO_DATA_FOUND
El error ORACLE (SQLCODE) ORA-01403
El mensaje de error (SQLERRM) no data found
SQL%NOTFOUND
SQL%FOUND
SQL%ROWCOUNT
-> TRUE
-> FALSE
-> 0
-> FALSE
-> TRUE
SQL%ROWCOUNT
-> 2
NOTA:
Todas estas sentencias se han visto con detalle en el manual de SQL.
/ 26
u.d. 1
NIVEL II
Donde record_type_name es el nombre que identifica la estructura del nuevo registro que
contiene campos individuales, con los nombres field_name1 al field_nameN. Observar que
cada campo tiene un tipo de dato especificado (que puede ser escalar o subtipo definido
por el usuario, u otro tipo de registro), una restriccin (constraint) opcional NOT NULL,
y una clusula DEFAULT, con los valores iniciales especificados por value1 a travs de
valueN. Alternativamente, los valores iniciales se pueden especificar para usar la asignacin
inicial con la sintaxis:= seguida de un valor. Aqu, assign1 y assignN son expresiones que
evalan un valor con el mismo tipo de dato que el tipo de dato especificado por el campo
correspondiente.
Ejemplo:
TYPE hrc_org_rec IS RECORD
(hrc_org_id NUMBER,
hrc_descr VARCHAR2(20),
org_short_name VARCHAR2(30));
Un ejemplo completo que combina los dos pasos precedentes es como sigue:
DECLARE
TYPE hrc_org_rec IS RECORD
(hrc_org_id NUMBER,
hrc_descr VARCHAR2(20),
org_short_name VARCHAR2(30));
v_example_rec hrc_org_rec;
BEGIN
/* Do some processing */
null;
END;
/
/ 27
u.d. 1
NIVEL II
Esta sintaxis es similar a ls sintaxis que se utiliza para tener acceso a una columna en una
tabla de la base de datos, usando el sintaxis de <table_name>.<column_name>. Esto hace
que haya una analoga entre las tablas de la base de datos y los registros. Sin embargo,
una diferencia entre los dos es que las anteriores estn almacenadas en una base de datos,
mientras que los ltimos no estn y no se pueden almacenar en una base de datos.
Aqu est el ejemplo para el registro del hrc_org_rec, definido anteriormente:
DECLARE
TYPE hrc_org_rec IS RECORD
(hrc_org_id NUMBER,
hrc_descr VARCHAR2(20),
org_short_name VARCHAR2(30));
v_example_rec hrc_org_rec;
BEGIN
v_example_rec.hrc_org_id := 1001;
v_example_rec.hrc_descr := CEO/COO;
v_example_rec.org_short_name := Office of CEO/COO ABC Inc.;
dbms_output.put_line(An example record:);
dbms_output.new_line;
dbms_output.put_line(to_number(v_example_rec.hrc_org_id)|| ||
v_example_rec.hrc_descr|| ||
v_example_rec.org_short_name);
END;
/
/ 28
u.d. 1
NIVEL II
La inicializacin de registro es til cuando se est pasando registros como parmetros a los
subprogramas. Puede ser que pase un registro como parmetro, declarar una variable de
registro local del mismo tipo que la del parmetro, y despus inicializar esta variable local
con el parmetro que se est pasando.
/ 29
u.d. 1
NIVEL II
cursor debe ser exactamente igual a la estructura del registro. Esto significa que el tipo de
datos de cada columna y el nmero de columnas en la SELECT del cursor deben ser exactamente iguales a la de los campos de registro. Sin embargo, los nombres individuales de
la columna de la SELECT del cursor pueden ser diferentes.
Ejemplo:
DECLARE
TYPE hrc_org_rec IS RECORD
(hrc_org_id NUMBER,
hrc_descr VARCHAR2(20),
org_short_name VARCHAR2(30));
v_example_rec hrc_org_rec;
CURSOR csr_hrc_org IS
SELECT hrc_org_seq.nextval, h.hrc_descr, o.org_short_name
FROM org_tab o, hrc_tab h
WHERE o.hrc_code = h.hrc_code
AND h.hrc_code = 1;
BEGIN
OPEN csr_hrc_org;
dbms_output.put_line(An example output: );
dbms_output.new_line;
LOOP
FETCH csr_hrc_org INTO v_example_rec;
EXIT WHEN csr_hrc_org%NOTFOUND;
dbms_output.put_line(to_number(v_example_rec.hrc_org_id)|| ||
v_example_rec.hrc_descr|| ||
v_example_rec.org_short_name);
END LOOP;
CLOSE csr_hrc_org;
END;
/
12.2 %ROWTYPE
Registros orientados a tablas
Se ha visto que un registro de PL/ SQL es un tipo de dato compuesto por campos. Estos
campos se eligen y se agrupan arbitrariamente juntos para formar parte de un solo registro.
En muchos casos, puede ser necesario construir un registro que se parezca a la estructura
de una fila de una tabla de la base de datos. Este registro se llama un registro orientado a
tabla o registro de tabla. En este caso, los campos individuales estn formados por todas
las columnas de una fila de una tabla de la base de datos. Los campos de este registro
corresponden uno por uno, tanto en el nombre como en la estructura, a las columnas de la
tabla de la base de datos en la cual se basa el registro.
Para crear un registro de tabla se utiliza el operador %ROWTYPE.
La sintaxis es:
record_var_name table_name%ROWTYPE;
Donde la variable record_var_name del registro tiene la misma estructura de registro que
una fila, en la tabla identificada por table_name. Para definir este tipo de registros se declara
/ 30
u.d. 1
NIVEL II
directamente, sin tener que definir el tipo de registro. El tipo de registro se hereda de la
estructura de la fila de la tabla de la base de datos.
Para acceder a los campos individuales de este tipo de registro tambin se utiliza la notacin
del punto.
Ejemplo:
DECLARE
hrc_rec hrc_tab%ROWTYPE;
BEGIN
SELECT *
INTO
hrc_rec
FROM
hrc_tab
WHERE hrc_code = 1;
dbms_output.put_line(An example record:);
dbms_output.new_line;
dbms_output.put_line(to_char(hrc_rec.hrc_code)|| ||hrc_rec.hrc_descr);
END;
/
La sintaxis es:
record_var_name cursor_name%ROWTYPE;
Donde la variable record_var_name del registro tiene la misma estructura que el registro
de una fila del cursor identificado por cursor_name. Al igual que con los registros de tabla,
se declara directamente sin tener que definir el tipo de registro, porque se hereda de la
estructura de la fila del cursor.
Para acceder a los campos individuales de este tipo de registro tambin se utiliza la notacin
del punto.
Ejemplo:
DECLARE
CURSOR csr_hrc IS
SELECT * FROM hrc_tab ORDER BY 1;
hrc_rec csr_hrc%ROWTYPE;
BEGIN
OPEN csr_hrc;
dbms_output.put_line(Hierarchy records: );
dbms_output.new_line;
LOOP
FETCH csr_hrc INTO hrc_rec;
EXIT WHEN csr_hrc%NOTFOUND;
dbms_output.put_line(to_char(hrc_rec.hrc_code)|| ||hrc_rec.hrc_descr);
/ 31
u.d. 1
NIVEL II
Imagen1-2-2
/ 32
u.d. 1
NIVEL II
Donde table_type_name identifica la estructura del nuevo Tablas INDEX-BY, que contiene
los elementos individuales del tipo de datos. Observar que cada elemento tiene un ndice
asociado a l y a un valor. El tipo de datos del elemento puede ser cualquier tipo escalar como
VARCHAR2, NUMBER, DATE, BOOLEAN , o puede ser una referencia a un tipo escalar,
usando %TYPE o un tipo de registro. Se puede especificar una constraint NOT NULL opcional
para indicar que cada elemento creado en Tablas INDEX-BY debe ser un valor no nulo.
Ejemplo:
TYPE num_tab IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
Los parntesis son obligatorios. Observar que se utiliza el nombre de la variable de la tabla
real, y no el nombre del tipo de la tabla.
/ 33
u.d. 1
NIVEL II
Ejemplo:
DECLARE
TYPE num_tab IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
v_example_tab num_tab;
v_num NUMBER := 13;
BEGIN
v_example_tab(1) := 1001;
v_example_tab(10) := 1002;
v_example_tab(-10) := 1003;
v_example_tab(v_num) := 1004;
dbms_output.put_line(An example array:);
dbms_output.new_line;
dbms_output.put_line(to_char(v_example_tab(1))|| ||
to_char(v_example_tab(10))|| ||
to_char(v_example_tab(-10))|| ||
to_char(v_example_tab(v_num)) );
END;
/
/ 34
u.d. 1
NIVEL II
En este caso, el ndice y el valor de cada fila en la tabla en blanco se fija a los valores de la
fila correspondiente en la tabla origen. Esto es bastante limpio, implica menos cdigo, y
provoca menos errores que la asignacin individual o la asignacin en un loop.
/ 35
NIVEL II
u.d. 1
Imagen1-2-3
/ 36
u.d. 1
NIVEL II
Ejemplo:
DECLARE
TYPE hrc_org_rec IS RECORD
(hrc_org_id NUMBER,
hrc_descr VARCHAR2(20),
org_short_name VARCHAR2(30));
TYPE hrc_org_tab IS TABLE OF hrc_org_rec INDEX BY BINARY_INTEGER;
v_example_tab hrc_org_tab;
CURSOR csr_hrc_org IS
SELECT hrc_org_seq.nextval hrc_org_id, h.hrc_descr, o.org_short_name
FROM org_tab o, hrc_tab h
WHERE o.hrc_code = h.hrc_code
AND h.hrc_code = 1;
i BINARY_INTEGER := 1;
BEGIN
FOR idx IN csr_hrc_org LOOP
v_example_tab(i).hrc_org_id := idx.hrc_org_id;
v_example_tab(i).hrc_descr := idx.hrc_descr;
v_example_tab(i).org_short_name := idx.org_short_name;
i := i + 1;
END LOOP;
dbms_output.put_line(An example output: );
dbms_output.new_line;
FOR j IN 1..v_example_tab.COUNT LOOP
dbms_output.put_line(to_char(v_example_tab(j).hrc_org_id)|| ||
v_example_tab(j).hrc_descr|| ||
v_example_tab(j).org_short_name);
END LOOP;
END;
/
13. CURSORES
Un cursor es un manejador o apuntador para el rea de contexto. Por medio de ste un
programa PL/SQL puede controlar el rea de contexto.
Hay dos tipos de cursores:
Los cursores implcitos son creados por Oracle para manejar alguna instruccin SQL,
y no son declarados por el programador.
Los cursores explcitos son aquellos que se declaran, generalmente, por medio de
una consulta SQL.
Imagen1-2-4
/ 37
NIVEL II
u.d. 1
Imagen1-2-5-
Una vez que se haya definido un cursor, se puede utilizar para procesar las filas contenidas
en el resultset. Para ello, se siguen los siguientes pasos:
1. Abrir el cursor.
/ 38
u.d. 1
NIVEL II
3. Cerrar el cursor.
4. Hay dos maneras de utilizar un cursor explcito una vez que se haya definido: usando
OPEN, FETCH, y CLOSE, y usando un cursor FOR LOOP. Se puede hacer esto en la
seccin de un bloque PL/SQL entre BEGIN y END.
Cerrar el cursor
La sintaxis es:
CLOSE nombre_cursor;
/ 39
u.d. 1
NIVEL II
dbms_output.put_line(rpad(v_org_rec.hrc_descr,20, )|| ||
rpad(v_org_rec.org_short_name,30, ));
END LOOP;
/* CLose the cursor */
CLOSE csr_org;
END;
/
El cursor_name es el nombre del cursor y el idx es el ndice del cursor FOR LOOP, y es de
tipo del cursor_name %ROWTYPE.
Procesar los datos en el sistema activo.
Ejemplo:
create or replace package EJEM_CURSOR is
procedure imprime_facturas;
end;
create or replace package body EJEM_CURSOR is
--- Este procedimiento genera un listado de proveedores
-- y las facturas que ha emitido
-procedure IMPRIME_FACTURAS is
cve_prov
proveedores.clave%type;
nom_prov
proveedores.nombre%type;
CURSOR c_proveedores IS
select clave, nombre FROM proveedores;
CURSOR c_facturas IS
select factura, fecha FROM facturas where
proveedor_clave=cve_prov order by fecha;
fact
c_facturas%rowtype;
begin
OPEN c_proveedores;
loop
FETCH c_proveedores INTO cve_prov, nom_prov;
exit when c_proveedores%notfound;
dbms_output.put_line(PROVEEDOR: || nom_prov);
for fact in c_facturas loop
dbms_output.put_line(
||
fact.factura || ( || fact.fecha || ));
end loop;
dbms_output.put_line( );
end loop;
CLOSE c_proveedores;
end;
end;
/ 40
u.d. 1
NIVEL II
Imagen1-2-6
Una vez que se haya definido el cursor, se utiliza la clusula WHERE CURRENT OF para
procesar las filas devueltas. Se puede utilizar esta clusula en una sentencia UPDATE o
DELETE.
La sintaxis es:
WHERE CURRENT of cursor_name;
Donde cursor_name es el nombre del cursor, definido con la clusula FOR UPDATE.
El mecanismo de los cursores SELECT FOR UPDATE trabaja as:
SELECT FOR UPDATE pone bloqueo en las filas recuperadas por el cursor. Si no puede
obtener un bloqueo porque otra sesin ha bloqueado las filas especficas, espera hasta
que pueda ser bloqueado. Un COMMIT o ROLLBACK en la sesin correspondiente libera
los bloqueos mantenidos por otras sesiones.
Para cada fila identificada por el cursor, actualiza la columna especificada de esa fila. Esto es
parecido a una sentencia ordinaria UPDATE o CANCEL dentro de un bucle, donde el cursor
recorre la tabla actualizada otra vez para determinar la fila actual que se va a modificar.
/ 41
final de leccin
FINAL DE LA LECCIN 2
Notas de trabajo del alumno:
Conclusiones:
/ 42
u.d. 1
NIVEL II
Imagen1-3-1
Excepciones predefinidas
Las excepciones predefinidas corresponden a errores comunes en SQL algunas de ellas
son:
/ 43
u.d. 1
NIVEL II
Imagen1-3-2
/ 44
u.d. 1
NIVEL II
secuencia_de_instrucciones2;
WHEN OTHERS THEN
secuencia_de_instrucciones3;
END;
Cuando se usa WHEN OTHERS y se desea saber qu error ocurri, las funciones SQLCODE
y SQLERRM proporcionan esta informacin.
SQLCODE
Devuelve el cdigo del error que lanz la excepcin.
SQLERRM
Devuelve el mensaje de error correspondiente al error que lanz la excepcin.
Esta funcin tambin acepta un argumento numrico, el cual debe de corresponder al texto
asociado con ese nmero.
numero_de_error
Es un nmero entre -20,000 y 20,999.
mensaje_de_error
Es el texto asociado con este error. Su longitud debe ser menor de 512 caracteres.
mantener_error
Es booleano y opcional. Si su valor es TRUE, el error es agregado a la lista de errores lanzados. Si es FALSE, el error reemplaza a la lista actual de errores.
/ 45
u.d. 1
NIVEL II
BEGIN
BEGIN
RAISE A;
EXCEPTION
WHEN A THEN
...
END;
END;
EXCEPTION
WHEN OTHERS THEN
END;
EXCEPTION
WHEN OTHERS THEN
...
END;
/ 46
u.d. 1
NIVEL II
/ 47
u.d. 1
NIVEL II
15. SUBPROGRAMAS
Los subprogramas en PL/SQL pueden recibir parmetros y ser invocados. PL tiene dos tipos
de subprogramas llamados procedimientos y funciones. Generalmente, usamos un procedimiento para ejecutar una
accin y una funcin para
calcular un valor.
Imagen1-3-3
/ 48
u.d. 1
NIVEL II
declaraciones del SQL, que dan lugar a un mejor funcionamiento con pocas llamadas a la
base de datos, y reducen el trfico de red en arquitecturas de dos niveles y aplicaciones de
tres capas. Tambin, en esta versin de PL/SQL 9i, los subprogramas almacenados pueden
utilizar la compilacin nativa, la conversin subsecuente al cdigo de C, y el almacenamiento del cdigo automtico en comparacin con cdigo interpretado. Esto permite una
ejecucin ms rpida.
15.1 PROCEDIMIENTOS
La sintaxis es:
CREATE [ OR REPLACE] PROCEDURE nombre
[(parametro1, [parametro2, ....])]
IS | AS
[declaraciones locales]
BEGIN
[Estructuras Ejecutables]
[EXCEPTION]
Majenadores de Excepciones
END [nombre];
/ 49
u.d. 1
NIVEL II
Imagen1-3-4
IN (por defecto): Pasa un valor constante desde el entorno donde se llama al procedimiento.
IN OUT: Para un valor desde el entorno que llama al procedimiento y un valor posible
diferente desde el procedimiento cuando regresa de la llamada, usando el mismo
parmetro.
15.2 FUNCIONES
Una funcin es un subprograma que calcula un valor. Las funciones y los procedimientos
estn estructurados de la misma forma, excepto que las funciones cuentan con la clusula
RETURN.
La sintaxis es:
CREATE OR REPLACE FUNCTION nombre [(parametro1, [parametro2, ....])] RETURN tipo_de_dato
IS
[declaraciones locales]
BEGIN
[Estructuras Ejecutables]
[EXCEPTION]
Manejadores de Excepciones
END [nombre];
/ 50
u.d. 1
NIVEL II
Imagen1-3-5
/ 51
u.d. 1
NIVEL II
Restricciones:
Las funciones no pueden modificar datos en las tablas. No pueden ejecutar INSERT, UPDATE
o DELETE.
Slo las funciones locales que se referencian en la lista de la SELECT, en la clusula VALUES
de un INSERT o en la clusula SET de un UPDATE pueden actualizar una variable definida
en un paquete.
No pueden actualizar variables dentro de un paquete las funciones referenciadas en las
clusulas CONNECT BY, START WITH, ORDER BY o GROUP BY.
Las funciones remotas no pueden leer ni escribir el estado de un paquete. Cada vez que se
accede a un enlace de base de datos, se establece una nueva sesin en la base de datos
remota.
Las funciones que leen o escriben en el estado de un paquete no pueden utilizar paralelismo.
15.3 PAQUETES
Un paquete es una unidad del programa almacenada, que agrupa objetos lgicamente
relacionados del PL/SQL, y los almacena en la base de datos como un solo objeto. Los
objetos relacionados PL/SQL pueden ser constantes, variables, cursores, excepciones,
procedimientos, y/o funciones. Un paquete PL/SQL tiene dos partes: la especificacin del
paquete y el cuerpo del paquete.
La especificacin del paquete consiste en las declaraciones de los objetos relacionados
que se incluirn en el paquete. En el caso de procedimientos y de funciones, solamente la
firma o la cabecera del procedimiento o de la funcin se incluye en la especificacin del
paquete. La puesta en prctica real de estos procedimientos y funciones se da en el cuerpo
del paquete. Adems, el cuerpo del paquete puede contener otras declaraciones, como
variables, constantes, cursores, e, incluso, procedimientos y funciones no definidos en la
especificacin del paquete.
Las declaraciones en la especificacin del paquete se llaman declaraciones Pblicas, pues su
alcance es la sesin entera de la base de datos, y todos los programas de aplicaciones que
tienen acceso a dicho paquete pueden referirse a ellos. Las declaraciones, los procedimientos
y las funciones adicionales definidos en el cuerpo del paquete se llaman Privadas, porque
son accesibles solamente para el creador del paquete. De esta manera, se puede referir a
ellos solamente en el cdigo contenido en el cuerpo del paquete, y no por otras aplicaciones
/ 52
u.d. 1
NIVEL II
La sintaxis es:
PACKAGE nombre IS
-- Declaraciones de tipos y objetos pblicos
-- especificaciones de los subprogramas
END [nombre];
PACKAGE BODY nombre IS
-- Declaraciones de tipos y objetos privados
-- Cuerpos de los subprogramas
[BEGIN
-- Estructura de Inicializacin ]
END [name];
Ejemplo:
CREATE OR REPLACE PACKAGE BODY orgMaster
IS
-- Procedimiento para crear un Nuevo registro en la tabla org_tab
PROCEDURE createOrg (ip_hrc_code NUMBER,
ip_org_id NUMBER,
ip_org_short_name VARCHAR2,
ip_org_long_name VARCHAR2,
op_retcd OUT NUMBER,
op_err_msg OUT VARCHAR2)
IS
BEGIN
INSERT INTO org_tab VALUES
(ip_hrc_code, ip_org_id, ip_org_short_name, ip_org_long_name);
op_retcd := 0;
EXCEPTION WHEN DUP_VAL_ON_INDEX THEN
op_retcd := -1;
op_err_msg := Organization with Id ||TO_CHAR(ip_org_id)||
already exists.;
WHEN OTHERS THEN
op_retcd := SQLCODE;
op_err_msg := SQLERRM;
END createOrg;
-- Procedimiento para actualizar los nombres cortos y largos de un registro de la tablan
org_tab
-- Basado en la entrada org_id
PROCEDURE updateOrg(ip_org_id NUMBER,
ip_org_short_name VARCHAR2,
ip_org_long_name VARCHAR2,
op_retcd OUT NUMBER,
op_err_msg OUT VARCHAR2)
IS
BEGIN
UPDATE org_tab
/ 53
u.d. 1
NIVEL II
/ 54
u.d. 1
NIVEL II
SELECT 1
INTO
v_num
FROM
org_site_tab
WHERE org_id = ip_org_id
AND site_no = ip_site_no;
IF (v_num = 1) THEN
op_retcd := 0;
RETURN;
END IF;
EXCEPTION WHEN NO_DATA_FOUND THEN
INSERT INTO org_site_tab VALUES (ip_org_id, ip_site_no);
END;
op_retcd := 0;
EXCEPTION WHEN OTHERS THEN
op_retcd := SQLCODE;
op_err_msg := SQLERRM;
END assignSiteToOrg;
END orgMaster;
/
Identificar paquetes
Para identificar a los tipos, objetos y subprogramas declarados dentro de un paquete debe
emplearse la notacin siguiente:
package_nombre.type_name
package_nombre.objeto_name
package_nombre.subprograma_name
Ejemplo:
DECLARE
v_retcd NUMBER;
v_err_msg VARCHAR2(1000);
BEGIN
orgMaster.createOrg(3, 1011,Office of Dir. SSL,Office of Dir. SSL,
v_retcd, v_err_msg);
IF (v_retcd <> 0) THEN
DBMS_OUTPUT.PUT_LINE(ERR: ||v_err_msg);
END IF;
END;
/
Objetos privados
Estos objetos son accesibles solamente al cuerpo del propio paquete y tambin puede
referirse a ellos sin la notacin del punto.
/ 55
u.d. 1
NIVEL II
La sintaxis es:
[BEGIN
sequence_of_statements ... ]
En este ejemplo, se muestra el cuerpo del paquete orgMaster, con una seccin de inicializacin incluida:
CREATE OR REPLACE PACKAGE BODY orgMaster
IS
-- Proc para borrar filas de org_site_tab table
-- Primero es necesario borrar las filas de org_tab.
-- Este proc llama a removeOrg
PROCEDURE removeOrgSites(ip_org_id NUMBER,
op_retcd OUT NUMBER,
op_err_msg OUT VARCHAR2)
IS
BEGIN
DELETE org_site_tab WHERE org_id = ip_org_id;
op_retcd := 0;
EXCEPTION WHEN OTHERS THEN
op_retcd := SQLCODE;
op_err_msg := SQLERRM;
END removeOrgSites;
- Proc para crear un Nuevo registro en in org_tab
PROCEDURE createOrg (ip_hrc_code NUMBER,
ip_org_id NUMBER,
ip_org_short_name VARCHAR2,
ip_org_long_name VARCHAR2,
op_retcd OUT NUMBER,
op_err_msg OUT VARCHAR2)
IS
BEGIN
INSERT INTO org_tab VALUES
(ip_hrc_code, ip_org_id, ip_org_short_name, ip_org_long_name);
op_retcd := 0;
EXCEPTION WHEN DUP_VAL_ON_INDEX THEN
op_retcd := -1;
op_err_msg := Organization with Id ||TO_CHAR(ip_org_id)||
already exists.;
WHEN OTHERS THEN
op_retcd := SQLCODE;
op_err_msg := SQLERRM;
END createOrg;
-- Proc para actualizar los nombres cortos y largos de org_tab
-- basados en la entreada de org_id
PROCEDURE updateOrg(ip_org_id NUMBER,
ip_org_short_name VARCHAR2,
ip_org_long_name VARCHAR2,
op_retcd OUT NUMBER,
op_err_msg OUT VARCHAR2)
/ 56
u.d. 1
NIVEL II
IS
BEGIN
UPDATE org_tab
SET org_short_name = ip_org_short_name,
org_long_name = ip_org_long_name
WHERE org_id = ip_org_id;
IF (SQL%NOTFOUND) THEN
op_retcd := -1;
op_err_msg := Organization with Id ||TO_CHAR(ip_org_id)||
does not exist.;
RETURN;
END IF;
op_retcd := 0;
EXCEPTION WHEN OTHERS THEN
op_retcd := SQLCODE;
op_err_msg := SQLERRM;
END updateOrg;
-- Proc para borrar un registro en org_tab
PROCEDURE removeOrg(ip_org_id NUMBER,
op_retcd OUT NUMBER,
op_err_msg OUT VARCHAR2)
IS
BEGIN
removeOrgSites(ip_org_id, op_retcd, op_err_msg);
IF (op_retcd <> 0) then
RETURN;
END IF;
DELETE org_tab WHERE org_id = ip_org_id;
IF (SQL%NOTFOUND) THEN
op_retcd := -1;
op_err_msg := Organization with Id ||TO_CHAR(ip_org_id)||
does not exist.;
RETURN;
END IF;
op_retcd := 0;
EXCEPTION WHEN OTHERS THEN
op_retcd := SQLCODE;
op_err_msg := SQLERRM;
END removeOrg;
-- Funcin que devuelve una fila de org_tab.
-- Devuelve un conjunto de resultados del tipo REF CURSOR, definido en la especificacin
del paquete
FUNCTION getOrgInfo(ip_org_id NUMBER) RETURN rc
IS
v_rc rc;
BEGIN
OPEN v_rc FOR SELECT * FROM org_tab WHERE org_id = ip_org_id;
RETURN (v_rc);
EXCEPTION WHEN OTHERS THEN
RAISE_APPLICATION_ERROR(-20001, SQLERRM);
END getOrgInfo;
-- Funcin que devuelve todas las filas de org_tab.
-- Devuelve un conjunto de resultados del tipo REF CURSOR, definido en la especificacin
del paquete
FUNCTION getAllOrgs(ip_hrc_code NUMBER) RETURN rc
IS
v_rc rc;
BEGIN
OPEN v_rc FOR SELECT * FROM org_tab WHERE hrc_code = ip_hrc_code;
RETURN (v_rc);
EXCEPTION WHEN OTHERS THEN
RAISE_APPLICATION_ERROR(-20002, SQLERRM);
END getAllOrgs;
-- Procedimiento para insertar un registro en la tabla org_site_tab based
/ 57
u.d. 1
NIVEL II
Donde:
WNDS: Si se aplica esta opcin, la funcin no puede modificar tablas de la base de datos.
(Writes No Database State).
WNPS: Si se aplica esta opcin, la funcin no puede cambiar los valores de variables de un
paquete pblico. (Writes No Package Status).
RNDS: Si se aplica esta opcin, la funcin no puede consultar ninguna tabla de la base de
datos. (Reads No Database State).
RNPS: Si se aplica esta opcin, la funcin no puede referenciar los valores de las variables
de un paquete pblico. (Reads No Database Status).
Este paquete sirve para alertar a los desarrolladores de aplicaciones con cdigo procedural,
que incumplen las restricciones de las funciones PL/SQL dentro de sentencias SQL.
Este paquete predefinido indica al compilador PL/SQL qu tipo de acciones pueden realizar
las funciones. Las sentencias SQL que incumplan estas reglas producen un error de com-
/ 58
u.d. 1
NIVEL II
pilacin.
El argumento WNDS debe indicarse SIEMPRE que se utilice RESTRICT_REFERENCES.
El propsito de indicar un nivel de depuracin en las funciones es identificar los errores en
tiempo de compilacin, en vez de esperar a la ejecucin.
Ejemplo:
Crear una funcin llamada COMP, dentro del paquete FINANZAS. La funcin ser invocada
desde sentencias SQL en bases de datos remotas. Por lo tanto, ser necesario indicar los
niveles de depuracin RNPS y WNPS, porque las funciones remotas no pueden nunca escribir
o leer el estado del paquete cuando se le invoca desde una sentencia SQL.
CREATE PACKAGE finanzas AS -- especificacin del paquete
interes REAL;
-- variable pblica del paquete
...
FUNCTION comp
(anos
IN NUMBER
cant
IN NUMBER
porc
IN NUMBER) RETURN NUMBER;
...
PRAGMA RESTRICT_REFERENCES(comp, WNDS, RNPS, WNPS);
END finanzas;
CREATE PACKAGE BODY finanzas AS -- cuerpo del paquete
FUNCTION comp
(anos
IN NUMBER
cant
IN NUMBER
porc
IN NUMBER) RETURN NUMBER IS
BEGIN
RETURN cant * POWER((porc/100) + 1, anos);
END comp;
...
END finanzas;
Se debe fijar el nivel de depuracin de una funcin en la zona de especificacin del paquete.
Si el paquete contiene varias funciones con el mismo nombre, el nivel de depuracin se
aplica a la ltima.
Para hacer cumplir reglas complejas de validacin, para evitar que se introduzcan
datos errneos o inadecuados en la base de datos.
Para hacer cumplir las relaciones complejas de la integridad de los datos que no se
/ 59
u.d. 1
NIVEL II
pueden especificar de
otra manera declaradamente; por ejemplo, una operacin de
conexin en cascada
de UPDATE en una
tabla hijo, siempre
que una fila del padre
sea actualizada.
Para
generar automticamente valores derivados.
Imagen1-3-6
/ 60
u.d. 1
NIVEL II
Tiene tres partes distintas: el evento que lo acciona, la restriccin que acciona, y el cuerpo
del trigger. Dependiendo del tipo de trigger, el evento que acciona puede ser un evento
DML, un evento del sistema, o un evento del usuario que causa el disparo del trigger. En el
trigger del ejemplo, el evento que acciona es la sentencia.
AFTER INSERT ON org_tab
En este caso, el evento es la operacin de INSERT en la tabla del org_tab, y este trigger se
dispara siempre que una operacin INSERT se ejecute en la tabla org_tab, despus de que
se escriba la nueva fila en la tabla del org_tab. La sentencia INSERT que causa el evento
del trigger se llama la sentencia disparadora. La restriccin que acciona es una condicin
opcional especificada como clusula WHEN, que hace que el cuerpo del trigger se ejecute
solamente cuando la condicin es TRUE. El cuerpo del trigger especifica el cdigo que se
ejecutar (es decir, la secuencia de las acciones que se realizarn) cuando l se dispare.
Ejemplo:
BEGIN
UPDATE sec_hrc_audit
SET num_rows = num_rows+1
WHERE hrc_code = :NEW.hrc_code;
IF (SQL%NOTFOUND) THEN
INSERT INTO sec_hrc_audit VALUES (:NEW.hrc_code, 1);
END IF;
END;
Un trigger no acepta parmetros, no incluye una seccin ejecutable con BEGIN y END, y
puede incluir una seccin opcional de sentencia y una seccin de la direccin de excepcin.
La seccin del BEGIN END puede incluir declaraciones de SQL y/o PL/SQL, llamadas a
procedimientos PL/ SQL y a las funciones (independientes o empaquetadas). Tambin, el
cuerpo del trigger puede ser una sola sentencia CALL, que invoca un procedimiento PL/SQL,
funcin o un procedimiento almacenado Java, publicado en PL/SQL.
/ 61
u.d. 1
NIVEL II
Triggers DML
Una DML acciona un trigger cuando una sentencia INSERT, UPDATE, o DELETE se ejecuta
en una tabla de la base de datos. Pueden ser clasificados ms a fondo como triggers de la
FILA o SENTENCIA, y especifican cuntas veces debe ser ejecutado el cuerpo del trigger.
Triggers INSTEAD-OF
INSTEAD-OF acciona el trigger en las declaraciones DML publicadas contra una vista relacionada o un objeto view. (Se vern mas adelante punto 3.11)
Donde trigger_name es el nombre del trigger de DML que es creado; triggering_event es una
combinacin INSERT, UPDATE, y/o DELETE; y el table_name es la tabla en la cual se est
ejecutando el INSERT, UPDATE; y/o DELETE. [OF column_name] la clusula que especifica
el column_name, que es actualizado en el caso de que una operacin UPDATE sea el evento
que lo acciona. BEFORE o AFTER especifica cundo se dispara el trigger (es decir, antes
o despus de que se ejecuta la sentencia DML); trigger_body es la secuencia de acciones
que se realizarn cuando se enciende el trigger, y la clusula [WHEN condicin] especifica
cualquier condicin que evala el cuerpo del trigger para ejecutarse.
Ejemplo:
/ 62
u.d. 1
NIVEL II
NIVEL DE LA SENTENCIA
Se dispara una vez para la sentencia que
acciona.
Se dispara, aunque el evento que acciona no
afecte a ninguna fila.
Se puede especificar BEFORE y AFTER
El cuerpo del TRIGGER no tiene acceso a los
datos de la fila.
Afectado actualmente por el evento que
acciona.
No bloquea las filas.
En el ejemplo del trigger ai_org_trig, el nuevo valor del hrc_code que se inserta se refiere
al cuerpo del trigger como:NEW.hrc_code, y lo hace a nivel de fila; pero, tb se puede hacer
cambiar este trigger a nivel de sentencia.
CREATE OR REPLACE TRIGGER ai_org_trig_statement
AFTER INSERT ON org_tab
BEGIN
FOR idx IN (SELECT hrc_code, COUNT(*) cnt
FROM org_tab
GROUP BY hrc_code) LOOP
UPDATE sec_hrc_audit
SET num_rows = idx.cnt
WHERE hrc_code = idx.hrc_code;
IF (SQL%NOTFOUND) THEN
INSERT INTO sec_hrc_audit VALUES (idx.hrc_code, idx.cnt);
END IF;
END LOOP;
END;
/ 63
u.d. 1
NIVEL II
Los valores de :OLD y :NEW son diferentes para los eventos triggers del INSERT, UPDATE,
y DELETE. En el caso de la sentencia INSERT, solamente se deinfe :NEW. Para UPDATE
se definen los dos, :OLD y :NEW. Y en el caso de DELETE, solamente se define :OLD. Los
valores que se identifican con :OLD.column_name o :NEW.column_name son los resultados
indefinidos en los valores NULL.
/ 64
u.d. 1
NIVEL II
Ejemplo.
CREATE OR REPLACE TRIGGER ai_org_trig
AFTER INSERT ON org_tab
REFERENCING NEW AS new_org
FOR EACH ROW
WHEN (new_org.hrc_code <> 1)
BEGIN
UPDATE sec_hrc_audit
SET num_rows = num_rows+1
WHERE hrc_code = :new_org.hrc_code;
IF (SQL%NOTFOUND) THEN
INSERT INTO sec_hrc_audit VALUES (:new_org.hrc_code, 1);
END IF;
END;
/
/ 65
u.d. 1
NIVEL II
END IF;
ELSIF DELETING THEN
UPDATE sec_hrc_audit
SET num_rows = num_rows1
WHERE hrc_code = :
OLD.hrc_code;
END IF;
END;
/
Imagen1-3-8
Aunque hay 12 combinaciones posibles, se pueden definir varios triggers del mismo tipo
en la misma tabla. (Esto es posible a partir e PL/SQL 2.1.) Otra cosa importante es el orden
en la cual se disparan triggers.
El orden es:
BEFORE STATEMENT (se dispara una vez por sentencia DML, no importa a cuntas filas
afecta).
BEFORE ROW (se dispara una vez por cada fila afectada por la sentencia DML).
/ 66
u.d. 1
NIVEL II
AFTER STATEMENT (se dispara una vez por cada sentencia DML, no importa a cuantas
filas afecta).
Tambin es posible habilitar o deshabilitar todos los triggers en una tabla particular. Esto
se hace con la sentencia ALTER TABLE. La sintaxis es:
ALTER TABLE table_name ENABLE| DISABLE ALL TRIGGERS;
Ejemplo:
ALTER TABLE org_tab DISABLE ALL TRIGGERS;
/ 67
u.d. 1
NIVEL II
Para borrar un trigger en cualquier esquema, se debe conceder el privilegio DROP ANY
TRIGGER.
Para crear triggers del sistema a nivel de base de datos, adems del privilegio CREAT
TRIGGER o CREATE ANY TRIGGER, se debe conceder el privilegio ADMIN DATABASE
TRIGGER.
Todos los privilegios sobre los triggers se tienen que dar explcitamente, y no mediante una
regla. CREATE ANY TRIGGER, ALTER ANY TRIGGER y DROP ANY TRIGGER trabajan sobre
esquemas, con excepcin del sistema. Se debe conceder a todos los objetos los privilegios
apropiados. Las declaraciones en el cuerpo del trigger se ejecutan bajo los privilegios del
propietario del trigger, no bajo privilegios del usuario que publica la sentencia que los
dispara.
1. Automticamente: Se hace cuando un trigger que es invalidado, debido a las dependencias, cuando se invoca la prxima vez.
/ 68
u.d. 1
NIVEL II
Este error salta durante la ejecucin del trigger, y no durante la creacin ni la compilacin
del trigger.
El nico caso en el que un trigger a nivel de fila puede leer o modificar la tabla que los
dispara es cuando la sentencia que acciona el trigger es una sentencia INSERT, que afecta
solamente a una fila. La sentencia INSERT SELECT no est permitida, aunque afecte a
una sola fila.
Para evitar errores mutating, se crea un ROW trigger que lea los nuevos valores de la fila
actual, y un STATEMENT trigger que pregunte o modifique la tabla mutating, basada en el
nuevo valor de la fila leda. Esto requiere un paquete PL/SQL para almacenar los nuevos valores ledos en el ROW trigger. Esta es una manera de manejar errores mutating. Un mtodo
alternativo para manejar las tablas mutating que implican errores es usando transacciones
autnomas. Sin embargo, este mtodo se debe utilizar con cuidado. El panorama perfecto para usar transacciones
autnomas para evitar errores
mutating es cuando la lgica
del trigger no es afectada por el
hecho de que los cambios realizados a la tabla que acciona
(es decir, la transaccin principal) no son visibles a la transaccin autnoma, hasta que
la transaccin principal est
confirmada. Los errores de la
tabla de Mutating son muy
inverosmiles en situaciones
normales, pero se debe tener
cuidado para evitarlos, si es
posible.
/ 69
u.d. 1
NIVEL II
Imagen1-3-9
Una vista no puede ser modificada por una sentencia DML normal si la consulta de la vista
contiene operadores SET, grupos de funciones, clusulas como GROUP BY, CONNECT BY,
START, el operador DISTINCT o joins. Por ejemplo, si una vista consiste en ms de una tabla,
un insert a la vista implica una insercin en una tabla y la actualizacin de otra. As que, se
escribe un trigger INSTEAD OF que se dispara cuando se escribe un insert contra la tabla
vista. En vez de una insercin normal, el cuerpo del trigger se ejecuta, y, como resultado,
se inserta en una tabla y se actualiza en otra.
La sintaxis es:
CREATE [OR REPLACE] TRIGGER trigger_name
INSTEAD OF triggering_event [OF column_name] ON view_name
[referencing_clause]
[FOR EACH ROW]
trigger_body ;
Ejemplo:
Lo primero, crear la vista hrc_org_site
CREATE VIEW hrc_org_site
AS
SELECT h.hrc_code, hrc_descr,
o.org_id, org_short_name,
org_long_name, os.site_no, site_descr
FROM
org_site_tab os, org_tab o, hrc_tab h, site_tab s
WHERE os.org_id = o.org_id
AND o.hrc_code = h.hrc_code
AND os.site_no = s.site_no;
/ 70
u.d. 1
NIVEL II
Para probar este trigger, se usa un INSERT, UPDATE, y DELETE contra la vista hrc_org_
site:
INSERT INTO hrc_org_site VALUES (11, ANALYST,1012, Office of Analyst,
Office of Analyst, 4, null);
UPDATE hrc_org_site SET org_short_name = Office of Analyst ABC Inc.,
org_long_name = Office of Analyst ABC Inc., site_no = 4
WHERE hrc_code = 11
AND org_id = 1012;
DELETE hrc_org_site WHERE org_id = 1012;
HRC_DESCR
----------------------ANALYST
ORG_SHORT_NAME
ORG_LONG_NAME
--------------------------------------Office of Analyst
-------------
Office of Analyst
/ 71
u.d. 1
NIVEL II
ORG_ID SITE_NO
--------- ----------1012
4
SQL> DELETE hrc_org_site WHERE org_id = 1012;
1 row deleted.
Tambin, permite crear triggers de base de datos durante eventos de usuario, como:
Logon y logout de sesin
Eventos de usuario como ejecucin de DDL (es decir, creacin, alteracin, y el borrado de
objetos de la base de datos)
La sintaxis para crear triggers en eventos del sistema y eventos de usuario:
CREATE [OR REPLACE] TRIGGER trigger_name
[BEFORE|AFTER] {triggering_event} ON [DATABASE|[schema.]SCHEMA]
[WHEN trigger_restriction]
trigger_body ;
/ 72
u.d. 1
BEFORE
NIVEL II
TIPO
VARCHAR2
(20)
NMERO
DESCRIPCIN
Evento del sistema que dispara el trigger. El nombre del
evento identifica a uno de los eventos del sistema.
Nmero de la instancia
VARCHAR2
(50)
NMERO
BOLEANO
VARCHAR2
(30)
Devuelve el nmero del error en una posicin dada respecto a la pila de errores: @@@1 tope de la pila.
Devuelve TRUE si el error est en la pila de errores; si
no, Devuelve FALSE.
Nombre del usuario de la conexin.
TIPO
VARCHAR
(20)
DESCRIPCIN
Tipo de objeto diccionario en el que se ejecut la operacin DDL
/ 73
u.d. 1
VARCHAR
(30)
VARCHAR
(30)
VARCHAR (2)
NIVEL II
ATRIBUTOS
Sys.Sysevent Sys.login_user Sys.Instance_num Sys.Database_name
Sys.sysevent Sys.login_user Sys.instance_num Sys.database_name
Sys.sysevent Sys.login_user Sys.instance_num Sys.database_name
Sys.server_error Sys.is_servererror
Ejemplo:
CREATE OR REPLACE TRIGGER ON_SHUTDOWN
BEFORE SHUTDOWN
ON DATABASE
BEGIN
<Enva una alerta a la base de datos de todos los accesos de los usuarios que usan
Advanced Queuing>
END;
/
Eventos de usuario
Los eventos de usuario son los eventos asociados a la conexin del usuario o de inicio y
trmino de una sesin, respuesta a un error del servidor, y a las operaciones DDL y DML.
EVENTO
LOGON
LOGOFF
BEFORE CREATE
AFTER CREATE
ATRIBUTOS
Sys.sysevent Sys.login_user
Sys.instance_num Sys.database_name
Sys.sysevent Sys.login_user
Sys.instance_num Sys.database_name
Sys.sysevent Sys.login_user Sys.instance_num
Sys.Database_name Sys.Dictionary_obj_type
Sys.Dictionary_obj_name Sys.Dictionary_obj_owner
/ 74
u.d. 1
NIVEL II
Ejemplo:
CREATE OR REPLACE TRIGGER On_Logon
AFTER LOGON
ON SCHEMA
BEGIN
DBMS_UTILITY.ANALYZE_SCHEMA(sys.login_user, ESTIMATE);
END;
/
Se puede hacer una DDL que revise el uso de los triggers AFTER CREATE, ALTER y DROP,
de la misma manera que se revis los triggers AFTER ROW INSERT, UPDATE y DELETE.
/ 75
final de leccin
Se puede crear un trigger AFTER CREATE de la siguiente manera, y rellenar la tabla siempre
que un objeto de la base de datos se cree en el esquema actual que el usuario ha registrado.
El cdigo es:
CREATE OR REPLACE TRIGGER after_ddl_creation
AFTER CREATE ON SCHEMA
BEGIN
INSERT INTO ddl_audit VALUES
(SYS.DICTIONARY_OBJ_NAME, SYS.DICTIONARY_OBJ_TYPE, SYSDATE, USER, NULL, NULL);
END;
/
La salida es:
FINAL DE LA LECCIN 3
Notas de trabajo del alumno:
Conclusiones:
/ 76
NIVEL II
Number(5)
Nombre
varChar(50)
Direccion
varChar(50)
Tabla DEPARTAMENTOS:
Numero
Number(5)
Centro
Number(5)
Todo departamento est en un centro de trabajo, que es un edificio o local, que puede
albergar ms de un departamento.
Director
Number(5)
Todo departamento tiene un solo director. Puede ser un director en propiedad o en funciones.
Un empleado slo puede ser director en propiedad de un nico departamento, pero puede
ser director provisional en funciones de varios.
Tipo_dir
Char(1)
Presuesto
Integer
Depto_jefe
Number(5)
Nombre
varChar(50)
Tabla EMPLEADOS:
Cod
Number(5)
Departamento
Number(5)
Telefono
Number(4)
Fecha_nacimiento Date
Fecha de nacimiento
Fecha_ingreso
Date
Salario
Integer
Comision
Integer
Slo es aplicable a los empleados que son vendedores o directores de vendedores, incluyendo hasta el director comercial. En el resto de empleados toma el valor nulo.
Son vendedores los que pertenecen al departamento de Direccin Comercial.
Num_hijos
Number(2)
Nmero de hijos
Nombre
varChar(50)
varChar(50)
NIVEL II
A. Salario medio de aquellos n empleados que tienen menor sueldo, siendo n el primer
argumento.
/78
NIVEL II
FROM Empleados
GROUP BY Departamento
HAVING COUNT(*) >= ALL (SELECT COUNT(*)
FROM Empleados
GROUP BY Departamento);
Dicha consulta tiene un coste bastante elevado y, por ello, se propone realizarla de dos
formas distintas, creando dos bloques PL/SQL, que cubren los siguientes razonamientos:
A. Creando una tabla: Crear una tabla llamada INFO_DPTOS, que contenga los valores de
cdigo de los departamentos y nmero de empleados en cada uno (sacar estos datos de
la tabla de empleados). A continuacin, se puede obtener el valor mximo de nmero de
empleados (consultando la tabla INFO_DPTOS), y recorrer la misma tabla para encontrar
qu departamentos coinciden con ese valor de nmero de empleados.
B. Sin crear ninguna tabla: Se pueden anidar dos cursores. El primero recorre la tabla
EMPLEADOS agrupada por el valor de departamento, y busca los valores de nmero de
empleados (N_EMP) y cdigo del departamento (COD_DPTO). A continuacin, se abre un
segundo cursor, que busca una tupla en EMPLEADOS agrupada por departamento, que
tenga un valor mayor de nmero de empleados que el que est en N_EMP. Si este cursor tiene
alguna tupla, entonces el departamento COD_DPTO no tiene el valor mximo de nmero
de empleados, por lo que se rechaza y seguimos buscando (se hace un nuevo FETCH del
primer cursor). En caso contrario, se selecciona ese departamento y seguimos buscando.
Realizar las dos opciones anteriores.
/79
NIVEL II
Solucin 2:
Declaramos la funcin DiferenciaSalario, que ordena los registros de la tabla de mayor a
menor salario, por lo que el primer registro ser el que tenga el mayor salario:
FUNCTION DiferenciaSalario (DNI IN NUMBER (8)) RETURN NUMBER (5) IS
Diferencia NUMBER (5);
/*El primer cursor extrae el registro con cdigo de empleado igual al DNI que se
introduce */
CURSOR cur_emp IS SELECT * FROM EMPLEADOS WHERE EMPLEADOS.Cod = DNI;
/80
NIVEL II
/*El segundo cursor extrae los registros con el mismo cdigo de departamento que el del
empleado anterior, ordenados de forma descendente por el Salario, de forma que el primer
registro tendr el salario mayor */
CURSOR cur1 IS SELECT * FROM EMPLEADOS EMP ORDER BY Salario DESC
WHERE
EMP.Departamento = cur_emp.Departamento;
V_cur1 cur1;
V_emp cur_emp;
BEGIN
OPEN cur_emp;
FETCH cur_emp INTO v_emp; --Se coge el registro del empleado
IF cur_emp%NOTFOUND THEN --No se ha encontrado el empleado
RETURN -1
ELSE
OPEN cur1;
FETCH cur1 INTO v_cur1; --Se cogen el registro del departamento
/* Se coge la primera fila, que es la que tiene el mayor salario */
diferencia := v_cur1.Salario v_emp.Salario
RETURN diferencia;
END DiferenciaSalario;
Solucin 3:
Se declara el procedimiento CambiarDepto:
PROCEDURE CambiarDepto (DNI IN NUMBER (8),deptoDestino IN NUMBER(5))
IS
v_cont BINARY_INTEGER
/*Se declara un cursor FOR UPDATE que coja el empleado con Cdigo igual al DNI
introducido*/
CURSOR cur_emp IS SELECT * FROM EMPLEADOS WHERE EMPLEADOS.Cod = DNI FOR UPDATE OF
Departamento;
/*Se declara otro cursor que coja los registros de todos los empleados del departamento
destino*/
CURSOR cur_dep IS SELECT * FROM EMPLEADOS WHERE EMPLEADOS.Departamento =
deptoDestino;
V_emp cur_emp;
V_dep cur_dep;
BEGIN
OPEN cur_emp; -- Se abre el cursor del empleado
FETCH cur_emp INTO v_emp;
IF cur_emp%NOTFOUND THEN --No se ha encontrado el empleado
DBMS_OUTPUT.PUTLINE (ERROR: No se ha encontrado el empleado);
ELSE
OPEN
cur_dep; --Se abre el cursor del departamento
FETCH cur_dep INTO v_dep;
IF cur_dep%FOUND THEN
IF cur_dep%ROWCOUNT > 20 THEN
/*hay ms de 20 empleados en ese departamento */
DBMS_OUTPUT.PUTLINE (ERROR: Este departamento tiene ms
de 20 empleados);
ELSE
--Se cambia el cdigo del empleado con un UPDATE
UPDATE EMPLEADOS SET Departamento = deptoDestino WHERE Cod = DNI;
END IF;
/81
NIVEL II
Solucin 4:
CREATE VIEW INF_GENERAL AS SELECT COUNT (E.Cod), COUNT (D.Numero), COUNT
(C.Numero), count(D.director), (Con esto tendras el numero total de jefes)
MIN (E.Fecha_ingreso), MAX (E.Fecha_ingreso), SUM (E.Comision)
FROM (centros INNER JOIN departamentos ON centros.numero=departamentos.numero)
INNER JOIN empleados ON departamentos.numero=empleados.departamento;
Ahora, cree una tabla INF_GRAL_FISICA que sirva para almacenar estos datos.
CREATE TABLE INF_GRAL_FISICA (
Num_emp
NUMBER(3),
Num_dep
NUMBER(3),
Num_centros
NUMBER(3),
Num_jefes
NUMBER(3),
Fecha_primero DATE,
Fecha_ultimo
DATE,
Comisiones
INTEGER)
Cree un bloque PL/SQL que realice una consulta a la base de datos para cada uno de estos
atributos y vaya almacenando los valores en variables para, finalmente hacer una insercin
de todos los datos en la tabla.
DECLARE
V_num_emp
V_num_dep
V_num_centros
V_num_jefes
V_fecha_prim
V_fecha_ult
V_comisiones
NUMBER (3);
NUMBER(3);
NUMBER(3);
NUMBER(3);
DATE;
DATE;
INTEGER;
BEGIN
--Se obtienen los valores de las tablas
SELECT *
INTO V_num_emp, V_num_dep, V_num_centros, V_num_jefes,
fecha_ult,
V_comisiones
FROM INF_GENERAL
V_fecha_prim, V_
No hace falta hacer la consulta de la tabla porque esa informacin ya la tenemos en la vista
INF_GENERAL
/82
NIVEL II
FECHA_NA DEPARTAMENTO
-------- -----------02/12/65
21
02/12/70
22
02/02/70
23
02/01/71
23
02/02/70
22
02/02/70
21
6 filas seleccionadas
Se prescinde en la creacin de la tabla de los parmetros de almacenamiento STORAGE
(INITIAL, NEXT, PCTINCREASE) y del tablespace de destino.
CREATE TABLE INF_EMP_FSICA
(
NOMBRE
VARCHAR(50),
FECHA_NACIMIENTO
DATE,
DEPARTAMENTO
NUMBER(5)
);
Tabla creada.
Solucin 6:
A. Se prescinde en la creacin de la tabla de los parmetros de almacenamiento STORAGE
(INITIAL, NEXT, PCTINCREASE) y del tablespace de destino.
CREATE TABLE INFO_DPTOS
(
N_EMP
NUMBER(5),
COD_DPTO
NUMBER(5)
);
Tabla creada.
INSERT INTO INFO_DPTOS (COD_DPTO, N_EMP) SELECT DISTINCT DEPARTAMENTO, COUNT(DISTINCT
COD) FROM EMPLEADOS GROUP BY DEPARTAMENTO;
3 filas creadas.
COMMIT;
Validacin terminada.
DECLARE
MAX_EMPLE := SELECT MAX(N_EMP) FROM INFO_DPTOS;
BEGIN
SELECT COD_DPTO DEPARTAMENTO FROM INFO_DPTOS WHERE N_EMP = MAX_EMPLE;
END;
/
DEPARTAMENTO
-------------------------21
22
23
/83
NIVEL II
B. DECLARE
CURSOR CURS1 IS
SELECT DEPARTAMENTO COD_DEPTO, COUNT(*) NUM_EMPLEADOS
FROM EMPLEADOS
GROUP DEPARTAMENTO;
CURSOR CURS2(valor_num_empl NUMBER) IS
SELECT DEPARTAMENTO FROM EMPLEADOS
GROUP BY DEPARTAMENTO
HAVING COUNT(*) > valor_num_empl;
v_reg CURS1%ROWTYPE;
v_reg_aux CURS2%ROWTYPE;
BEGIN
FOR v_reg IN CURS1
LOOP
OPEN CURS2(v_reg.NUM_EMPLEADOS);
FETCH CURS2 INTO v_reg_aux;
IF CURS2%NOTFOUND
THEN
/* SELECCIONAMOS EL REGISTRO (ESCRIBIENDOLO POR PANTALLA) Y
SEGUIMOS BUSCANDO CONTINUANDO CON EL LOOP*/
DBMS_OUTPUT.PUT_LINE(Codigo de departamento: || v_reg.COD_
DEPTO);
END IF;
/* SI HAY ALGN REGISTRO ENCONTRADO EN EL CURSOR NO HACEMOS NADA,
SE RECHAZA EL REGISTRO v_reg Y SE HACE UN NUEVO FETCH CONTINUANDO CON EL LOOP*/
CLOSE CURS2;
END LOOP;
END;
Codigo de departamento: 21
Codigo de departamento: 22
Codigo de departamento: 23
Solucin 7:
DECLARE
CURSOR busqueda salario IS
SELECT codigo empleado, salario FROM EMPLEADOS
FOR UPDATE OF salario;
codigo empleados.codigo empleado%TYPE;
salario empleados.salario empleado%TYPE;
BEGIN
OPEN busqueda salario;
LOOP
FETCH busqueda salario INTO codigo, salario;
EXIT WHEN busqueda salario%NOTFOUND;
IF salario < 100 THEN
UPDATE empleados SET salario=salario*0,2 ;
WHERE CURRENT OF busqueda salario ;
END IF;
END LOOP;
CLOSE busqueda salario ;
COMMIT;
END;
/84
GLOSARIO
3GL. LENGUAJES DE TERCERA GENERACIN.
Lenguaje que se dise para que fuera ms fcil de entender incluyendo cosas como el
nombre a las variables. Por ejemplo, FORTRAN y COBOL.
ANSI
American National Standards Institute
API
Application Program Interface.
Application Program Interface (API)
Un sistema de interfaces programados pblicos, que consisten en un formato del lenguaje
y del mensaje para comunicarse con el sistema operativo o en otro entorno programtico,
tal como bases de datos, servidores Web, JVMs, y as sucesivamente. Estos mensajes llaman
las funciones y los mtodos disponibles para el desarrollo de la aplicacin.
Servidor de la aplicacin
Un servidor dise recibir usos y sus ambientes, permitiendo que los usos del servidor
funcionen. Un ejemplo tpico es OAS, que puede recibir los usos de Java, de C, de C++, y
del PL/del SQL, en caso de que un cliente del telecontrol controle el interfaz. Vea tambin
el servidor de la aplicacin del Oracle.
AT
Autonomous Transaction
Atributo
Una propiedad de un elemento, que consiste en un nombre y un valor separados por un
igual, y contenidos dentro de las etiquetas del comienzo despus del nombre del elemento.
En este ejemplo, el <Price units=USD>5</Price>, unidades es el atributo y los USD son su
valor, que debe estar en cotizaciones simples o dobles. Los atributos pueden residir en el
documento o en el DTD. Los elementos pueden tener muchos atributos, pero su orden de
recuperacin no se define.
BFILES
Archivos binarios externos, que existen fuera de los tablespaces de la base de datos que
/85
Callback
Una tcnica programtica, en la cual un proceso comienza otro y entonces contina. El
segundo proceso llama al primero como resultado de la accin, del valor, o del otro acontecimiento. Esta tcnica se utiliza en la mayora de los programas que tengan una interfaz
utilitaria, para permitir la interaccin continua.
Cartridge
Un programa almacenado en Java o en PL/SQL, que agrega la funcionalidad necesaria para
que la base de datos entienda y manipule un nuevo datatype.
CDATA
Vea los datos de carcter.
CGI
Vea Common Gateway Interface
CLASSPATH
La variable ambiental del sistema operativo que el JVM utiliza para encontrar las clases que
necesita para ejecutar aplicaciones.
/86
CLOB
Vea el objeto grande del carcter.
Datagrama
Un fragmento de texto, que puede estar en el formato XML, que se devuelve al solicitante
en una pgina HTML de una query de SQL, procesada por el XSQL Servlet.
DOCTYPE
El trmino usado como el nombre de la etiqueta que seala el DTD o su referencia dentro
de un documento de XML.
/87
DCL
Data Control Language
DDL
Data Definition Language
DML
Data Manipulation Language
EDI
Intercambio de los datos electrnicos.
Elemento
La unidad lgica bsica de un documento de XML que puede servir como un envase para
otros elementos como hijos, datos, atributos, y sus valores. Los elementos son identificados
por las etiquetas de comienzo el <name> y el extremo-tags</el name> o en el caso de los
elementos vacos, <name/>.
Framework
Entorno de trabajo
Generador de la clase
Una utilidad que acepta un fichero de entrada y crea un sistema de las clases de salida
que tienen funcionalidad correspondiente. En el caso del generador de la clase de XML, el
fichero de entrada es un DTD, y la salida es una serie de clases que se puedan utilizar para
crear los documentos de XML que se conforman con el DTD.
/88
HTTP
Vea el protocolo del transporte del hypertext.
Hypertext
El mtodo de crear y de publicar los documentos del texto en los cuales los usuarios pueden
navegar entre otros documentos o grficos, seleccionando las palabras o las frases sealadas como hyperlinks.
Instancia
Un trmino usado en lenguajes, basado en objetos como Java y C++ para referir a la creacin de un objeto de una clase especfica.
ISO
International Organization for Standardization
/89
MR
Modelo Relacional
MT
Main Transaction
Namespace
El trmino para describir un sistema de nombres o de cualidades relacionados del elemento
dentro de un documento de XML. La sintaxis del namespace y su uso es definido por una
recomendacin del W3 C. Por ejemplo, el <xsl:las aplicar-plantillas/> elemento se identifican
como parte del namespace de XSL. Namespaces se declara en el documento de XML o el
DTD antes de que se est utilizando el sintaxis siguiente de la cualidad:- los xmlns:xsl=
http://www.w3.org/TR/WD-xsl .
N-Tier
La designacin para una arquitectura de red de comunicaciones de la mquina, que consiste
en una o ms capas compuestas de clientes y de servidores. Los sistemas tpicamente de
dos niveles se componen de un nivel del cliente y de un nivel del servidor. Un sistema de
la tres capas utiliza dos capas del servidor; normalmente, un servidor de la base de datos y
un Web o un servidor de la aplicacin, junto con una capa del cliente.
OAG
Open Applications Group.
OAS
Oracle Application Server
OASIS
Organization for the Advancement of Structured Information.
Object View
Una presentacin adaptada de los datos contenidos en una o ms tablas del objeto u otras
vistas. La salida de una query se trata como tabla. Las vistas del objeto se pueden utilizar
en la mayora de los lugares en donde se utiliza una tabla.
/90
OE
Oracle Exnchage
ORACLE_HOME
La variable ambiental del sistema operativo que identifica la localizacin de la instalacin
de la base de datos del Oracle para uso de las aplicaciones.
PL/SQL
El lenguaje procesal de la base de datos del Oracle, que ampla el SQL para crear los programas que se pueden funcionar dentro de la base de datos.
Schema
La definicin de los tipos de la estructura y de datos dentro de una base de datos. Puede
tambin ser utilizada para referir a un documento de XML, que apoya la recomendacin
del W3 C del esquema de XML.
Servlet
Una aplicacin de Java que funciona en un servidor; normalmente, un Web o un servidor
de la aplicacin, y realiza el proceso en ese servidor. Servlets a Java, equivalente a las
escrituras del cgi.
/91
SGBD
Sistema de Gestin de Bases de Datos.
SGBDR
Sistema de Gestin de Bases de Datos Relacionales.
Tag etiqueta
Una pieza nica de XML que delimita el comienzo o el extremo de un elemento. Las etiquetas comienzan con < y terminan con >. En XML, hay que empezar-etiquetas (<name>),
extremo-etiquetas (</name>), y etiquetas vacas (<name/>).
W3 C
World Wide Web (W3 C).
/92
Wrapper
El trmino que describe una estructura o un software de datos que se envuelven alrededor
de los otros datos o software, para proporcionar un interfaz genrico del objeto.
Web server
Un proceso del servidor (demonio del HTTP) que funciona en un Web site, que enva pginas
Web en respuesta a peticiones HTTP de los browsers.
/93