Gracias por tu respuesta Álvaro.

 

Por ejemplo, quiere realizar un procedimiento con esta consulta SQL que te
adjunto en el email:

 

SELECT forma_pago.descripcion as forma_pago,clientes.nombre, clientes.cif,
('INT'::character varying::text) || contratos.clave::text AS contrato,

  sum(round("numeric"(detalle_contratos.cantidad *
(detalle_contratos.precio_unidad - detalle_contratos.precio_unidad *
detalle_contratos.porc_descuento / 100::double precision)), 2)) AS
inporte_sin_iva

  FROM contratos, detalle_contratos, productos, clientes, forma_pago,
tipo_cobro

  WHERE contratos.clave = detalle_contratos.c_contrato 

         AND contratos.b_baja = false 

         AND contratos.b_cerrado = true 

         AND contratos.b_baja_solicitada = false 

         AND contratos.c_cliente = clientes.clave   

         AND contratos.c_forma_pago = forma_pago.clave

         AND detalle_contratos.b_baja = false 

         AND productos.clave = detalle_contratos.producto 

         AND productos.gratis = false

         AND productos.tipo_cobro = tipo_cobro.clave

         AND ((detalle_contratos.fecha_primera_factura IS NOT NULL) AND
(detalle_contratos.fecha_primera_factura >= '01/6/2011' AND
detalle_contratos.fecha_primera_factura < '01/06/2011') OR
(detalle_contratos.fecha_primera_factura < '01/5/2011' AND
productos.tipo_cobro = 2) OR (detalle_contratos.fecha_primera_factura <
'01/6/2011' AND productos.tipo_cobro = 3 AND
date_part('month',detalle_contratos.fecha_primera_factura)='5'))

         GROUP BY forma_pago.clave,
forma_pago.descripcion,clientes.nombre,clientes.cif,contratos.clave

ORDER BY forma_pago.clave, forma_pago.descripcion,clientes.nombre

 

El procedimiento debe devolver todos los registros.

 

¿Cómo se debe construir la función SQL/PL?

 

Para ir probando (es un ejemplo, este procedimiento es incompleto y poco
funcional) he creado esta función SQL/PL:

 

CREATE FUNCTION test(text, text, text, integer, integer) RETURNS text AS '

DECLARE

 

-- Declare aliases.

 

primeroMes ALIAS FOR $1  -- 01/05/2011

finalMes ALIAS FOR $2  -- 01/06/2011

mes ALIAS FOR $3 -- 5

cobroMensual ALIAS FOR $4 -- 2

cobroAnual ALIAS FOR $5 -- 3

 

 

-- Declare variables to hold the customer name.

 

f_forma_pago text;

f_cliente text;

f_cif text;

f_contrato text;

f_importe float;

 

 

BEGIN

  SELECT SELECT INTO f_forma_pago, f_cliente, f_cif, f_contrato, f_importe

  forma_pago.descripcion as forma_pago,clientes.nombre, clientes.cif,
(''INT''::character varying::text) || contratos.clave::text AS contrato,

  sum(round("numeric"(detalle_contratos.cantidad *
(detalle_contratos.precio_unidad - detalle_contratos.precio_unidad *
detalle_contratos.porc_descuento / 100::double precision)), 2)) AS
inporte_sin_iva

  FROM contratos, detalle_contratos, productos, clientes, forma_pago,
tipo_cobro

  WHERE contratos.clave = detalle_contratos.c_contrato 

         AND contratos.b_baja = false 

         AND contratos.b_cerrado = true 

         AND contratos.b_baja_solicitada = false 

         AND contratos.c_cliente = clientes.clave   

         AND contratos.c_forma_pago = forma_pago.clave

         AND detalle_contratos.b_baja = false 

         AND productos.clave = detalle_contratos.producto 

         AND productos.gratis = false

         AND productos.tipo_cobro = tipo_cobro.clave

         AND ((detalle_contratos.fecha_primera_factura IS NOT NULL) AND
(detalle_contratos.fecha_primera_factura >= finalMes AND
detalle_contratos.fecha_primera_factura < finalMes) OR
(detalle_contratos.fecha_primera_factura < primeroMes AND
productos.tipo_cobro = cobroMensual) OR
(detalle_contratos.fecha_primera_factura < finalMes AND productos.tipo_cobro
= cobroAnual AND
date_part(''month'',detalle_contratos.fecha_primera_factura)= mes))

         GROUP BY forma_pago.clave,
forma_pago.descripcion,clientes.nombre,clientes.cif,contratos.clave

         ORDER BY forma_pago.descripcion,clientes.nombre

 

 

-- Return the name.

 

RETURN f_forma_pago || '':'' || f_cliente || '':'' || f_cif || '':'' ||
f_contrato || '':'' || f_importe;

 

END

' LANGUAGE 'plpgsql';

 

 

Errores no solucionados:

 
ERROR:  syntax error en o cerca de "finalMes"
CONTEXT:  compile of PL/pgSQL function "test" near line 6

select test('01/05/2011', '01/06/2011', '5', 2, 3) 

En el caso que funcione todo correctamente, como deficiencia de la función
solo retorna el último registro…..es la primera que construyo, todo será
cuestión de ir mejorándola….

 

Desde ya, Gracias por todo.

Saludos.

 

 

-----Mensaje original-----
De: pgsql-es-ayuda-ow...@postgresql.org
[mailto:pgsql-es-ayuda-ow...@postgresql.org] En nombre de Alvaro Herrera
Enviado el: martes, 12 de abril de 2011 2:48
Para: Sergio Villalba Moreno
CC: pgsql-es-ayuda
Asunto: Re: [pgsql-es-ayuda] Función SQL/PL en versión 7.4

 

Excerpts from Sergio Villalba Moreno's message of mar abr 05 13:28:30 -0300
2011:

 

> Estoy intentando realizar un procedimiento almacenado con una consulta
algo

> compleja…

> 

>  

> 

> La consulta es esta:

> 

> SELECT sum(round("numeric"(float8(detalle_facturas.cantidad) *

> (detalle_facturas.precio_unidad - detalle_facturas.precio_unidad *

> detalle_facturas.porc_descuento / 100::double precision) *

> (detalle_facturas.porc_comision / 100::double precision)), 2)) AS total
FROM

> facturas, contratos, detalle_facturas, agentes WHERE facturas.c_contrato =

> contratos.clave AND facturas.clave = detalle_facturas.c_factura AND

> contratos.c_agente = agentes.clave AND contratos.b_baja = false AND

> contratos.clave=1928

 

Honestamente no veo en qué sentido esta consulta es compleja ni por qué

se dificultaría la creación de un procedimiento almacenado con ella.

 

Lo único que veo complejo es la posible pérdida de precisión y error

aritmético introducido por el uso de aritmética de punto flotante.  ¿No

sería más sano convertir todo a numeric desde el principio?  Es más,

¿por qué las columnas no son numeric?

 

> Como no consigo realizar la consulta en el procedimiento almacenado, he

> pensado en esta alternativa, aunque no funciona correctamente.

 

¿Podrías por favor explicar qué problema tuviste creando el

procedimiento almacenado?  ¿Arrojó algún mensaje de error?  Si es así,

¿cuál?

 

-- 

Álvaro Herrera <alvhe...@alvh.no-ip.org>

-

Enviado a la lista de correo pgsql-es-ayuda (pgsql-es-ayuda@postgresql.org)

Para cambiar tu suscripcin:

http://www.postgresql.org/mailpref/pgsql-es-ayuda

Responder a