declare
Cursor tipoIdCursor is
select EMPLOYEE_ID from employees;
vemployee_id employees.employee_id%type;
vtipoId employees.Tipoid%type;
begin
open tipoIdCursor;
loop
fetch tipoIdCursor into vemployee_id;
exit when tipoIdCursor%NOTFOUND;
if mod(vemployee_id,2)= 0 then
vtipoId := 'Par' ;
else
vtipoId := 'Impar';
end if;
update employees
set Tipoid = vtipoId
where EMPLOYEE_ID = vemployee_id;
end loop;
close tipoIdCursor;
end;
lunes, 30 de abril de 2012
jueves, 26 de abril de 2012
Clase 25 de Abril
--CURSOR : ESPACIO DE MEMORIA EN DONDE SE ALMACENA EL RESULTADO DE UNA CONSULTA, PARA DESPUES PROCESARLA--
set serveroutput on;
DECLARE
vPropietario varchar2(40);
vNombreTabla varchar2(40);
vNombreColumna varchar2(100);
/* Primer cursor */
cursor obtieneTablas is
select distinct t.owner, t.table_name
from all_tables t
where t.owner = 'HR';
/* Segundo cursor */
cursor obtieneColumnas is
select distinct c.column_name
from all_tab_columns c
where c.owner = vPropietario
and c.table_name = vNombreTabla;
begin
open obtieneTablas();
dbms_output.put_line('Abriendo Cursor - obtieneTablas');
loop fetch obtieneTablas into vPropietario, vNombreTabla;
exit when obtieneTablas%NOTFOUND;
dbms_output.put_line('Tabla : '||vPropietario||'.'||vNombreTabla);
open obtieneColumnas;
loop fetch obtieneColumnas into vNombreColumna;
exit when obtieneColumnas%NOTFOUND;
dbms_output.put_line('=>'||vNombreTabla||'.'||vNombreColumna);
end loop;
close obtieneColumnas;
end loop;
close obtieneTablas;
EXCEPTION
WHEN OTHERS THEN
raise_application_error(-20001,'Se ha detectado un error - '||SQLCODE||' -ERROR- '||SQLERRM);
end;
-- PASO DE PARAMETROS EN CURSORES--
set serveroutput on;
DECLARE
vPropietario varchar2(40);
vNombreTabla varchar2(40);
vNombreColumna varchar2(100);
/* Primer cursor */
cursor obtieneTablas(pPropietario all_tables.owner%type) is
select distinct t.owner, t.table_name
from all_tables t
where t.owner = pPropietario;
/* Segundo cursor */
cursor obtieneColumnas is
select distinct c.column_name
from all_tab_columns c
where c.owner = vPropietario
and c.table_name = vNombreTabla;
begin
open obtieneTablas('SYSTEM');
dbms_output.put_line('Abriendo Cursor - obtieneTablas');
loop fetch obtieneTablas into vPropietario, vNombreTabla;
exit when obtieneTablas%NOTFOUND;
dbms_output.put_line('Tabla : '||vPropietario||'.'||vNombreTabla);
open obtieneColumnas;
loop fetch obtieneColumnas into vNombreColumna;
exit when obtieneColumnas%NOTFOUND;
dbms_output.put_line('=>'||vNombreTabla||'.'||vNombreColumna);
end loop;
close obtieneColumnas;
end loop;
close obtieneTablas;
EXCEPTION
WHEN OTHERS THEN
raise_application_error(-20001,'Se ha detectado un error - '||SQLCODE||' -ERROR- '||SQLERRM);
end;
--CREAR PROCEDIMIENTOS--
CREATE PROCEDURE catuser;
-- se omite el declare--
CREATE OR REPLACE PROCEDURE CATUSER AS
vPropietario varchar2(40);
vNombreTabla varchar2(40);
vNombreColumna varchar2(100);
/* Primer cursor */
cursor obtieneTablas(pPropietario all_tables.owner%type) is
select distinct t.owner, t.table_name
from all_tables t
where t.owner = pPropietario;
/* Segundo cursor */
cursor obtieneColumnas is
select distinct c.column_name
from all_tab_columns c
where c.owner = vPropietario
and c.table_name = vNombreTabla;
begin
open obtieneTablas('SYSTEM');
dbms_output.put_line('Abriendo Cursor - obtieneTablas');
loop fetch obtieneTablas into vPropietario, vNombreTabla;
exit when obtieneTablas%NOTFOUND;
dbms_output.put_line('Tabla : '||vPropietario||'.'||vNombreTabla);
open obtieneColumnas;
loop fetch obtieneColumnas into vNombreColumna;
exit when obtieneColumnas%NOTFOUND;
dbms_output.put_line('=>'||vNombreTabla||'.'||vNombreColumna);
end loop;
close obtieneColumnas;
end loop;
close obtieneTablas;
EXCEPTION
WHEN OTHERS THEN
raise_application_error(-20001,'Se ha detectado un error - '||SQLCODE||' -ERROR- '||SQLERRM);
END CATUSER;
set serveroutput on;
DECLARE
vPropietario varchar2(40);
vNombreTabla varchar2(40);
vNombreColumna varchar2(100);
/* Primer cursor */
cursor obtieneTablas is
select distinct t.owner, t.table_name
from all_tables t
where t.owner = 'HR';
/* Segundo cursor */
cursor obtieneColumnas is
select distinct c.column_name
from all_tab_columns c
where c.owner = vPropietario
and c.table_name = vNombreTabla;
begin
open obtieneTablas();
dbms_output.put_line('Abriendo Cursor - obtieneTablas');
loop fetch obtieneTablas into vPropietario, vNombreTabla;
exit when obtieneTablas%NOTFOUND;
dbms_output.put_line('Tabla : '||vPropietario||'.'||vNombreTabla);
open obtieneColumnas;
loop fetch obtieneColumnas into vNombreColumna;
exit when obtieneColumnas%NOTFOUND;
dbms_output.put_line('=>'||vNombreTabla||'.'||vNombreColumna);
end loop;
close obtieneColumnas;
end loop;
close obtieneTablas;
EXCEPTION
WHEN OTHERS THEN
raise_application_error(-20001,'Se ha detectado un error - '||SQLCODE||' -ERROR- '||SQLERRM);
end;
-- PASO DE PARAMETROS EN CURSORES--
set serveroutput on;
DECLARE
vPropietario varchar2(40);
vNombreTabla varchar2(40);
vNombreColumna varchar2(100);
/* Primer cursor */
cursor obtieneTablas(pPropietario all_tables.owner%type) is
select distinct t.owner, t.table_name
from all_tables t
where t.owner = pPropietario;
/* Segundo cursor */
cursor obtieneColumnas is
select distinct c.column_name
from all_tab_columns c
where c.owner = vPropietario
and c.table_name = vNombreTabla;
begin
open obtieneTablas('SYSTEM');
dbms_output.put_line('Abriendo Cursor - obtieneTablas');
loop fetch obtieneTablas into vPropietario, vNombreTabla;
exit when obtieneTablas%NOTFOUND;
dbms_output.put_line('Tabla : '||vPropietario||'.'||vNombreTabla);
open obtieneColumnas;
loop fetch obtieneColumnas into vNombreColumna;
exit when obtieneColumnas%NOTFOUND;
dbms_output.put_line('=>'||vNombreTabla||'.'||vNombreColumna);
end loop;
close obtieneColumnas;
end loop;
close obtieneTablas;
EXCEPTION
WHEN OTHERS THEN
raise_application_error(-20001,'Se ha detectado un error - '||SQLCODE||' -ERROR- '||SQLERRM);
end;
--CREAR PROCEDIMIENTOS--
CREATE PROCEDURE catuser;
-- se omite el declare--
CREATE OR REPLACE PROCEDURE CATUSER AS
vPropietario varchar2(40);
vNombreTabla varchar2(40);
vNombreColumna varchar2(100);
/* Primer cursor */
cursor obtieneTablas(pPropietario all_tables.owner%type) is
select distinct t.owner, t.table_name
from all_tables t
where t.owner = pPropietario;
/* Segundo cursor */
cursor obtieneColumnas is
select distinct c.column_name
from all_tab_columns c
where c.owner = vPropietario
and c.table_name = vNombreTabla;
begin
open obtieneTablas('SYSTEM');
dbms_output.put_line('Abriendo Cursor - obtieneTablas');
loop fetch obtieneTablas into vPropietario, vNombreTabla;
exit when obtieneTablas%NOTFOUND;
dbms_output.put_line('Tabla : '||vPropietario||'.'||vNombreTabla);
open obtieneColumnas;
loop fetch obtieneColumnas into vNombreColumna;
exit when obtieneColumnas%NOTFOUND;
dbms_output.put_line('=>'||vNombreTabla||'.'||vNombreColumna);
end loop;
close obtieneColumnas;
end loop;
close obtieneTablas;
EXCEPTION
WHEN OTHERS THEN
raise_application_error(-20001,'Se ha detectado un error - '||SQLCODE||' -ERROR- '||SQLERRM);
END CATUSER;
martes, 24 de abril de 2012
Clase 21 de Abril
set serveroutput on;
declare
NO_REGISTRO exception; --declaramos la exception
vtotalCargo integer;
vtotalEmpleados integer;
vtasa numeric(4,1);
vnombreCargo employees.job_id%type;
begin
vnombreCargo := '&IngreseCargo';
select count(*) into vtotalCargo from employees where job_id = vnombreCargo;
select count(*) into vtotalEmpleados from employees;
if vtotalEmpleados = 0 then --gatillamos la exception
Raise NO_REGISTRO;
dbms_output.put_line('El total de empleados con el cargo de ' || vnombreCargo || ' es: ' || vtotalCargo);
dbms_output.put_line('El total de empleados de la compañia es: ' || vtotalEmpleados);
vtasa := round(vtotalCargo / vtotalEmpleados,1);
if vtasa >= 0.3 and vnombreCargo = 'SA_REP' then
dbms_output.put_line('Muchos caciques para tan pocos indios');
end if;
Exception
when ZERO_DIVIDE then
dbms_output.put_line('');
when NO_REGISTRO then
dbms_output.put_line('No se han encontrado registros para esta busqueda');
when others then
dbms_output.put_line('Ha ocurrido un Error del tipo OTHERS');
end;
declare
NO_REGISTRO exception; --declaramos la exception
vtotalCargo integer;
vtotalEmpleados integer;
vtasa numeric(4,1);
vnombreCargo employees.job_id%type;
begin
vnombreCargo := '&IngreseCargo';
select count(*) into vtotalCargo from employees where job_id = vnombreCargo;
select count(*) into vtotalEmpleados from employees;
if vtotalEmpleados = 0 then --gatillamos la exception
Raise NO_REGISTRO;
dbms_output.put_line('El total de empleados con el cargo de ' || vnombreCargo || ' es: ' || vtotalCargo);
dbms_output.put_line('El total de empleados de la compañia es: ' || vtotalEmpleados);
vtasa := round(vtotalCargo / vtotalEmpleados,1);
if vtasa >= 0.3 and vnombreCargo = 'SA_REP' then
dbms_output.put_line('Muchos caciques para tan pocos indios');
end if;
Exception
when ZERO_DIVIDE then
dbms_output.put_line('');
when NO_REGISTRO then
dbms_output.put_line('No se han encontrado registros para esta busqueda');
when others then
dbms_output.put_line('Ha ocurrido un Error del tipo OTHERS');
end;
jueves, 19 de abril de 2012
Clase 18 de Abril
--NUMERO PRIMO
set serveroutput on
declare
primo char(2) := 'si';
num integer;
begin
num := to_number('&ingreseElNumero');
dbms_output.put_line('El numero ingresado es: '|| num);
for i in 2..num-1
loop
if mod(num,i)=0 then
primo := 'no';
end if;
end loop;
if primo='si' then
dbms_output.put_line('el numero es primo ');
else
dbms_output.put_line('el numero no es primo');
end if;
Exception
when value_error then
dbms_output.put_line('El valor ingresado no es valido');
end;
---------------------------------------------------------------------------------------------------------
CURSOR 1.0
set serveroutput on
declare
cursor miPrimerCursor is
select EMPLOYEE_ID, FIRST_NAME from employees;
vnombre employees.first_name%Type;
vid employees.employee_id%Type;
begin
open miPrimerCursor;
loop
fetch miPrimerCursor into vid,vnombre;
exit when miPrimerCursor%NOTFOUND;
dbms_output.put_line('ID: '||vid||' - ' ||'Nombre: '||vnombre);
end loop;
close miPrimerCursor;
end;
---------------------------------------------------------------------------------------------------------
CURSOR 2.0
set serveroutput on
declare
cursor miPrimerCursor is
select EMPLOYEE_ID, FIRST_NAME, HIRE_DATE from employees order by hire_date desc;
vnombre employees.first_name%Type;
vid employees.employee_id%Type;
vFechaContrato employees.HIRE_DATE%Type;
antiguedad integer;
begin
open miPrimerCursor;
loop
fetch miPrimerCursor into vid,vnombre,vFechaContrato;
exit when miPrimerCursor%NOTFOUND;
antiguedad := round((sysdate - vFechaContrato)/365);
if(antiguedad = 12) then
dbms_output.put_line(antiguedad||' * ' || ' ID: '||vid||' - ' ||'Nombre: '||vnombre);
end if;
end loop;
close miPrimerCursor;
end;
---------------------------------------------------------------------------------------------------------
DOS CURSORES
--select TABLE_NAME from all_tables where owner= 'HR'; --obtener tablas
--select OWNER,TABLE_NAME,column_name from all_tab_columns where TABLE_NAME = 'JOBS' AND owner = 'HR'; -- obtener columnas
set serveroutput on -- para que se vean los dbms :D
declare
nomTabla all_tables.table_name%Type;
nomColumna all_tab_columns.column_name%Type;
cursor CursorTabla is select TABLE_NAME from all_tables where owner ='HR';
cursor CursorColumna is select column_name from all_tab_columns where owner ='HR' ;
BEGIN
open CursorTabla;
loop
fetch CursorTabla into nomTabla;
exit when CursorTabla%NOTFOUND;
open CursorColumna;
loop
fetch CursorColumna into nomColumna;
exit when CursorColumna%NOTFOUND;
dbms_output.put_line(nomTabla || ' - ' || nomColumna);
end loop;
close CursorColumna;
end loop;
close CursorTabla;
end;
set serveroutput on
declare
primo char(2) := 'si';
num integer;
begin
num := to_number('&ingreseElNumero');
dbms_output.put_line('El numero ingresado es: '|| num);
for i in 2..num-1
loop
if mod(num,i)=0 then
primo := 'no';
end if;
end loop;
if primo='si' then
dbms_output.put_line('el numero es primo ');
else
dbms_output.put_line('el numero no es primo');
end if;
Exception
when value_error then
dbms_output.put_line('El valor ingresado no es valido');
end;
---------------------------------------------------------------------------------------------------------
CURSOR 1.0
set serveroutput on
declare
cursor miPrimerCursor is
select EMPLOYEE_ID, FIRST_NAME from employees;
vnombre employees.first_name%Type;
vid employees.employee_id%Type;
begin
open miPrimerCursor;
loop
fetch miPrimerCursor into vid,vnombre;
exit when miPrimerCursor%NOTFOUND;
dbms_output.put_line('ID: '||vid||' - ' ||'Nombre: '||vnombre);
end loop;
close miPrimerCursor;
end;
---------------------------------------------------------------------------------------------------------
CURSOR 2.0
set serveroutput on
declare
cursor miPrimerCursor is
select EMPLOYEE_ID, FIRST_NAME, HIRE_DATE from employees order by hire_date desc;
vnombre employees.first_name%Type;
vid employees.employee_id%Type;
vFechaContrato employees.HIRE_DATE%Type;
antiguedad integer;
begin
open miPrimerCursor;
loop
fetch miPrimerCursor into vid,vnombre,vFechaContrato;
exit when miPrimerCursor%NOTFOUND;
antiguedad := round((sysdate - vFechaContrato)/365);
if(antiguedad = 12) then
dbms_output.put_line(antiguedad||' * ' || ' ID: '||vid||' - ' ||'Nombre: '||vnombre);
end if;
end loop;
close miPrimerCursor;
end;
---------------------------------------------------------------------------------------------------------
DOS CURSORES
--select TABLE_NAME from all_tables where owner= 'HR'; --obtener tablas
--select OWNER,TABLE_NAME,column_name from all_tab_columns where TABLE_NAME = 'JOBS' AND owner = 'HR'; -- obtener columnas
set serveroutput on -- para que se vean los dbms :D
declare
nomTabla all_tables.table_name%Type;
nomColumna all_tab_columns.column_name%Type;
cursor CursorTabla is select TABLE_NAME from all_tables where owner ='HR';
cursor CursorColumna is select column_name from all_tab_columns where owner ='HR' ;
BEGIN
open CursorTabla;
loop
fetch CursorTabla into nomTabla;
exit when CursorTabla%NOTFOUND;
open CursorColumna;
loop
fetch CursorColumna into nomColumna;
exit when CursorColumna%NOTFOUND;
dbms_output.put_line(nomTabla || ' - ' || nomColumna);
end loop;
close CursorColumna;
end loop;
close CursorTabla;
end;
lunes, 16 de abril de 2012
Clase 14 de Abril
set serveroutput on;
Declare
vnumempleado empleado.numempleado%type;
vnombre empleado.nombre%type;
cFechNac empleado.fechnac%type;
vedad integer;
Begin
vnumempleado := '&IngreseNumEmpleado';
select trim(nombre), fechnac into vnombre, vFechNac from empleado where upper(numempleado) = upper(vnumempleado);
vedad := trunc((sysdate-vfechnac)/365);
dbms_output.put_line('El empleado '|| vnombre || ' tiene ' || rtrim(vedad) || ' años');
end;
dbms_output.put_line('El Numempleado Ingresado es : ' || vnumempleado);
select nombre, fechnac into vnombre, vfechnac from empleado
where upper(numempleado) = upper(vnumempleado);
dbms_output.put_line('Cuyo nombre es : ' || vnombre);
dbms_output.put_line('y nacido el : ' || vFechNac);
end;
Declare
vnumempleado empleado.numempleado%type;
vnombre empleado.nombre%type;
cFechNac empleado.fechnac%type;
vedad integer;
Begin
vnumempleado := '&IngreseNumEmpleado';
select trim(nombre), fechnac into vnombre, vFechNac from empleado where upper(numempleado) = upper(vnumempleado);
vedad := trunc((sysdate-vfechnac)/365);
dbms_output.put_line('El empleado '|| vnombre || ' tiene ' || rtrim(vedad) || ' años');
end;
dbms_output.put_line('El Numempleado Ingresado es : ' || vnumempleado);
select nombre, fechnac into vnombre, vfechnac from empleado
where upper(numempleado) = upper(vnumempleado);
dbms_output.put_line('Cuyo nombre es : ' || vnombre);
dbms_output.put_line('y nacido el : ' || vFechNac);
end;
miércoles, 11 de abril de 2012
Tarea 2 : Tipos de Datos PL/SQL
Tipos de Datos PL/SQL
VARCHAR2 : Cadena de caracteres de longitud variable con un máximo de size bytes de longitud. Debe especificar el tamaño
NVARCHAR2 : De longitud variable de cadena nacional, el conjunto de caracteres que tiene un máximo tamaño de bytes de longitud.
Debe especificar el tamaño
Así que utilice PLS_INTEGER donde se puede
XMLType: De datos XML
3) Funciones de conversión entre tipos de datos.
Aqui algunos ejemplos para adicionar y sustraer días y meses y encontrar la diferencia entre
fechas en Oracle. Estos ejemplos toman el resultado de la tabla "dual. La tabla Dual es una
tabla virtual que existe en todas las Bases de datos Oracle. Muchas veces hemos usado la
consulta SELECT sysdate FROM dual; la cual simplemente nos retorna la fecha y hora
actual.
Ajustar Dias, Semanas, Horas y minutos
Para adicionar y sustraer días a una fecha, simplemente usamos los signos + o -
respectivamente. Algunos ejemplos:
SELECT sysdate + 7 FROM dual;
salida:
SYSDATE+7
18/04/12
------------------------------------------------------------------------
SELECT sysdate - 30 FROM dual;
salida
SYSDATE-30
12/03/12
--------------------------------------------------------------------------------
SQL> SELECT to_char(sysdate - 14, 'MM/DD/YYYY HH:MI AM') FROM dual;
salida
TO_CHAR(SYSDATE-14,'MM/DD/YYYYHH:MIAM')
03/28/2012 12:44 AM
--------------------------------------------------------------------------------
En el primer ejemplo, vemos que la consulta retorna la fecha siete días apartir de hoy. La segunda
retorna la fecha de hace 30 días. En la tercera, se ha usado la función de conversión to_char,
para ver las horas y minutos. Esto nos muestra que mientras la fecha, ha cambiado, el tiempo no
cambia.
Los ejemplos primero y tercero ademas muestran como el adicionar días, puede ser útil para
computar semanas. Si ud desea simplificar el computo de semanas, podías usar querys de este
tipo:
SQL> SELECT sysdate + (7 * 3) FROM dual;
salida
SYSDATE+(7*3) 02/05/12
--------------------------------------------------------------------------------
Para trabajar con meses y años (cada uno de los cuales puede variar en número de días)
Oracle ofrece la función numtoyminterval. Esta trabaja en forma similar a la función
numtodsinterval tomando un numero y una cadena string. Las opciones válidas para esta
función son: ‘YEAR’ or ‘MONTH’.
SELECT to_char(sysdate + numtoyminterval(5, 'MONTH'), 'MM/DD/YYYY') FROM dual;
salida
TO_CHAR(SYSDATE+NUMTOYMINTERVAL(5,'MONTH'),'MM/DD/YYYY')
09/11/2012
------------------------------------------------------------------------------------------
SELECT to_char(sysdate + numtoyminterval(2, 'YEAR'), 'MM/DD/YYYY') FROM dual;
salida
TO_CHAR(SYSDATE+NUMTOYMINTERVAL(2,'YEAR'),'MM/DD/YYYY')
04/11/2014
------------------------------------------------------------------------------------------
Comparar fechas
Suponga que deseamos comparar algunas fechas y encontrar el número de días entre ellas. Para
ver este resultado en días, simplemente basta con usar el operador -, de la siguiente manera:
SELECT TO_DATE('11/04/2006', 'MM/DD/YYYY') - sysdate FROM dual;
salida
TO_DATE('11/04/2006','MM/DD/YYYY')-SYSDATE
-1985,0386111111111111
------------------------------------------------------------------------------------------
El resultado es expresado en días, incluyendo horas fracción de horas. Por supuesto si se desea
semanas, se podría dividir el resultado entre 7. De manera similar, si se desea obtener horas, se
debería multiplicar por 24, pero si se desea meses, entonces se podría usar la función
months_between.
SELECT months_between(sysdate, to_date('01/01/2006', 'MM/DD/YYYY')) FROM dual;
salida
MONTHS_BETWEEN(SYSDATE,TO_DATE('01/01/2006','MM/DD/YYYY'))
75,323867607526881
------------------------------------------------------------------------------------------
Retornar la mayor y menor fecha dentro de un conjunto
Las funciones greatest y least pueden ser usadas en fechas para retornar la menor o la mayor
fecha.
SELECT greatest(sysdate,sysdate+1, to_date('09/11/2005','MM/DD/YYYY'), to_date('12/25/
2005','MM/DD/YYYY'))FROM dual;
salida
GREATEST(SYSDATE,SYSDATE+1,TO_DATE('09/11/2005','MM/DD/YYYY'),TO_DATE('12/25/2005','MM/DD/YYYY'))
12/04/12
------------------------------------------------------------------------------------------
SELECT least(sysdate,sysdate+1,to_date('09/11/2005','MM/DD/YYYY'), to_date('12/25/
2005','MM/DD/YYYY'))FROM dual;
salida
LEAST(SYSDATE,SYSDATE+1,TO_DATE('09/11/2005','MM/DD/YYYY'),TO_DATE('12/25/2005','MM/DD/YYYY'))
11/09/05
------------------------------------------------------------------------------------------
Cual es el último día de este mes?
La función last_day retorna el último día del mes pasado como parámetro.
select last_day(sysdate) from dual;
salida
LAST_DAY(SYSDATE) 30/04/12
------------------------------------------------------------------------------------------
Siguiente día de la semana despues de una fecha
La función next_day retorna la fecha de la próxima ocurrencia de un día de la
semana(’Monday’, ‘Tuesday’, etc.) después de una fecha dada. ejemplo: consultar la fecha del
próximo domingo:
select next_day(sysdate,'Domingo') from dual;
salida
NEXT_DAY(SYSDATE,'DOMINGO') 15/04/12
------------------------------------------------------------------------------------------
3) Funciones para manipular fechas
Statement
processed.
VARCHAR2 : Cadena de caracteres de longitud variable con un máximo de size bytes de longitud. Debe especificar el tamaño
NVARCHAR2 : De longitud variable de cadena nacional, el conjunto de caracteres que tiene un máximo tamaño de bytes de longitud.
Debe especificar el tamaño
CHAR : Los datos de caracteres de longitud fija de bytes de tamaño de longitud. Esto
se debe utilizar para los datos de longitud fija.
Nchar : De caracteres de longitud fija nacional de conjunto de datos de tamaño
bytes de longitud.Esto se debe utilizar para los datos de longitud fija.
NUMBER : Número de tener la precisión p y
escala s.
PLS_INTEGER : enteros con signo
Los valores PLS_INTEGER menos espacio de almacenamiento y ofrecer un mejor
rendimiento que los valores numéricos.Así que utilice PLS_INTEGER donde se puede
BINARY_INTEGER : enteros con signo (mayor versión más lenta de PLS_INTEGER)
DATE : Intervalo de fechas válido
TIMESTAMP : el número de dígitos en la parte fraccionaria del campo de fecha y hora
SEGUNDO.
INTERVAL YEAR : Tiempo en años y meses, donde year_precision es el
número de dígitos en el campo de fecha y hora AÑO.
INTERVAL DAY: El tiempo en días, horas, minutos y segundos.
day_precision es el número máximo de dígitos en el 'DIA' fractional_seconds_precisiones el número máximo de decimales en el
segundo campo.
RAW : Datos binarios de bytes de tamaño de longitud.
Debe especificar el tamaño de un valor RAW.
Debe especificar el tamaño de un valor RAW.
ROWID : Cadena hexadecimal que representa la dirección única de una fila en su
tabla.
(Sobre todo para los valores devueltos por el ROWID pseudocolumna.)
(Sobre todo para los valores devueltos por el ROWID pseudocolumna.)
UROWID : Cadena Hex en representación de la dirección lógica de una fila de una
tabla organizada por índices
MLSLABEL : Formato binario de un sistema de tipo de datos de funcionamiento label
CLOB : Carácter y objeto grande
NCLOB : Character Large Object Nacional
BLOB: Binary Large Object
BFILE: puntero a un archivo binario en el disco
3) Funciones de conversión entre tipos de datos.
Aqui algunos ejemplos para adicionar y sustraer días y meses y encontrar la diferencia entre
fechas en Oracle. Estos ejemplos toman el resultado de la tabla "dual. La tabla Dual es una
tabla virtual que existe en todas las Bases de datos Oracle. Muchas veces hemos usado la
consulta SELECT sysdate FROM dual; la cual simplemente nos retorna la fecha y hora
actual.
Ajustar Dias, Semanas, Horas y minutos
Para adicionar y sustraer días a una fecha, simplemente usamos los signos + o -
respectivamente. Algunos ejemplos:
SELECT sysdate + 7 FROM dual;
salida:
SYSDATE+7
18/04/12
------------------------------------------------------------------------
SELECT sysdate - 30 FROM dual;
salida
SYSDATE-30
12/03/12
--------------------------------------------------------------------------------
SQL> SELECT to_char(sysdate - 14, 'MM/DD/YYYY HH:MI AM') FROM dual;
salida
TO_CHAR(SYSDATE-14,'MM/DD/YYYYHH:MIAM')
03/28/2012 12:44 AM
--------------------------------------------------------------------------------
En el primer ejemplo, vemos que la consulta retorna la fecha siete días apartir de hoy. La segunda
retorna la fecha de hace 30 días. En la tercera, se ha usado la función de conversión to_char,
para ver las horas y minutos. Esto nos muestra que mientras la fecha, ha cambiado, el tiempo no
cambia.
Los ejemplos primero y tercero ademas muestran como el adicionar días, puede ser útil para
computar semanas. Si ud desea simplificar el computo de semanas, podías usar querys de este
tipo:
SQL> SELECT sysdate + (7 * 3) FROM dual;
salida
SYSDATE+(7*3) 02/05/12
--------------------------------------------------------------------------------
Para trabajar con meses y años (cada uno de los cuales puede variar en número de días)
Oracle ofrece la función numtoyminterval. Esta trabaja en forma similar a la función
numtodsinterval tomando un numero y una cadena string. Las opciones válidas para esta
función son: ‘YEAR’ or ‘MONTH’.
SELECT to_char(sysdate + numtoyminterval(5, 'MONTH'), 'MM/DD/YYYY') FROM dual;
salida
TO_CHAR(SYSDATE+NUMTOYMINTERVAL(5,'MONTH'),'MM/DD/YYYY')
09/11/2012
------------------------------------------------------------------------------------------
SELECT to_char(sysdate + numtoyminterval(2, 'YEAR'), 'MM/DD/YYYY') FROM dual;
salida
TO_CHAR(SYSDATE+NUMTOYMINTERVAL(2,'YEAR'),'MM/DD/YYYY')
04/11/2014
------------------------------------------------------------------------------------------
Comparar fechas
Suponga que deseamos comparar algunas fechas y encontrar el número de días entre ellas. Para
ver este resultado en días, simplemente basta con usar el operador -, de la siguiente manera:
SELECT TO_DATE('11/04/2006', 'MM/DD/YYYY') - sysdate FROM dual;
salida
TO_DATE('11/04/2006','MM/DD/YYYY')-SYSDATE
-1985,0386111111111111
------------------------------------------------------------------------------------------
El resultado es expresado en días, incluyendo horas fracción de horas. Por supuesto si se desea
semanas, se podría dividir el resultado entre 7. De manera similar, si se desea obtener horas, se
debería multiplicar por 24, pero si se desea meses, entonces se podría usar la función
months_between.
SELECT months_between(sysdate, to_date('01/01/2006', 'MM/DD/YYYY')) FROM dual;
salida
MONTHS_BETWEEN(SYSDATE,TO_DATE('01/01/2006','MM/DD/YYYY'))
75,323867607526881
------------------------------------------------------------------------------------------
Retornar la mayor y menor fecha dentro de un conjunto
Las funciones greatest y least pueden ser usadas en fechas para retornar la menor o la mayor
fecha.
SELECT greatest(sysdate,sysdate+1, to_date('09/11/2005','MM/DD/YYYY'), to_date('12/25/
2005','MM/DD/YYYY'))FROM dual;
salida
GREATEST(SYSDATE,SYSDATE+1,TO_DATE('09/11/2005','MM/DD/YYYY'),TO_DATE('12/25/2005','MM/DD/YYYY'))
12/04/12
------------------------------------------------------------------------------------------
SELECT least(sysdate,sysdate+1,to_date('09/11/2005','MM/DD/YYYY'), to_date('12/25/
2005','MM/DD/YYYY'))FROM dual;
salida
LEAST(SYSDATE,SYSDATE+1,TO_DATE('09/11/2005','MM/DD/YYYY'),TO_DATE('12/25/2005','MM/DD/YYYY'))
11/09/05
------------------------------------------------------------------------------------------
Cual es el último día de este mes?
La función last_day retorna el último día del mes pasado como parámetro.
select last_day(sysdate) from dual;
salida
LAST_DAY(SYSDATE) 30/04/12
------------------------------------------------------------------------------------------
Siguiente día de la semana despues de una fecha
La función next_day retorna la fecha de la próxima ocurrencia de un día de la
semana(’Monday’, ‘Tuesday’, etc.) después de una fecha dada. ejemplo: consultar la fecha del
próximo domingo:
select next_day(sysdate,'Domingo') from dual;
salida
NEXT_DAY(SYSDATE,'DOMINGO') 15/04/12
------------------------------------------------------------------------------------------
3) Funciones para manipular fechas
TO_CHAR
Con esta función es posible convertir números a caracteres, otra versión de la misma función nos permite hacer lo mismo con los tipos de dato asociados con fechas y tiempo. De igual manera que con los números, TO_CHAR ofrecen un gran número de posibilidades para formatear fechas y que estas aparezcan tal y como queramos.
Ejemplo:
Convertir números:
Begin
Dbms_output.put_line (to_char (sysdate));
Dbms_output.put_line (to_char (systimestamp));
End;
Resultado:
11/04/12
11-ABR-12 01.10.57,711000000 AM -03:00
Devuelve dia de la "de"semana y el nombre del mes
Begin
dbms_output.put_line(to_char (sysdate,'day,dd "de" Month "de" YYYY' ));
end;
Resultado
Con esta función es posible convertir números a caracteres, otra versión de la misma función nos permite hacer lo mismo con los tipos de dato asociados con fechas y tiempo. De igual manera que con los números, TO_CHAR ofrecen un gran número de posibilidades para formatear fechas y que estas aparezcan tal y como queramos.
Ejemplo:
Convertir números:
Begin
Dbms_output.put_line (to_char (sysdate));
Dbms_output.put_line (to_char (systimestamp));
End;
Resultado:
11/04/12
11-ABR-12 01.10.57,711000000 AM -03:00
Devuelve dia de la "de"semana y el nombre del mes
Begin
dbms_output.put_line(to_char (sysdate,'day,dd "de" Month "de" YYYY' ));
end;
Resultado
miércoles,11
de Abril de 2012
lunes, 9 de abril de 2012
Tarea 1: Buenas Practicas en PL/SQL
Buenas practicas PL / SQL
Pauta para variables y estructuras de datos
Declarar, definir el tipo, inicializar y asignar valor por defecto a las estructura de datos antes de trabajar con ellas
PL/SQL
es un lenguaje fuertemente tipificado. Esto significa que antes de
trabajar con cualquier tipo de estructura de datos, es necesario
declarar las mismas, definir el tipo y opcionalmente inicializarlas o
asignarles un valor por defecto. Las declaraciones deben realizarse en la sección de declaración de variables de un bloque anónimo, procedimiento, función o paquete.
En las declaraciones que se relacionan a tablas y columnas utilizar la cláusula
%TYPE y %ROWTYPE.
Esta forma permite al código adaptarse a cambios de estructuras de datos yautodocumentarse, ya que al leer el código se puede saber a qué tipo de dato hace referencia. Para el tipo VARCHAR2, Oracle separa la memoria necesaria según la longitud definida. Es muy común ‘Hardcodear’ la longitud del mismo a su máxima tamaño para evitar problemas, a costo de utilizar más memoria de la necesaria. Aquí nuevamente se hace conveniente el uso de%TYPE o %SUBTYPE para un mejor aprovechamiento de los recursos de memoria.
En los datos numéricos, definir la precisión.
Oracle soporta hasta 38 dígitos de precisión en los tipos NUMBER .
Si no se define en forma correcta se está derrochando memoria.
Siempre que sea posible, utilizar el tipo de dato RECORD para manejar estructuras.
La declaración de variables individuales o dispersión de datos, muchas veces, complica la lectura del código. La agrupación de los mismos bajo estructuras, facilita la administración y el mantenimiento del código.
Los errores de un código solo pueden ser capturados en la sección ejecutable de un bloque. Si la inicialización de una variable en la sección de declaración falla, el error no se puede manejado. Para ello hay que asegurar que la inicialización lógica no falle y esto se asegura haciendo las inicializaciones al comienzo de la sección de ejecución. Si se produce un error, se puede capturar el error y decidir su tratamiento.
Reemplazar expresiones complejas con variables booleanas y funciones.
Las expresiones booleanas se pueden evaluar con tres valores: TRUE, FALSE o NULL
.Se pueden usar variables de este tipo para ocultar expresiones complejas. Como consecuencia se puede leer más fácilmente el código y es más simple su mantenimiento.
Tener cuidado con las conversiones implícitas de tipos de datos.
Si
bien es sabido que PL/SQL maneja las conversiones implícitas, existen
al menos dos grandes problemas con esto. Las conversiones no son
intuitivas, a veces se realizan de formas no esperadas y ocurren
problemas, especialmente dentro de sentencias SQL. Las reglas de
conversión no están bajo el control de desarrollador. Pueden cambiar
con el upgrade a una versión de Oracle o con el cambio de parámetros como NLS_DATE_FORMAT.
Se puede convertir con el uso explícito de funciones como son:
TO_DATE, TO_CHAR,TO_NUMBER y CAST.
Pauta para declaración y uso de variables de paquetes.
Agrupar los tipos de datos, evitar su exposición y controlar su manipulación.
Los paquetes requieren ciertos tipos de recaudos en la forma de declaración y uso de variables.
Agrupar los tipos de datos, evitar su exposición y controlar su
manipulación permiten obtener las ventajas del uso de los mismos.
Definir las constantes que son referenciadas por toda la aplicación en un paquete único.
Definir las constantes que corresponden a un área específica dentro de un paquete
que encapsula esa funcionalidad nunca colocar literales ‘en duro’, como
‘SI’ o 150 en el código. Es conveniente crear un paquete para mantener estos nombres y valores publicados en reemplazo de los literales.
Este tipo de práctica permite que el código no luzca ‘hard codeado’, lo cual lo hace más legible y mantenible y además evita que los literales sean modificados.
Centralizar las definiciones de Types en las especificaciones del paquete. A medida que se usan los features del lenguaje, se definirán distintos TYPE entre los que podemos incluir:
SUBTYPEs que definen tipos específicos de la aplicación.
Collection TYPEs, como lista de números, fechas y records.
Cursores referenciados
Esto
permite tener estandarizados los tipos de datos para que sean usados
por múltiples programas. Los desarrolladores pueden escribir más
rápidamente y disminuir los bugs. También simplifica el mantenimiento de los types, ya que solo es necesario modificarle/los paquetes donde están declarados.
Disminuir el uso de variables globales en paquetes y en caso de hacerlo, solo en el cuerpo del paquete. Una variable global es una estructura de datos que se puede referenciar fuera del alcance o bloque en donde está declarada. Cuando se declara una variable en un paquete, existe y retiene su valor durante la duración de la sesión. Son peligrosas porque crean dependencias ocultas o efectos laterales. El seguimiento delas mismas es complejo, ya que es necesario ver la implementación para ver sus instancias. Una solución general para esto es pasar estas variables globales como un parámetropara no referenciarlas directamente en el programa.
Exponer las variables globales de los paquetes usando ‘get and set’. Cualquier estructura de datos declarada en la especificación del paquete puede ser referenciada por cualquier programa con autorización de EXECUTE. Esto hace que en forma
deliberada se pueda hacer uso de esas estructuras globales. Para evitar
eso, es conveniente declarar estos datos en el cuerpo del paquete y
proveer al paquete de métodos get y set, declarados en la
especificación. Esta forma le permite a los desarrolladores, acceder a los datos a través de estos programas y manipular los datos según las reglas de estos procedimientos.
Pautas para el uso de estructuras de Control
Las estructuras de control pueden convertirse en un punto de complejidad de un código. La normalización del uso de RETURN y el EXIT garantiza rapidez en la comprensión de las lógicas escritas y facilidad en su mantenimiento.
Nunca se sale de una estructura repetitiva con RETURN o con EXIT. Cada estructura repetitiva tiene un punto de control por donde se debe producir su salida.
Un FOR loop itera desde el valor de comienzo hasta el valor de terminación (ciclo N).
Un WHILE loop itera mientras no se cumpla la condición de terminación. (Ciclo0).
Existe un LOOP con control de la condición al final de ciclo (ciclo 1). Es LOOP … EXIT WHEN condición lógica.
Combinando estos ciclos se puede hacer que las estructuras tengan un único punto de control
para el ciclo repetitivo. Esto facilita la lectura, comprensión y
mantenimiento del programa y permite hacer modificaciones en forma más
simple.
Una
función debe tener un único RETURN exitoso como última línea de la
sección ejecutable. Normalmente, cada manejador de excepciones puede retornar un valor. En los programas largos donde se evalúan muchas condiciones, la existencia de múltiples salidas dificulta el entendimiento y mantenimiento del código.
Nunca declarar el índice de un FOR .. LOOP.
PL/SQL ofrece dos tipos de FOR LOOP: Numéricos y cursores.
Ambos tienen este formato general:
FOR indice_loop IN loop range LOOP
Loop body
END LOOP;
El índice del loop se declara implícitamente durante la ejecución. El ámbito de existencia está restringido al cuerpo del loop. Si
se declarase el índice, se estaría generando otra variable
completamente separada que en el mejor de los casos nunca será usada,
pero si se usa fuera del loop, puede introducir errores.
Pautas para el manejo de excepciones
Aunque se escriba un código perfecto, que no contenga errores y que nunca realice operaciones inapropiadas, el usuario podría usar el programa incorrectamente, produciendo una falla que no estaba contemplada. El uso de excepciones permite capturar y administrar los errores que se pueden producir dentro del código. Su buen uso trae como resultado un código con menos bugsy más fácil de corregir.
Establecer los lineamientos para el manejo de errores antes de comenzar a codificar.
Es impráctico definir secciones de excepciones en el código después de
que el programa fue escrito. La mejor forma de implementar un manejo de
errores en toda la aplicación es usando paquetes que contengan al menos
los siguientes elementos.
Procedimientos que realicen el manejo de tareas de excepciones, como por ejemplo escribir un log de errores.
Un programa que oculte la complejidad de RAISE_APPLICATION_ERROR y los números de aplicación-error.
Una función que retorne el mensaje de error para un código de error.
Utilizar el modelo por defecto de manejo de excepciones para propagar la comunicación de errores. Aprovechar la arquitectura de manejo de errores de PL/SQL y separar las excepciones en bloques.
La sección de código ejecutable debe estar limpia, simple y fácil de seguir. No es necesario
controlar el estado después de cada llamada a un programa. Simplemente
debe incluirse una sección de excepción, capturar el error y determinar
la acción a realizar.
Capturar
todas las excepciones y convertir el significado de los códigos de
error en los retornos a programas que no son PL/SQL. Cuando los
programas PL/SQL son llamados por otros lenguajes de programación (Java,
Visual Basic, etc.), al menos es necesario regresar el estado de error
(código y mensaje)para que administren los mismos .Una manera sencilla de hacer esto es sobrecargar el programa original con otro del mismo nombre y dos parámetros adicionales.
Los
desarrolladores pueden llamar al procedimiento que deseen y chequear
los errores de la manera más apropiada para sus programas.
Usar procedimientos propios de RAISE en lugar de las llamadas explicitas a
RAISE_APPLICATION_ERROR. Cuando se está controlando excepciones de sistemas como
NO_DATA_FOUND, se usa RAISE, pero cuando se quiere controlar un error de aplicación específico, se usa RAISE_APPLICATION_ERROR. Para el último caso, se debe asignar un número de error y mensaje, lo cual termina en un ‘hardcodeo’.Para ello se puede utilizar constantes para especificar un número. Una manera más clara es proveer un procedimiento que automáticamente controle el número de error y determina la forma de ejecutar el error.
Los
desarrolladores no tienen que determinar cuál es el número de error que
tienen que usar, solo pasan la constante que desean usar y dejan que la
rutina determine cuál es el RAISE correspondiente.
No sobrecargar una EXCEPTION con múltiples errores al menos que la pérdidade información sea intencional.
No declarar una excepción genérica como ERROR_GENERAL y luego ejecutar la excepción en diferentes circunstancias. La lectura del código traerá problemas alintentar cual fue la causa de problema. La excepción NO_DATA_FOUND se puede utilizar para indicar que no se encontraron filas en la ejecución de un query o para indicar que se llegó al final de un archivo.
No
Manejar excepciones que no pueden evitarse, pero si anticiparse. Si
cuando se está escribiendo un programa, se puede predecir que un error
va a ocurrir, se debería incluir un manejador para ese caso.
Evitar exponer código en duro para el manejo de errores, reemplazar por procedimientos que administren los mismos. Evitar exponer código en duro para el manejo de errores, reemplazar por procedimientos que administren los mismos. La mejor manera de registrar en forma consistente y tener mantener la calidad del seguimiento de errores por toda la aplicación es ofreciendo un conjunto de procedimientos predefinidos que canalicen el manejo de los mismos. Es fundamental que el equipo de desarrollo use siempre solamente estos procedimientos en sus cláusulas WHEN.
Usar nombres constantes para flexibilizar los números y mensajes de errores de aplicación, Oracle define 1000 números de error, entre –20000 y –20999 para usar para nuestra aplicación.
Se recomienda definir todos los errores en una tabla o un archivo del
sistema operativo, construir paquetes para manipular esos datos y
ejecutar el RAISE usando esos nombres y no códigos en duro.
Usar WHEN OTHERS solo para excepciones desconocidas que deben serejecutadas. No es conveniente usar WHEN OTHERS para
cualquier error. Si se puede conocer el tipo de excepción que se quiere
ejecutar, es conveniente administrarla en forma específica.
Pautas mínimas para uso de SQL dentro de PL/SQL
La escritura de SQL dentro del código es uno de los aspectos más flexibles de PL/SQL y también puede ser uno de los más peligrosos. El establecimiento de reglas claras para su inclusión permite asegurar beneficios y buenos resultados.
Usar transacciones autónomas para aislar los efectos del ROLLBACK y COMMIT Permite grabar o realizar rollback dentro de un código PL/SQL sin afectar la sesión principal.
No utilizar COMMIT o ROLLBACK dentro de los procedimientos PL/SQL que son utilizados por procesos en otros leguajes. El COMMIT o ROLLBACK debe utilizarse dentro del proceso que llama los procedimientos PL/SQL. Cuando
los procedimientos PL/SQL son llamados por otros lenguajes de
programación (Java, Visual Basic, etc.) no deben utilizar las sentencias
de manejo de transaccionesCOMMIT o ROLLBACK de modo de posibilitar un ordenado control de transacciones.
Usar COUNT solo cuando es necesario saber el número de ocurrencias. No usar
COUNT para saber si hay una o más de una fila para una condición dada. Solo se debe usar
COUNT para saber cuántas filas hay.
Usar
cursores implícitos para realizar operaciones sobre muchos registros
este constructor realiza la apertura y cierre en forma automática. Es
fácil de usar y su lectura es más simple.
Nunca usar cursores implícitos para una fila El FOR LOOP está diseñado para múltiples filas de un cursor. Para un solo registro es más eficiente un SELECT INTO o un cursor explícito.
Parametrizar cursores explícitos. Los cursores retornan información como lo haría una función, por lo cual también pueden
aceptar parámetros. Si se define un cursor con parámetros, se puede
hacer quesea reutilizable en diferentes circunstancias de un programa.
Esto es mejor si se define en un paquete.
Usar RETURNING para obtener información sobre filas modificada
Referenciar atributos del cursor inmediatamente después de ejecutar la operación de SQL. Las sentencias INSERT, UPDATE y DELETE se ejecutan como cursores implícitos en PL/SQL. Es decir, no se puede declarar, abrir y procesar este tipo de operaciones en forma
explícita. El motor de Oracle SQL toma el control y administración del
cursor. Se puede obtener información acerca de los resultados de estas
operaciones implícitas más recientemente utilizada consultando los
siguientes atributos de cursor.
SQL%ROWCOUNT: Números de filas afectadas por la instrucción DML.
SQL%ISOPEN: Siempre es falso en los manejos de cursores implícitos.
SQL%FOUND: Retorna TRUE si la operación afecta al menos una fila.
SQL%NOTFOUND: Retorna FALSE si la operación afecta al menos una fila. Hay un solo set de atributos SQL% en una sesión, el cual refleja la última operación implícita realizada. Por lo cual el uso de estos atributos deberá hacerse con el mínimo uso de código entre la operación y la referencia al atributo. De otra manera el valor retornado por el atributo podría no corresponder al SQL deseado.
Usar BULK COLLECT para
mejorar la performance de los querys multiregistros. En algunas
oportunidades es necesario recuperar un gran número de filas desde la
base de datos.
BULK COLLECT permite obtener el set de filas en una sola llamada al motor y recuperar el resultado en un arreglo (COLLECTION).Para usar este método es necesario declarar un arreglo para mantener los datos recuperados y luego anteponer al INTO la cláusula BULK COLLECT.
Esta forma de recuperación de datos mejora (en algunos casos enormemente) la performance del query .Se debe tener cuidado cuando el
SELECT retorna miles de filas ya que si el mismo programa
está corriendo con diferentes usuarios en una misma instancia, puede
haber problemas de memoria. Se podría restringir usando ROWNUM o LIMIT para cada instancia.
Usar FORALL para mejorar la performance de DML basados en arreglos.
Para los casos en que es necesario modificar (INSERT, DELETE o UPDATE) un gran número de filas en una base de datos dentro de un PL/SQL, se recomienda la sentencia FORALL
. La performance mejora notablemente ya que se reduce el número de llamadas entre PL/SQL y el SQL engine.
Reglas generales para performance
Para el manejo de datos dentro de un código PL/SQL es necesario tener en cuenta las siguientes premisas.
Una
sentencia SQL es más rápida que un programa. Siempre es preferible
utilizar la potencia del SQL antes que emular su funcionamiento con un
PL/SQL largo y complejo.
Un programa pequeño es más rápido que uno extenso. El uso de programas largos agrega más tiempo de ejecución. El uso de paquetes pequeños permite al servidor disponer de ellos de manera más rápida y eficiente
Evitar
llamadas repetitivas al sql engine Mientras menos solicitudes de
servicios se hagan al sql engine, más rápido se ejecutará un programa. Para el caso de operaciones de SQL similares o repetitivas, utilizarFORALL, BULKS, variables BIND, etc.
jueves, 5 de abril de 2012
Clase 04 de Abril
--ejercicio de ppt de arreglos
set serveroutput on
declare
type tArreglo is varray(6) of varchar2(25);
miarreglo tArreglo := tArreglo('Juan', 'Pedro', 'Diego', 'Alicia', 'Jose', 'Salir');
i integer := 1;
begin
loop
exit when miarreglo(i) = 'Salir';
dbms_output.put_line ('Elemento '||i|| ': '||miarreglo(i));
i := i + 1;
end loop;
end;
--ver limite de un varray
set serveroutput on
declare
type tArreglo is varray(6) of varchar2(25);
miarreglo tArreglo := tArreglo('Juan', 'Pedro', 'Diego', 'Alicia', 'Jose');
i integer := 1;
begin
dbms_output.put_line ('El limite es: '||miarreglo.limit);
end;
--copiar el tipo de dato de la columnia first_name de la tabla employees a la variable vnombre
set serveroutput on;
declare
vnombre employees.first_name%type;
begin
select first_name into vnombre from employees where employee_id = 104;
dbms_output.put_line('Nombre: '||vnombre);
end;
--lo mismo de antes pero nombre y apellido
set serveroutput on;
declare
vnombre employees.first_name%type;
vapellido employees.last_name%type;
begin
select first_name, last_name into vnombre, vapellido from employees where employee_id = 104;
dbms_output.put_line('Nombre y Apellido: '||vnombre ||' ' ||vapellido);
end;
--usar record(registros) para buscar nombre, apellido, codigo cargo y salario--
set serveroutput on;
declare
type tregistro is record (
vnombre employees.first_name%type,
vapellido employees.last_name%type,
vcodcargo employees.job_id%type,
vsalario employees.salary%type);
vregistro tregistro;
begin
select first_name, last_name, job_id, salary into vregistro from employees where employee_id = 104;
dbms_output.put_line('Nombre y Apellido: '||vregistro.vnombre || ' '|| vregistro.vapellido ||' '|| 'Codigo de Cargo: '||vregistro.vcodcargo ||' '|| 'Salario: ' || vregistro.vsalario);
end;
--asdf
set serveroutput on;
declare
type tregistro is record (
vnombre employees.first_name%type,
vapellido employees.last_name%type,
vcodcargo employees.job_id%type,
vsalario employees.salary%type);
vregistro tregistro;
vcargo jobs.job_title%type;
begin
select first_name, last_name, job_id, salary into vregistro from employees where employee_id = 104;
select job_title into vcargo from jobs where job_id = vregistro.vcodcargo;
dbms_output.put_line('Nombre y Apellido: '||vregistro.vnombre || ' '|| vregistro.vapellido ||' '|| 'Codigo de Cargo: '||vregistro.vcodcargo ||' '|| 'Salario: ' || vregistro.vsalario || ' '||'Cargo: '|| vregistro.vcargo);
end;
set serveroutput on
declare
type tArreglo is varray(6) of varchar2(25);
miarreglo tArreglo := tArreglo('Juan', 'Pedro', 'Diego', 'Alicia', 'Jose', 'Salir');
i integer := 1;
begin
loop
exit when miarreglo(i) = 'Salir';
dbms_output.put_line ('Elemento '||i|| ': '||miarreglo(i));
i := i + 1;
end loop;
end;
--ver limite de un varray
set serveroutput on
declare
type tArreglo is varray(6) of varchar2(25);
miarreglo tArreglo := tArreglo('Juan', 'Pedro', 'Diego', 'Alicia', 'Jose');
i integer := 1;
begin
dbms_output.put_line ('El limite es: '||miarreglo.limit);
end;
--copiar el tipo de dato de la columnia first_name de la tabla employees a la variable vnombre
set serveroutput on;
declare
vnombre employees.first_name%type;
begin
select first_name into vnombre from employees where employee_id = 104;
dbms_output.put_line('Nombre: '||vnombre);
end;
--lo mismo de antes pero nombre y apellido
set serveroutput on;
declare
vnombre employees.first_name%type;
vapellido employees.last_name%type;
begin
select first_name, last_name into vnombre, vapellido from employees where employee_id = 104;
dbms_output.put_line('Nombre y Apellido: '||vnombre ||' ' ||vapellido);
end;
--usar record(registros) para buscar nombre, apellido, codigo cargo y salario--
set serveroutput on;
declare
type tregistro is record (
vnombre employees.first_name%type,
vapellido employees.last_name%type,
vcodcargo employees.job_id%type,
vsalario employees.salary%type);
vregistro tregistro;
begin
select first_name, last_name, job_id, salary into vregistro from employees where employee_id = 104;
dbms_output.put_line('Nombre y Apellido: '||vregistro.vnombre || ' '|| vregistro.vapellido ||' '|| 'Codigo de Cargo: '||vregistro.vcodcargo ||' '|| 'Salario: ' || vregistro.vsalario);
end;
--asdf
set serveroutput on;
declare
type tregistro is record (
vnombre employees.first_name%type,
vapellido employees.last_name%type,
vcodcargo employees.job_id%type,
vsalario employees.salary%type);
vregistro tregistro;
vcargo jobs.job_title%type;
begin
select first_name, last_name, job_id, salary into vregistro from employees where employee_id = 104;
select job_title into vcargo from jobs where job_id = vregistro.vcodcargo;
dbms_output.put_line('Nombre y Apellido: '||vregistro.vnombre || ' '|| vregistro.vapellido ||' '|| 'Codigo de Cargo: '||vregistro.vcodcargo ||' '|| 'Salario: ' || vregistro.vsalario || ' '||'Cargo: '|| vregistro.vcargo);
end;
Suscribirse a:
Entradas (Atom)