You are on page 1of 15

Funciones PL/SQL

Ejercicio 1

Crear una funcin pl/sql que duplica la cantidad recibida como parmetro
--Funcin que duplica la cantidad recibida como parmetro
CREATE OR REPLACE FUNCTION duplicador(
valor number
) RETURN number IS
BEGIN
return (valor * 2);
END;
/
show errors
var x number;
EXEC :x := duplicador(5);
print x

Ejercicio 2

Crear una funcin pl/sql llamada factorial que devuelva el factorial de un nmero, por ejemplo 5! = 1 *
2 * 3 * 4 * 5 = 120
--Clculo del factorial de un nmero
CREATE OR REPLACE FUNCTION factorial (
pNum number
) RETURN number IS
BEGIN
if pNum = 0 then
return 1;
else
return pNum * factorial(pNum - 1);
end if;
END;
/
show errors
var x number;
EXEC :x := factorial(5);
print x;

Problema:
Una librera almacena la informacin de sus libros en una tabla llamada "libros".
Eliminamos la tabla:
drop table libros;
Creamos la tabla "libros" con la siguiente estructura:
create table libros(
codigo number(3),
titulo varchar2(40),
autor varchar2(30),
precio number(5,2)
);
Ingresamos algunos registros:
insert into libros values(100,'Uno','Richard Bach',15);
insert into libros values(300,'Aprenda PHP','Mario Molina',55);
insert into libros values(102,'Matematica estas ahi','Paenza',18);
insert into libros values(105,'El aleph','Borges',25);
insert into libros values(109,'El experto en
laberintos','Gaskin',20);
insert into libros values(204,'Alicia en el pais de las
maravillas','Carroll',31);
Creamos o reemplazamos una funcin que reciba 1 parmetro (un valor numrico a
incrementar) y retorne el valor ingresado como argumento con el incremento del 10%:
create or replace function f_incremento10 (avalor number)
return number
is
begin
return avalor+(avalor*0.1);
end;
Realizamos un "select" sobre "libros" que muestre el ttulo, precio y llamamos a la funcin
creada anteriormente para que nos devuelva el precio incrementado en un 10%:
select titulo,precio,f_incremento10(precio) from libros;
Creamos otra funcin que reciba 2 parmetros, un valor a incrementar y el incremento, y que
nos retorne el valor ingresado como primer argumento con el incremento especificado por el
segundo argumento:
create or replace function f_incremento (avalor number, aincremento
number)
return number
is
begin
return avalor+(avalor*aincremento/100);
end;
Realizamos un "select" sobre "libros" que muestre el ttulo, precio y el precio incrementado en
un 20% (llamando a la funcin creada anteriormente, enviando como primer argumento el
campo "precio" y como segundo argumento el valor "20"):

select titulo,precio,f_incremento(precio,20) from libros;


Realizamos otro "select" similar al anterior, pero en esta ocasin le enviamos a la funcin otro
valor como segundo argumento:
select titulo,precio,f_incremento(precio,50) from libros;
Creamos o reemplazamos una funcin que recibe un parmetro de tipo numrico y retorna
una cadena de caracteres. Se define una variable en la zona de definicin de variables
denominada "valorretornado" de tipo varchar. En el cuerpo de la funcin empleamos una
estructura condicional (if) para averiguar si el valor enviado como argumento es menor o igual
a 20, si lo es, almacenamos en la variable "valorretornado" la cadena "economico", en caso
contrario guardamos en tal variable la cadena "costoso"; al finalizar la estructura condicional
retornamos la variable "valorretornado":
create or replace function f_costoso (avalor number)
return varchar2
is
valorretornado varchar2(20);
begin
valorretornado:='';
if avalor<=20 then
valorretornado:='economico';
else valorretornado:='costoso';
end if;
return valorretornado;
end;
Realizamos un "select" para mostrar el ttulo, precio y una cadena que indique si el libro es
econmico o costoso (llamando a la funcin creada anteriormente):
select titulo,precio,f_costoso(precio) from libros;.
Podemos emplear la funcin "f_costoso" sin incluir campos de una tabla. Por ejemplo:
select f_costoso (10) from dual;

EJERCICIOS
CREATE OR REPLACE PROCEDURE...
1.- Ejemplos de creacin procedimientos.
1) Indicar los errores que aparecen en las siguientes instrucciones y la forma de corregirlos.
DECLARE
Num1 NUMBER(8,2) := 0
Num2 NUMBER(8,2) NOT NULL DEFAULT 0;
Num3 NUMBER(8,2) NOT NULL;
Cantidad INTEGER(3);
Precio, Descuento NUMBER(6);
Num4 Num1%ROWTYPE;
Dto CONSTANT INTEGER;
BEGIN
...
END;
Num3 NUMBER(8,2) NOT NULL DEFAULT 0;
Cantidad INTEGER;
Precio NUMBER(6);
Descuento NUMBER(6);
Num4 Num1%TYPE;
2) Escribir un procedimiento que reciba dos nmeros y visualice su suma.
CREATE OR REPLACE PROCEDURE sumar_numeros (
num1 NUMBER,
num2 NUMBER)
IS
suma NUMBER(6);
BEGIN
suma := num1 + num2;
DBMS_OUTPUT.PUT_LINE('Suma: '|| suma);
END sumar_numeros;
3) Codificar un procedimiento que reciba una cadena y la visualice al revs.
CREATE OR REPLACE PROCEDURE cadena_reves(
vcadena VARCHAR2)
AS
vcad_reves VARCHAR2(80);
BEGIN
FOR i IN REVERSE 1..LENGTH(vcadena) LOOP
vcad_reves := vcad_reves || SUBSTR(vcadena,i,1);
END LOOP;
DBMS_OUTPUT.PUT_LINE(vcad_reves);
END cadena_reves;
4) Escribir una funcin que reciba una fecha y devuelva el ao, en nmero, correspondiente
a esa fecha.
CREATE OR REPLACE FUNCTION anio (
fecha DATE)
RETURN NUMBER
AS
v_anio NUMBER(4);
BEGIN

v_anio := TO_NUMBER(TO_CHAR(fecha, 'YYYY'));


RETURN v_anio;
END anio;

CREATE OR REPLACE FUNCTION....


2 .- Ejemplos de creacin de funciones.
5) Escribir un bloque PL/SQL que haga uso de la funcin anterior.
DECLARE
n NUMBER(4);
BEGIN
n := anio(SYSDATE);
DBMS_OUTPUT.PUT_LINE('AO : '|| n);
END;
6) Dado el siguiente procedimiento:
CREATE OR REPLACE PROCEDURE crear_depart (
v_num_dept depart.dept_no%TYPE,
v_dnombre depart.dnombre%TYPE DEFAULT 'PROVISIONAL',
v_loc depart.loc%TYPE DEFAULT PROVISIONAL)
IS
BEGIN
INSERT INTO depart
VALUES (v_num_dept, v_dnombre, v_loc);
END crear_depart;
Indicar cules de las siguientes llamadas son correctas y cules incorrectas, en este ltimo
caso escribir la llamada correcta usando la notacin posicional (en los casos que se pueda):
crear_depart; -- 1
crear_depart(50); -- 2
crear_depart('COMPRAS'); -- 3
crear_depart(50,'COMPRAS'); -- 4
crear_depart('COMPRAS', 50); -- 5
crear_depart('COMPRAS', 'VALENCIA'); -- 6
crear_depart(50, 'COMPRAS', 'VALENCIA'); -- 7
crear_depart('COMPRAS', 50, 'VALENCIA'); -- 8
crear_depart('VALENCIA', COMPRAS); -- 9
crear_depart('VALENCIA', 50); -- 10
1 Incorrecta: hay que pasar al menos el nmero de departamento.
2 Correcta.
3 Incorrecta: hay que pasar tambin el nmero de departamento.
4 Correcta.
5 Incorrecta: los argumentos estn en orden inverso.
Solucin: crear_depart(50, 'COMPRAS');
6 Incorrecta: hay que pasar tambin el nmero.
7 Correcta.
8 Incorrecta: el orden de los argumentos es incorrecto.
Solucin: crear_depart(50, 'COMPRAS', 'VALENCIA');
9 Incorrecta: hay que pasar tambin el nmero de departamento.
10 Incorrecta: los argumentos estn en orden inverso.
Solucin: crear_depart(50, NULL, 'VALENCIA');
7) Desarrollar una funcin que devuelva el nmero de aos completos que hay entre dos
fechas que se pasan como argumentos.
CREATE OR REPLACE FUNCTION anios_dif (
fecha1 DATE,
fecha2 DATE)

RETURN NUMBER
AS
v_anios_dif NUMBER(6);
BEGIN
v_anios_dif := ABS(TRUNC(MONTHS_BETWEEN(fecha2,fecha1)
/ 12));
RETURN v_anios_dif;
END anios_dif;
8) Escribir una funcin que, haciendo uso de la funcin anterior devuelva los trienios que
hay entre dos fechas. (Un trienio son tres aos completos).
CREATE OR REPLACE FUNCTION trienios (
fecha1 DATE,
fecha2 DATE)
RETURN NUMBER
AS
v_trienios NUMBER(6);
BEGIN
v_trienios := TRUNC(anios_dif(fecha1,fecha2) / 3);
RETURN v_trienios;
END;

PROCEDIMIENTOS Y FUNCIONES
3 .- Ejemplos de procedimientos y funciones.
9) Codificar un procedimiento que reciba una lista de hasta 5 nmeros y visualice su suma.
CREATE OR REPLACE PROCEDURE sumar_5numeros (
Num1 NUMBER DEFAULT 0,
Num2 NUMBER DEFAULT 0,
Num3 NUMBER DEFAULT 0,
Num4 NUMBER DEFAULT 0,
Num5 NUMBER DEFAULT 0)
AS
BEGIN
DBMS_OUTPUT.PUT_LINE(Num1 + Num2 + Num3 + Num4 + Num5);
END sumar_5numeros;
10) Escribir una funcin que devuelva solamente caracteres alfabticos sustituyendo
cualquier otro carcter por blancos a partir de una cadena que se pasar en la llamada.
CREATE OR REPLACE FUNCTION sust_por_blancos(
cad VARCHAR2)
RETURN VARCHAR2
AS
nueva_cad VARCHAR2(30);
car CHARACTER;
BEGIN
FOR i IN 1..LENGTH(cad) LOOP
car:=SUBSTR(cad,i,1);
IF (ASCII(car) NOT BETWEEN 65 AND 90)
AND (ASCII(car) NOT BETWEEN 97 AND 122) THEN
car :=' ';
END IF;
nueva_cad := nueva_cad || car;
END LOOP;
RETURN nueva_cad;
END sust_por_blancos;

11) Implementar un procedimiento que reciba un importe y visualice el desglose del cambio
en unidades monetarias de 1, 5, 10, 25, 50, 100, 200, 500, 1000, 2000, 5000 Ptas. en orden
inverso al que aparecen aqu enumeradas.
CREATE OR REPLACE PROCEDURE desglose_cambio(
importe NUMBER)
AS
cambio NATURAL := importe;
moneda NATURAL;
v_uni_moneda NATURAL;
BEGIN
DBMS_OUTPUT.PUT_LINE('***** DESGLOSE DE: ' || importe );
WHILE cambio > 0 LOOP
IF cambio >= 5000 THEN
moneda := 5000;
ELSIF cambio >= 2000 THEN
moneda := 2000;
ELSIF cambio >= 1000 THEN
moneda := 1000;
ELSIF cambio >= 500 THEN
moneda := 500;
ELSIF cambio >= 200 THEN
moneda := 200;
ELSIF cambio >= 100 THEN
moneda := 100;
ELSIF cambio >= 50 THEN
moneda := 50;
ELSIF cambio >= 25 THEN
moneda := 25;
ELSIF cambio >= 10 THEN
moneda := 10;
ELSIF cambio >= 5 THEN
moneda := 5;
ELSE
moneda := 1;
END IF;
v_uni_moneda := TRUNC(cambio / moneda);
DBMS_OUTPUT.PUT_LINE(v_uni_moneda ||
' Unidades de: ' || moneda || ' Ptas. ');
cambio := MOD(cambio, moneda);
END LOOP;
END desglose_cambio;

12) Codificar un procedimiento que permita borrar un empleado cuyo nmero se pasar en
la llamada.
CREATE OR REPLACE PROCEDURE borrar_emple(
num_emple emple.emp_no%TYPE)
AS
BEGIN
DELETE FROM emple WHERE emp_no = num_emple;
END borrar_emple;
Nota: El procedimiento anterior devolver el mensaje
<< Procedimiento PL/SQL terminado con xito >> aunque no exista el nmero y, por tanto,
no se borre el empleado. Para evitarlo se puede escribir:
CREATE OR REPLACE PROCEDURE borrar_emple(
num_emple emple.emp_no%TYPE)
AS
v_row ROWID;
BEGIN

SELECT ROWID INTO v_row FROM emple


WHERE emp_no = num_emple;
DELETE FROM emple WHERE ROWID = v_row;
END borrar_emple;
13) Escribir un procedimiento que modifique la localidad de un departamento. El
procedimiento recibir como parmetros el nmero del departamento y la localidad nueva.
CREATE OR REPLACE
PROCEDURE modificar_localidad(
num_depart NUMBER,
localidad VARCHAR2)
AS
BEGIN
UPDATE depart SET loc = localidad
WHERE dept_no = num_depart;
END modificar_localidad;
Nota: Lo indicado en la nota del ejercicio anterior se puede aplicar tambin a este.
14) Visualizar todos los procedimientos y funciones del usuario almacenados en la base de
datos y su situacin (valid o invalid).
SELECT OBJECT_NAME, OBJECT_TYPE, STATUS
FROM USER_OBJECTS
WHERE OBJECT_TYPE IN ('PROCEDURE','FUNCTION');
Nota: Tambin se puede utilizar la vista ALL_OBJECTS.

Oracle construido en Funciones


Hay dos tipos de funciones en Oracle.
1) Funciones de una fila: Funciones de una sola hilera o escalares devuelven un valor para
cada fila que se procesa en una consulta.
2) Funciones de Grupo: Estas funciones de grupo de las filas de datos en funcin de los
valores devueltos por la consulta. Esto se discute en Funciones de SQL GROUP. Las funciones
de grupo se utilizan para calcular valores agregados como totales o promedio, que devuelven
un solo total o un valor medio despus de procesar un grupo de filas.
Hay cuatro tipos de funciones de una sola fila. Ellos son:
1) Funciones numricas: Estas son funciones que aceptan entrada numrica y
devuelven valores numricos.
2) Carcter o texto Funciones: Estas son funciones que aceptan la entrada de caracteres
y pueden regresar tanto carcter y los valores numricos.
3) Funciones de fecha: Estas son funciones que toman valores que son del tipo de datos
FECHA como entrada y devuelven valores de tipo de datos FECHA, a excepcin de la
funcin MONTHS_BETWEEN, que devuelve un nmero.
4) Funciones de conversin: Estas son funciones que nos ayudan a convertir un valor en
una forma a otra forma. Por ejemplo: un valor nulo en un valor real, o un valor de un tipo de
datos a otro tipo de datos como NVL, TO_CHAR, TO_NUMBER, TO_DATE etc
Puede combinar ms de una funcin juntos en una expresin. Esto se conoce como
anidamiento de funciones.
Qu es una tabla DUAL en Oracle?
Se trata de una sola fila y una sola columna tabla ficticia proporcionada por el orculo. Esto
se utiliza para realizar clculos matemticos sin necesidad de utilizar una tabla.

Select * from DUAL

Salida:
DUMMY
------X

Select 777 * 888 from Dual

Salida:
777
--------689976

888

1) Funciones numricas:
Funciones numricas se utilizan para realizar operaciones en los nmeros. Ellos aceptan
los valores numricos como entrada y devuelven valores numricos como salida. Pocas
de las funciones numricas son:

Function
Name

Return Value

ABS (x)

Absolute value of the number 'x'

CEIL (x)

Integer value that is Greater than or equal to the number 'x'

FLOOR (x)

Integer value that is Less than or equal to the number 'x'

TRUNC (x, y) Truncates value of number 'x' up to 'y' decimal places


ROUND (x, y)

Rounded off value of the number 'x' up to the number 'y'


decimal places

Los siguientes ejemplos se explica el uso de las funciones numricas anteriores

Function Name

Examples

Return Value

ABS (x)

ABS (1)
ABS (-1)

1
-1

CEIL (x)

CEIL (2.83)
CEIL (2.49)
CEIL (-1.6)

3
3
-1

FLOOR (x)

FLOOR (2.83)
FLOOR (2.49)
FLOOR (-1.6)

2
2
-2

TRUNC (x, y)

ROUND (125.456, 1)
ROUND (125.456, 0)
ROUND (124.456, -1)

125.4
125
120

ROUND (x, y)

TRUNC
TRUNC
TRUNC
TRUNC

140.23
54
5
140

(140.234, 2)
(-54, 1)
(5.7)
(142, -1)

Estas funciones se pueden utilizar en las columnas de la base de datos.


Por ejemplo: Consideremos la tabla de productos utilizados en las uniones SQL. Podemos
utilizar REDONDA para redondear el unit_price al entero ms cercano, si algn producto
tiene precios en fraccin.

SELECT ROUND (unit_price) FROM product;

2) Carcter o texto Funciones:


Funciones de caracteres o de texto se utilizan para manipular cadenas de texto. Ellos aceptan
cadenas o caracteres como entrada y pueden volver carcter y los valores de nmero como
salida.
Pocos de los caracteres o funciones de texto es el que aparece a continuacin:

Function Name

Return Value

LOWER
(string_value)

All the letters in 'string_value' is converted to lowercase.

UPPER
(string_value)

All the letters in 'string_value' is converted to uppercase.

INITCAP
(string_value)

All the letters in 'string_value' is converted to mixed


case.

LTRIM
(string_value,
trim_text)

All occurrences of 'trim_text' is removed from the left


of 'string_value'.

RTRIM
(string_value,
trim_text)

All occurrences of 'trim_text' is removed from the right


of'string_value' .

All occurrences of 'trim_text' from the left and right


TRIM (trim_text
of 'string_value' ,'trim_text' can also be only one
FROM string_value)
character long .
SUBSTR
Returns 'n' number of characters
(string_value, m, n) from'string_value' starting from the 'm'position.
LENGTH
(string_value)

Number of characters in 'string_value'in returned.

LPAD (string_value, Returns 'string_value' left-padded with'pad_value' . The


n, pad_value)
length of the whole string will be of 'n' characters.
RPAD (string_value, Returns 'string_value' right-padded with 'pad_value' .
n, pad_value)
The length of the whole string will be of 'n' characters.

Por ejemplo, podemos utilizar la funcin de texto anterior UPPER () con el valor de la
columna de la siguiente manera.

SELECT UPPER (product_name) FROM product;

Los siguientes ejemplos explican el uso del carcter por encima o por funciones de texto

Function Name

Examples

Return Value

LOWER(string_value)

LOWER('Good Morning')

good morning

UPPER(string_value)

UPPER('Good Morning')

GOOD
MORNING

INITCAP(string_value)

INITCAP('GOOD MORNING')

Good Morning

LTRIM(string_value, trim_text) LTRIM ('Good Morning', 'Good) Morning


RTRIM (string_value, trim_text)

RTRIM ('Good Morning', '


Morning')

Good

TRIM (trim_text FROM


string_value)

TRIM ('o' FROM 'Good


Morning')

Gd Mrning

SUBSTR (string_value, m, n)

SUBSTR ('Good Morning', 6, 7) Morning

LENGTH (string_value)

LENGTH ('Good Morning')

12

LPAD (string_value, n,
pad_value)

LPAD ('Good', 6, '*')

**Good

RPAD (string_value, n,
pad_value)

RPAD ('Good', 6, '*')

Good**

3) Funciones de fecha:
Estas son funciones que toman valores que son del tipo de datos FECHA como entrada y
devuelven valores de tipos de datos DATE, excepto para la funcin MONTHS_BETWEEN, que
devuelve un nmero como de salida.
Pocas funciones de fecha es el que aparece a continuacin.

Function Name

Return Value

ADD_MONTHS
(date, n)

Returns a date value after adding 'n'months to the


date 'x'.

MONTHS_BETWEEN Returns the number of months between dates x1 and


(x1, x2)
x2.
ROUND (x,
date_format)

Returns the date 'x' rounded off to the nearest century,


year, month, date, hour, minute, or second as specified
by the 'date_format'.

TRUNC (x,
date_format)

Returns the date 'x' lesser than or equal to the nearest


century, year, month, date, hour, minute, or second as
specified by the 'date_format'.

NEXT_DAY (x,
week_day)

Returns the next date of the 'week_day'on or after the


date 'x' occurs.

LAST_DAY (x)

It is used to determine the number of days remaining in


a month from the date 'x' specified.

SYSDATE

Returns the systems current date and time.

NEW_TIME (x,
zone1, zone2)

Returns the date and time in zone2 if date 'x' represents


the time in zone1.

La siguiente tabla muestra los ejemplos de las funciones anteriores

Function Name

Examples

Return Value

ADD_MONTHS ( )

ADD_MONTHS ('16-Sep-81', 3)

16-Dec-81

MONTHS_BETWEEN(MONTHS_BETWEEN ('16-Sep-81', '16)


Dec-81')

NEXT_DAY( )

NEXT_DAY ('01-Jun-08', 'Wednesday')

04-JUN-08

LAST_DAY( )

LAST_DAY ('01-Jun-08')

30-Jun-08

NEW_TIME( )

NEW_TIME ('01-Jun-08', 'IST', 'EST')

31-May-08

4) Funciones de conversin:
Estas son funciones que nos ayudan a convertir un valor en una forma a otra forma. Por
Ejemplo: un valor nulo en un valor real, o un valor de un tipo de datos a otro tipo de datos
como NVL, TO_CHAR, TO_NUMBER, TO_DATE.
Pocas de las funciones de conversin disponibles en Oracle son:

Function Name

Return Value

TO_CHAR (x [,y])

Converts Numeric and Date values to a character string


value. It cannot be used for calculations since it is a
string value.

TO_DATE (x [,
date_format])

Converts a valid Numeric and Character values to a


Date value. Date is formatted to the format specified
by 'date_format'.

NVL (x, y)

If 'x' is NULL, replace it with 'y'. 'x' and 'y'must be of the


same datatype.

DECODE (a, b, c, d, Checks the value of 'a', if a = b, then returns'c'. If a = d,


e, default_value)
then returns 'e'. Else, returnsdefault_value.

La siguiente tabla muestra los ejemplos de las funciones anteriores

Function Name

Examples

Return Value

TO_CHAR ()

TO_CHAR (3000, '$9999')


TO_CHAR (SYSDATE, 'Day, Month
YYYY')

$3000
Monday, June
2008

TO_DATE ()

TO_DATE ('01-Jun-08')

01-Jun-08

NVL ()

NVL (null, 1)

Principiante-Sql-Tutorial.com | 2007 -2014 | Principiante-SQL-Tutorial.com Pol tica | Reservados


todos los der