Buenas amigos del foro tengo el siguiente problema: tengo dos procedimientos almacenados el primero es el siguiente:
Código SQL
[-] SET TERM ^ ;
CREATE OR ALTER PROCEDURE LISTADO_REGISTRO_SERVICIOS_AMB (
f1 date,
f2 date,
valor char(1))
returns (
fecha date,
nro_recibo integer,
tipo_servicio varchar(30),
servicio varchar(70),
costo numeric(18,2),
costo_total numeric(18,2),
literal varchar(300),
nro_ambulatorio integer,
usuario varchar(20),
nombre_amb varchar(70),
edad integer,
sexo char(1),
tipo_pac varchar(20),
factura varchar(10),
hora time,
monto_cobrar numeric(18,2),
porcentaje integer,
nro_registro integer,
nro_factura integer)
as
declare variable nro_asegurado integer;
declare variable nro_internado integer;
begin
for
select r.nro_recibo,cast(r.fecha as date),d.ap_paterno||' '||d.ap_materno||' '||d.nombres||'-->'||e.nombre_e, case r.porcentaje_cobro when 100 then c.costo else (r.porcentaje_cobro*c.costo)/100 end,r.costo_total,r.literal,r.nro_ambulatorio,r.usuario,r.tipo_paciente,r.nro_asegurado,r.nro_intern acion,r.factura,cast(r.fecha as time),r.monto_cobrar,r.porcentaje_cobro,c.nro,r.nro_factura
from (recibo r inner join registro_consulta_med c on r.nro_recibo=c.nro_recibo),c_externa c1,especialidad e,doctor d
where ((c.nro_consulta=c1.nro)and(c1.id_doctor=d.ci)and(d.esp=e.nro)and(cast(r.fecha as date) between :f1 and :f2)and((r.cancelado=:valor)or(r.cancelado='M')))
into :nro_recibo,:fecha,:servicio,:costo,:costo_total,:literal,:nro_ambulatorio,:usuario,:tipo_pac,:nro_a segurado,:nro_internado,:factura,:hora,:monto_cobrar,orcentaje,:nro_registro,:nro_factura
DO
begin
if (factura='F') then
factura='RECIBO';
ELSE
FACTURA='FACTURA';
tipo_servicio='CONSULTA EXTERNA';
if (tipo_pac='AMBULATORIO') then
BEGIN
select X.ap_paterno||' '||coalesce(X.ap_materno,'')||' '||X.nombreS,X.edad,X.sexo
from paciente_externo X
where (x.nro=:nro_ambulatorio)
into :nombre_amb,:edad,:sexo;
end
if (tipo_pac='ASEGURADO') then
BEGIN
select R.ap_paterno||' '||coalesce(R.ap_materno,'')||' '||r.nombres,R.edad,R.sexo
from paciente_asegurado R,instituciones i
where ((r.nro_registro=:nro_asegurado)and(R.habilitado='T')and(r.institucion=i.nro))
into :nombre_amb,:edad,:sexo;
END
if (TIPO_PAC='INTERNADO') then
BEGIN
select p.ap_paterno||' '||coalesce(p.ap_materno,'')||' '||p.nombre,p.edad,p.sexo
from paciente p,registro_internacion n
where ((n.nro=:nro_internado)and(n.nro_historia=p.nro))
into :nombre_amb,:edad,:sexo;
END
suspend;
end
for
select r.nro_recibo,cast(r.fecha as date),e.nombre, case r.porcentaje_cobro when 100 then g.costo else (r.porcentaje_cobro*g.costo)/100 end,r.costo_total,r.literal,r.nro_ambulatorio,r.usuario,r.tipo_paciente,r.nro_asegurado,r.nro_intern acion,r.factura,cast(r.fecha as time),r.monto_cobrar,r.porcentaje_cobro,g.nro,r.nro_factura
from recibo r,registro_emergencias g,emergencias e
where ((R.nro_recibo=G.nro_recibo)AND(g.nro_emergencias=e.nro)and(cast(g.fecha as date) between :f1 and :f2)and((r.cancelado=:valor)or(r.cancelado='M')))
into :nro_recibo,:fecha,:servicio,:costo,:costo_total,:literal,:nro_ambulatorio,:usuario,:tipo_pac,:nro_a segurado,:nro_internado, :factura,:hora,:monto_cobrar,orcentaje,:nro_registro,:nro_factura
DO
begin
if (factura='F') then
factura='RECIBO';
ELSE
FACTURA='FACTURA';
if (tipo_pac='AMBULATORIO') then
BEGIN
select X.ap_paterno||' '||coalesce(X.ap_materno,'')||' '||X.nombreS,X.edad,X.sexo
from paciente_externo X
where (x.nro=:nro_ambulatorio)
into :nombre_amb,:edad,:sexo;
end
if (tipo_pac='ASEGURADO') then
BEGIN
select R.ap_paterno||' '||coalesce(R.ap_materno,'')||' '||r.nombres,R.edad,R.sexo
from paciente_asegurado R,instituciones i
where ((r.nro_registro=:nro_asegurado)and(R.habilitado='T')and(r.institucion=i.nro))
into :nombre_amb,:edad,:sexo;
END
if (TIPO_PAC='INTERNADO') then
BEGIN
select p.ap_paterno||' '||coalesce(p.ap_materno,'')||' '||p.nombre,p.edad,p.sexo
from paciente p,registro_internacion n
where ((n.nro=:nro_internado)and(n.nro_historia=p.nro))
into :nombre_amb,:edad,:sexo;
END
tipo_servicio='EMERGENCIAS';
suspend;
end
for
select r.nro_recibo,cast(r.fecha as date),g.nombre, case r.porcentaje_cobro when 100 then r1.costo else (r.porcentaje_cobro*r1.costo)/100 end,r.costo_total,r.literal,r.nro_ambulatorio,r.usuario,r.tipo_paciente,r.nro_asegurado,r.nro_intern acion,r.factura,cast(r.fecha as time),r.monto_cobrar,r.porcentaje_cobro,r1.nro,r.nro_factura
from recibo r,registro__ecografia R1,ecografia g
where ((r1.nro_recibo=r.nro_recibo)and(r1.tipo_ecografia=g.nro)and(cast(r.fecha as date) between :f1 and :f2)and(r.cancelado=:valor)and((r.cancelado=:valor)or(r.cancelado='M')))
into :nro_recibo,:fecha,:servicio,:costo,:costo_total,:literal,:nro_ambulatorio,:usuario,:tipo_pac,:nro_a segurado,:nro_internado,:factura,:hora,:monto_cobrar,orcentaje,:nro_registro,:nro_factura
DO
begin
if (factura='F') then
factura='RECIBO';
ELSE
FACTURA='FACTURA';
if (tipo_pac='AMBULATORIO') then
BEGIN
select X.ap_paterno||' '||coalesce(X.ap_materno,'')||' '||X.nombreS,X.edad,X.sexo
from paciente_externo X
where (x.nro=:nro_ambulatorio)
into :nombre_amb,:edad,:sexo;
end
if (tipo_pac='ASEGURADO') then
BEGIN
select R.ap_paterno||' '||coalesce(R.ap_materno,'')||' '||r.nombres,R.edad,R.sexo
from paciente_asegurado R,instituciones i
where ((r.nro_registro=:nro_asegurado)and(R.habilitado='T')and(r.institucion=i.nro))
into :nombre_amb,:edad,:sexo;
END
if (TIPO_PAC='INTERNADO') then
BEGIN
select p.ap_paterno||' '||coalesce(p.ap_materno,'')||' '||p.nombre,p.edad,p.sexo
from paciente p,registro_internacion n
where ((n.nro=:nro_internado)and(n.nro_historia=p.nro))
into :nombre_amb,:edad,:sexo;
END
tipo_servicio='ECOGRAFIA';
suspend;
end
for
select r.nro_recibo,cast(r.fecha as date),a.nombre_a, case r.porcentaje_cobro when 100 then e.costo else (r.porcentaje_cobro*e.costo)/100 end,r.costo_total,r.literal,r.nro_ambulatorio,r.usuario,r.tipo_paciente,r.nro_asegurado,r.nro_intern acion,r.factura,cast(r.fecha as time),r.monto_cobrar,r.porcentaje_cobro,e.nro,r.nro_factura
from recibo r,registro_examenes_lab E,analisis_clinico A
where ((E.nro_recibo=r.nro_recibo)and(e.examen=a.nombre_a)and(cast(r.fecha as date) between :f1 and :f2)and((r.cancelado=:valor)or(r.cancelado='M')))
into :nro_recibo,:fecha,:servicio,:costo,:costo_total,:literal,:nro_ambulatorio,:usuario,:tipo_pac,:nro_a segurado,:nro_internado,:factura,:hora,:monto_cobrar,orcentaje,:nro_registro,:nro_factura
DO
begin
if (factura='F') then
factura='RECIBO';
ELSE
FACTURA='FACTURA';
if (tipo_pac='AMBULATORIO') then
BEGIN
select X.ap_paterno||' '||coalesce(X.ap_materno,'')||' '||X.nombreS,X.edad,X.sexo
from paciente_externo X
where (x.nro=:nro_ambulatorio)
into :nombre_amb,:edad,:sexo;
end
if (tipo_pac='ASEGURADO') then
BEGIN
select R.ap_paterno||' '||coalesce(R.ap_materno,'')||' '||r.nombres,R.edad,R.sexo
from paciente_asegurado R,instituciones i
where ((r.nro_registro=:nro_asegurado)and(R.habilitado='T')and(r.institucion=i.nro))
into :nombre_amb,:edad,:sexo;
END
if (TIPO_PAC='INTERNADO') then
BEGIN
select p.ap_paterno||' '||coalesce(p.ap_materno,'')||' '||p.nombre,p.edad,p.sexo
from paciente p,registro_internacion n
where ((n.nro=:nro_internado)and(n.nro_historia=p.nro))
into :nombre_amb,:edad,:sexo;
END
tipo_servicio='LABORATORIO';
suspend;
end
for
select r.nro_recibo,cast(r.fecha as date),g.nombre, case r.porcentaje_cobro when 100 then x.costo else (r.porcentaje_cobro*x.costo)/100 end,r.costo_total,r.literal,r.nro_ambulatorio,r.usuario,r.tipo_paciente,r.nro_asegurado,r.nro_intern acion,r.factura,cast(r.fecha as time),r.monto_cobrar,r.porcentaje_cobro,x.nro,r.nro_factura
from recibo r,registro_radiologia X,estudio_radiografia G
where ((x.nro_recibo=r.nro_recibo)and(g.nro_estudio=x.nro_estudio)and(cast(r.fecha as date) between :f1 and :f2)and((r.cancelado=:valor)or(r.cancelado='M')))
into :nro_recibo,:fecha,:servicio,:costo,:costo_total,:literal,:nro_ambulatorio,:usuario,:tipo_pac,:nro_a segurado,:nro_internado,:factura,:hora,:monto_cobrar,orcentaje,:nro_registro,:nro_factura
DO
begin
if (factura='F') then
factura='RECIBO';
ELSE
FACTURA='FACTURA';
if (tipo_pac='AMBULATORIO') then
BEGIN
select X.ap_paterno||' '||coalesce(X.ap_materno,'')||' '||X.nombreS,X.edad,X.sexo
from paciente_externo X
where (x.nro=:nro_ambulatorio)
into :nombre_amb,:edad,:sexo;
end
if (tipo_pac='ASEGURADO') then
BEGIN
select R.ap_paterno||' '||coalesce(R.ap_materno,'')||' '||r.nombres,R.edad,R.sexo
from paciente_asegurado R,instituciones i
where ((r.nro_registro=:nro_asegurado)and(R.habilitado='T')and(r.institucion=i.nro))
into :nombre_amb,:edad,:sexo;
END
if (TIPO_PAC='INTERNADO') then
BEGIN
select p.ap_paterno||' '||coalesce(p.ap_materno,'')||' '||p.nombre,p.edad,p.sexo
from paciente p,registro_internacion n
where ((n.nro=:nro_internado)and(n.nro_historia=p.nro))
into :nombre_amb,:edad,:sexo;
END
tipo_servicio='RAYOS X';
suspend;
end
for
select r.nro_recibo,cast(r.fecha as date),v.cantidad||'==>'||m.nombre_producto||'==>'||p.nombre, case r.porcentaje_cobro when 100 then v.costo else (r.porcentaje_cobro*v.costo)/100 end,r.costo_total,r.literal,r.nro_ambulatorio,r.usuario,r.tipo_paciente,r.nro_asegurado,r.nro_intern acion,r.factura,cast(r.fecha as time),r.monto_cobrar,r.porcentaje_cobro,v.nro,r.nro_factura
from recibo r,venta_med v,medicamento m,presentacion_med p
where ((v.nro_recibo=r.nro_recibo)and(m.id_producto=v.id_medicamento)and(m.id_presentacion=p.id_presentaci on)and(cast(r.fecha as date) between :f1 and :f2)and((r.cancelado=:valor)or(r.cancelado='M')))
into :nro_recibo,:fecha,:servicio,:costo,:costo_total,:literal,:nro_ambulatorio,:usuario,:tipo_pac,:nro_a segurado,:nro_internado,:factura,:hora,:monto_cobrar,orcentaje,:nro_registro,:nro_factura
DO
begin
if (valor='F') then
begin
select distinct v.usuario
from venta_med v
where (v.nro_recibo=:nro_recibo)
into :usuario;
end
if (factura='F') then
factura='RECIBO';
ELSE
FACTURA='FACTURA';
if (tipo_pac='AMBULATORIO') then
BEGIN
select X.ap_paterno||' '||coalesce(X.ap_materno,'')||' '||X.nombreS,X.edad,X.sexo
from paciente_externo X
where (x.nro=:nro_ambulatorio)
into :nombre_amb,:edad,:sexo;
end
if (tipo_pac='ASEGURADO') then
BEGIN
select R.ap_paterno||' '||coalesce(R.ap_materno,'')||' '||r.nombres,R.edad,R.sexo
from paciente_asegurado R,instituciones i
where ((r.nro_registro=:nro_asegurado)and(R.habilitado='T')and(r.institucion=i.nro))
into :nombre_amb,:edad,:sexo;
END
if (TIPO_PAC='INTERNADO') then
BEGIN
select p.ap_paterno||' '||coalesce(p.ap_materno,'')||' '||p.nombre,p.edad,p.sexo
from paciente p,registro_internacion n
where ((n.nro=:nro_internado)and(n.nro_historia=p.nro))
into :nombre_amb,:edad,:sexo;
END
tipo_servicio='FARMACIA';
suspend;
end
for
select r.nro_recibo,cast(r.fecha as date),o.nombre, case r.porcentaje_cobro when 100 then s.costo else (r.porcentaje_cobro*s.costo)/100 end,r.costo_total,r.literal,r.nro_ambulatorio,r.usuario,r.tipo_paciente,r.nro_asegurado,r.nro_intern acion,r.factura,cast(r.fecha as time),r.monto_cobrar,r.porcentaje_cobro,s.nro,r.nro_factura
from recibo r,registro_otros_servicios s,otros_servicios o
where ((s.nro_recibo=r.nro_recibo)and(s.nro_servicio=o.numero)and(cast(r.fecha as date) between :f1 and :f2)and((r.cancelado=:valor)or(r.cancelado='M')))
into :nro_recibo,:fecha,:servicio,:costo,:costo_total,:literal,:nro_ambulatorio,:usuario,:tipo_pac,:nro_a segurado,:nro_internado,:factura,:hora,:monto_cobrar,orcentaje,:nro_registro,:nro_factura
DO
begin
if (factura='F') then
factura='RECIBO';
ELSE
FACTURA='FACTURA';
if (tipo_pac='AMBULATORIO') then
BEGIN
select X.ap_paterno||' '||coalesce(X.ap_materno,'')||' '||X.nombreS,X.edad,X.sexo
from paciente_externo X
where (x.nro=:nro_ambulatorio)
into :nombre_amb,:edad,:sexo;
end
if (tipo_pac='ASEGURADO') then
BEGIN
select R.ap_paterno||' '||coalesce(R.ap_materno,'')||' '||r.nombres,R.edad,R.sexo
from paciente_asegurado R,instituciones i
where ((r.nro_registro=:nro_asegurado)and(R.habilitado='T')and(r.institucion=i.nro))
into :nombre_amb,:edad,:sexo;
END
if (TIPO_PAC='INTERNADO') then
BEGIN
select p.ap_paterno||' '||coalesce(p.ap_materno,'')||' '||p.nombre,p.edad,p.sexo
from paciente p,registro_internacion n
where ((n.nro=:nro_internado)and(n.nro_historia=p.nro))
into :nombre_amb,:edad,:sexo;
END
tipo_servicio='OTROS SERVICIOS';
suspend;
end
end
^
SET TERM ; ^
este procedimiento hace un listado con todos los ingresos que se tiene en la seccion caja por diferentes servicios
luego tengo otro procedimiento que genera los totales por cada servicio en funcion a las fechas y que llama al procedimiento anterior, el SP es el siguiente:
Código SQL
[-]
begin
for
select distinct (l.tipo)
from listado_servicios l
where tipo<>'INTERNACION'
into :tipo_servicio
do
begin
for
select distinct m.usuario
from listado_registro_servicios_amb (:f1, :f2, 'T') m
where (m.tipo_servicio=:tipo_servicio)
into :usuario
do
begin
select sum(m.costo)
from listado_registro_servicios_amb (:f1,:f2,'T') m
where ((M.usuario=:USUARIO)AND(m.factura='FACTURA')and(m.tipo_servicio=:tipo_servicio))
into :monto_factura;
select coalesce(sum(case when m.costo is null then 0 else m.costo end),0) as monto_recibo
from listado_registro_servicios_amb (:f1,:f2,'T') m
where ((M.usuario=:USUARIO)AND(m.factura='RECIBO')and(m.tipo_servicio=:tipo_servicio))
into :monto_recibo;
select m.tipo_servicio,sum(m.costo)
from listado_registro_servicios_amb (:f1,:f2,'T') m
where ((m.tipo_servicio=:tipo_servicio)AND(M.usuario=:USUARIO))
group by m.tipo_servicio
into :tipo_servicio,:total;
suspend;
end
end
end
pero cuando ejecuto el segundo procedimiento con rango de fechas de 5 dias me tarda como 2,5 minutos.
He visto en el foro el tratamiento de indices, comentarles que las llaves primarias de las tablas tienen ya creado sus indices y aun eso tarda.
Por lo que e visto en el foro creo q esta parte seria la causante:
Código SQL
[-]
select coalesce(sum(case when m.costo is null then 0 else m.costo end),0) as monto_recibo
from listado_registro_servicios_amb (:f1,:f2,'T') m
where ((M.usuario=:USUARIO)AND(m.factura='RECIBO')and(m.tipo_servicio=:tipo_servicio))
into :monto_recibo;
Les pido porfavor sugerencias pues mi cliente me tiene ya loco porq tarda mucho en mostrar los datos el reporte asociado al SP
Trabajo con delphi y firebird 2.1
Agradesco cualquier sugerencia
COnsulta todos los campos a consultas en la sentencia where tienen que tener su indice creado????
Estare agradecido por la colaboracion de los amigos del foro