Mostrando entradas con la etiqueta Oracle. Mostrar todas las entradas
Mostrando entradas con la etiqueta Oracle. Mostrar todas las entradas

7 feb 2011

PL SQL - Seleccionar los N Top por categoria

Hola!!!

Hoy estuve tratando de descifrar como lograr que en una sola consulta vinieran las ultimas 5 facturas emitidas por tienda en el 2010.

Después de leer un "poco" y navegar otro poco, quemar un poco de neuronas, etc, etc...

Mi intención era poder hacer algo como

Select periodo, tienda, serie, max(factura)
from CC_ventas


Pero que en lugar de traerme solo una factura me trajera 5 por tienda.

El resultado quedo algo así:

select a.periodo, a.tienda, a.serie, a.factura,
count(*) as ranking
from cc_ventas a, cc_ventas b
where a.periodo = b.periodo
and a.tienda = b.tienda
and a.serie = b.serie
and a.factura <= b.factura and a.periodo = '2010' group by a.periodo, a.tienda, a.serie, a.factura having count(*) <= 5 order by a.periodo, a.tienda, a.serie, count(*) desc;

OJO: dos cosas importantes 1. Si ven la linea and a.factura <= b.factura hace un join de el mismo y todos menos el. Si no desean obtener los últimos sino los primeros registros solo deben de cambiarlo a >=.

2. Si desean traer mas de 5 registros por categoría solo deben de cambiar el valor en la linea: having count(*) <= 5

El código de access que me sirvió de ejemplo esta Aquí.

Espero les sea de utilidad.

19 feb 2009

PL/SQL Usar MD5 en un trigger

Hola!!

Estamos desarrollando una nueva solucion de intranet, y necesitabamos almacenar las contraseñas de usuarios en un entorno "Relativamente" seguro. Por lo que se decidio dejarlas en la BDD con MD5 y realizar la validacion cada vez que el usuario envia la contraseña.

Para optimizar el proceso, todos los usuarios tendrian de clave inicial una palabra comun y ellos en su primer acceso tendrian que actualizarla.

Para que este proceso se llevara a cabo a nivel de base de datos y no de WEB se utilizaria la funcion DBMS_OBFUSCATION_TOOLKIT.MD5. Sin embargo truco para usar esta funcion es que hay que forzar el descriptor del parametro, de lo contrario Oracle envia el mensaje:

PLS-00307: too many declarations of 'MD5' match this call

Esto se debe a que hay dos declaraciones de la misma funcion con el tipo de ingreso.
1. DBMS_OBFUSCATION_TOOLKIT.MD5(INPUT: RAW)
2. DBMS_OBFUSCATION_TOOLKIT.MD5(INPUT_STRING: VARCHAR2)

SOLUCION: Forzar el tipo de parametro que recibira la funcion.
DBMS_OBFUSCATION_TOOLKIT.MD5(input_string=>'usuario');

Aca les dejo todo el trigger por si les sirve de referencia:

create or replace trigger "TABLA1_BI"
BEFORE insert on "TABLA1" for each row
declare
raw_data VARCHAR2(100);
texto_cifrado VARCHAR2(100);
begin
--Convierte la cadena DOSPINOS a MD5
raw_data :=
DBMS_OBFUSCATION_TOOLKIT.MD5(input_string=>'usuario');
--Convierte el MD5
crudo a datos legibles
select lower(rawtohex(raw_data)) into texto_cifrado
from dual;
--Asigna al nuevo campo el dato en MD5 legible
:new.password
:= texto_cifrado;
--imprime el debug para ver que devuelve la funcion
--DBMS_OUTPUT.put_line('texto_cifrado 'texto_cifrado);
end;

Las fuentes que use de ejemplo estan Aqui y Aqui

9 dic 2008

PL/SQL Recorrer un cursor

Buenos dias,

Cuando se esta realizando un recorrido sobre un cursor en PL/SQL un metodo practico de realizarlo es a traves de LOOP ... END LOOP. Para el caso de la variable que contendra el registro activo, esta se define en la creacion del ciclo y para utilizar los datos se maneja variable.dato (ej. c.nombre)


FOR d IN c_descuentos LOOP
   --El cursor que vamos a recorrer es C_DESCUENTOS
   --El registro activo esta en la variable d
   insert into hist_descuentos(codigo,fecha_inicio,fecha_fin)
   values(d.cod,d.fini,d.ffin);
END LOOP; -- Descuentos


los LOOP se pueden usar anidados siempre tomando en cuenta el scope de cada cursor, para que no les de un problema de acceso a datos o un comportamiento inesperado.

La referencia en ingles esta aca

PL/SQL Cursores

Buenos dias,

Los cursores en Oracle pueden ser de varios tipos, sin embargo los dos mas usados son:
1. Cursores implicitos: Son aquellos que devuelven un unico valor usando SELECT INTO.
Select nombre into V_nombre
from VNT_empleado
where cod_empleado = '123321';

2. Cursores explicitos: Son aquellos quedevuelven un conjunto de registros, puden o no contener parametros para filtrar el contenido que devuelven.  Utilizan la instruccion CURSOR IS
Cursor C_empleados is
Select cod_empleado, nombre, area
from VNT_empleado
where cod_area in ('01','03');
Para poder crear un cursor con parametros estos se deben de definir en el encabezado de la instruccion CURSOR NOMBRE(PARAMETROS) IS
Cursor C_empleados(p_compania in varchar2) is
Select cod_empleado, nombre, area
from VNT_empleado
where cod_compania = p_compania;

Espero les sea de utilidad, cualquier cosa no duden en escribirme

Hay todo un manual muy completo de cursores aca