Descripción de tablas

Las tres tablas son telcuent, detld y totxabonado
SQL> DESCRIBE TELCUENT ;
Name
Null? Type
-------------------------------
-------- ----
CONT_SAT
NUMBER(6)
COD_CUENTA
NUMBER(10)
ABONADOA NOT
NULL VARCHAR2(15)
SQL> DESCRIBE DETLD ;
Name
Null? Type
-------------------------------
-------- ----
Anno
NUMBER(4)
MES
NUMBER(2)
Abonadoa
VARCHAR2(15)
Fechacom
DATE
Décima
NUMBER(1)
Clase
VARCHAR2(3)
Abonadob
VARCHAR2(15)
Destino
VARCHAR2(15)
Duración
NUMBER(5,2)
LLAM_CEL
VARCHAR2(2)
OPER_CEL
VARCHAR2(2)
Banda
VARCHAR2(2)
Novedad
CHAR(1)
Tarifa
VARCHAR2(2)
VLR_LLAM
NUMBER(12,2)
TIPO_LLAM
NUMBER(3)
DESCUENTO
VARCHAR2(20)
VLR_EXPRESO
NUMBER(12,2)
VLR_MIN
NUMBER(12,2)
SQL> DESCRIBE TOTXABONADO ;
Name
Null? Type
-------------------------------
-------- ----
CONT_SAT
NUMBER(6)
COD_CUENTA
NUMBER(10)
Anno
NUMBER(4)
MES
NUMBER(2)
Abonadoa
VARCHAR2(15)
Destino
VARCHAR2(15)
Clase
VARCHAR2(2)
Novedad
VARCHAR2(1)
VLR_ABONADO
NUMBER(10,2)
MIN_ABONADO
NUMBER(8,2)
DESC_ABONADO
NUMBER(10,2)
EXPR_ABONADO
NUMBER(10,2)
Esta es la definición de datos de las
Tres tablas implicadas en el proceso.
El proceso de carga es el siguiente:
La tabla detld contiene datos de la
Facturación telefónica de cuertos
Clientes que están relacionados por
Contrato y linea telefónica en la
Tabla telcuent.
La tabla totxabonado lo que hace es
Recibir un resumen calculado de los
Valores facturados por cada linea
Telefónica del cliente (vlr_abonado
Es el valor facturado para una linea
Telefónica en el mes, debe
Corresponder a la sumatoria de
VLR_LLAM EN LA TABLA DETLD;
MIN_ABONADO CORRESPONDE A LA
SUMATORIA DE VLR_MIN; EL DESC_ABONADO
Corresponde a realizar una resta
Entre el vlr_abonado y el
EXPR_ABONADO; EL CAMPO EXPR_ABONADO
Corresponde a la sumatoria de
vlr_expreso en la tabla detld).
El ejemplo que me ha enviado me ha
Resuelto ciertas dudas pero no me fue
Posible adaptarlo correctamente a mi
Caso,
porque la actualización se debe hacer
Cuando existan datos en la tabla
Totxabonado, de lo contrario debe
HACER UN INSERT DE LOS DATOS
Encontrados cuando se compara
Abonadoa en ambas tablas.
Gracias por su ayuda,
También le envío el procedimiento que trate de implementar.
CREATE OR REPLACE PROCEDURE PR_TOTXABON1
IS
V_CONT_SAT CUENTA.CONT_SAT%TYPE;
V_COD_CUENTA CUENTA.COD_CUENTA%TYPE;
V_ABONADOA DETLD.ABONADOA%TYPE;
V_ANNO DETLD.ANNO%TYPE;
V_MES DETLD.MES%TYPE;
V_DESTINO DETLD.DESTINO%TYPE;
V_CLASE DETLD.CLASE%TYPE;
V_NOVEDAD DETLD.NOVEDAD%TYPE;
V_VLR_LLAM TOTXABONADO.VLR_ABONADO%TYPE;
V_VLR_MIN TOTXABONADO.MIN_ABONADO%TYPE;
V_VLR_DESC TOTXABONADO.DESC_ABONADO%TYPE;
V_VLR_EXPRESO TOTXABONADO.EXPR_ABONADO%TYPE;
Cursor c_uno is (select distinct
A.CONT_SAT,
A.COD_CUENTA,
a.abonadoa,
B.ANNO,
B.MES,
B.DESTINO,
B.CLASE,
B.NOVEDAD,
FROM TELCUENT A, DETLD B
WHERE A.ABONADOA = '76322472'
AND A.ABONADOA = B.ABONADOA
GROUP BY A.CONT_SAT, A.COD_CUENTA, A.ABONADOA, B.ANNO,
B.MES, B.DESTINO, B.CLASE, B.NOVEDAD);
R_UNO C_UNO%ROWTYPE;
BEGIN
V_VLR_LLAM :=NULL;
V_VLR_MIN :=NULL;
V_VLR_DESC :=NULL;
V_VLR_EXPRESO :=NULL;
FOR R_UNO IN C_UNO LOOP
V_CONT_SAT := R_UNO.CONT_SAT;
V_COD_CUENTA :=R_UNO.COD_CUENTA;
V_ABONADOA := R_UNO.ABONADOA
V_MES :=R_UNO.MES;
V_DESTINO :=R_UNO.DESTINO;
V_CLASE :=R_UNO.CLASE;
V_NOVEDAD :=R_UNO.NOVEDAD;
BEGIN
SELECT SUM(B.VLR_LLAM),
SUM(B.VLR_MIN),
SUM(B.VLR_LLAM)-SUM(B.VLR_EXPRESO),
SUM(B.VLR_EXPRESO) EXPR_ABONADO
INTO
V_VLR_LLAM,
V_VLR_MIN ,
V_VLR_DESC,
V_VLR_EXPRESO
FROM DETLD
WHERE ABONADOA = R_UNO.ABONADOA;
SELECT * FROM TOTXABONADO
WHERE ABONADOA = R_UNO.ABONADOA;
IF SQL%FOUND THEN
UPDATE TOTXABONADO
SET
VLR_ABONADO = VLR_ABONADO + V_VLR_LLAM,
MIN_ABONADO = MIN_ABONADO + V_VLR_MIN,
DESC_ABONADO = DESC_ABONADO + V_VLR_DESC,
EXPR_ABONADO = EXPR_ABONADO + V_VLR_EXPRESO;
END IF;
END;
IF SQL%FOUND THEN
INSERT INTO TOTXABONADO
VALUES (
V_CONT_SAT,
V_COD_CUENTA ,
V_ABONADOA,
V_ANNO ,
V_MES ,
V_DESTINO ,
V_CLASE ,
V_NOVEDAD ,
V_VLR_LLAM ,
V_VLR_MIN ,
V_VLR_DESC ,
V_VLR_EXPRESO );
END IF;
END LOOP;
END;
/

1 respuesta

Respuesta
1
Tal como has construido el procedimiento, entiendo que el valor de ABONADOA lo tomas de forma externa de algún modo y utilizas dicho valor para ejecutar el procedimiento. Con ello, supongo que el procedimiento está dirigido a los datos de un sólo valor de ABONADOA cada vez.
Bueno, no sé muy bien qué significan el resto de los campos de las tablas, pero creo que el resumen implica a un abonado, en un mes y año determinado, y con una clase, un destino, una novedad, etc.
De modo que todos esos valores hay que tenerlos en cuenta en cada paso. Creo que el procedimiento sería algo así (repásalo por si tiene errores de escritura):
CREATE OR REPLACE PROCEDURE PR_TOTXABON1
IS
-- Variables para recoger los valores
V_CONT_SAT CUENTA.CONT_SAT%TYPE;
V_COD_CUENTA CUENTA.COD_CUENTA%TYPE;
V_ABONADOA DETLD.ABONADOA%TYPE;
V_ANNO DETLD.ANNO%TYPE;
V_MES DETLD.MES%TYPE;
V_DESTINO DETLD.DESTINO%TYPE;
V_CLASE DETLD.CLASE%TYPE;
V_NOVEDAD DETLD.NOVEDAD%TYPE;
V_VLR_ABONADO TOTXABONADO.VLR_ABONADO%TYPE;
V_MIN_ABONADO TOTXABONADO.MIN_ABONADO%TYPE;
V_DESC_ABONADO TOTXABONADO.DESC_ABONADO%TYPE;
V_EXPR_ABONADO TOTXABONADO.EXPR_ABONADO%TYPE;
-- Declaracion del cursor
CURSOR C_UNO IS(
SELECT A.CONT_SAT, A.COD_CUENTA, A.ABONADOA,
B.ANNO, B.MES, B.CLASE, B.NOVEDAD, B.DESTINO,
SUM(B.VLR_LLAM) VLR_ABONADO,
SUM(B.VLR_MIN) MIN_ABONADO,
SUM(B.VLR_EXPRESO) EXPR_ABONADO
FROM TELCUENT A, DETLD B
WHERE ABONADOA = '76322472'
AND A.ABONADOA = B.ABONODOA
GROUP BY A.CONT_SAT, A.COD_CUENTA, A.ABONADOA,
B.ANNO, B.MES, B.CLASE, B.NOVEDD, B.DESTINO);
R_UNO C_UNO%ROWTYPE;
IND_HAY_DATOS VAHCAR2(1); -- Va a indicar si hay datos en TOTXABONADO
BEGIN
FOR R_UNO IN C_UNO -- Recorremos el cursor
LOOP
-- Las variables recogen los valores necesarios
V_CONT_SAT := R_UNO.CONT_SAT;
V_COD_CUENTA := R_UNO.COD_CUENTA;
V_ANNO := R_UNO.ANNO;
V_MES := R_UNO.MES;
V_ABONADOA := R_UNO.ABONADOA;
V_DESTINO := R_UNO.DESTINO;
V_CLASE := R_UNO.CLASE;
V_NOVEDAD := R_UNO.NOVEDAD;
V_VLR_ABONADO := R_UNO.VLR_ABONADO;
V_MIN_ABONADO := R_UNO.MIN_ABONADO;
V_EXPR_ABONADO := R_UNO_EXPR_ABONADO;
V_DESC_ABONADO := V_VLR_ABPNADO - V_EXPR_ABONADO;
IND_HAY_DATOS := 'N'; -- Inicializacion. Hasta comprobarlo, no hay datos
-- Si hay datos en TOTXABONADO, IND_HAY_DATOS toma el valor 'S'
BEGIN
SELECT 'S'
INTO IND_HAY_DATOS
FROM TOTXABONADO
WHERE CONT_SAT = V_CONT_SAT -- Hay que tener en cuenta todos los campos
AND COD_CUENTA = V_COD_CUENTA
AND ANNO = V_ANNO
AND MES = V_MES
AND ABONADOA = V_ACONADOA
AND DESTINO = V_DESTINO
AND CLASE = V_CLASE
AND NOVEDAD = V_NOVEDAD;
EXCEPTION
WHEN NO_DATA_FOUND THEN NULL; -- Si no encuentra datos, IND_HAY_DATOS = 'N'
END;
-- Si hay datos en TOTXABONADO,se actualizan
IF IND_HAY_DATOS = 'S' THEN
UPDATE TOTXABONADO
SET VLR_ABONADO = V_VLR_ABONADO,
MIN_ABONADO = V_MIN_ABONADO,
DESC_ABONADO = V_DESC_ABONADO,
EXPR_ABONADO = V_EXPR_ABONADO
WHERE CONT_SAT = V_CONT_SAT
AND COD_CUENTA = V_COD_CUENTA
AND ANNO = V_ANNO
AND MES = V_MES
AND ABONADOA = V_ABONADOA
AND DESTINO = V_DESTINO
AND CLASE = V_CLASE
AND NOVEDAD = V_NOVEDAD;
-- Si no hay datos en TOTXABONADO se inserta el registro
ELSE
INSERT INTO TOTXABONADO
VALUES(V_CONT_SAT, V_COD_CUENTA, V_ANNO, V_MES,
V_ABONADOA, V_DESTINO, V_CLASE, V_NOVEDAD,
V_VLR_ABONADO, V_MIN_ABONADO, V_DESC_ABONADO, V_EXPR_ABONADO);
END IF;
END LOOP;
END;
/
Si ves que no he entendido algo, o que me he saltado algo importante, aquí estoy.
Mil gracias por la ayuda que has brindado por que me sirvió de mucho para desarrollar bien el procedimiento, habían cosas que mandaste en el procedimiento que yo no sabia que se podían hacer pero que me arreglaron el que estaba realizando.
Mil gracias

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas