On Tue, May 3, 2022 at 5:40 AM Fernando Siguenza <fs...@hotmail.com> wrote:

> Amigos tengo una duda,
> En una funcion recibo algunos parametros para usarlos como filtros, algo
> asi
>
> CREATE OR REPLACE FUNCTION reporte_ventas_grupo(
> pgrupo_id varchar,
> pfinicio date,
> pffin date,
> OUT pproducto character varying,
> OUT ptotal numeric,
> OUT pcantidad integer)
>     RETURNS SETOF record
>     LANGUAGE 'plpgsql'
>     COST 100
>     VOLATILE PARALLEL UNSAFE
>     ROWS 1000
>     .......
>
> en el campo grupo id, viene los codigos seleccionados por el usuario de
> los grupos que desea ver en el reporte mas o menos viene un varchar de esta
> forma '1,4,6,8,12'
>
> entonces quiero generar un select como este
>
> select p.id,p.nombre,d.cantidad,d.precio
> from ventas v
> inner join ventasd d on v.id=d.venta_id
> inner join productos p on d.producto_id=p.id
> inner join grupos l on p.grupo_id=l.id
> where v.fecha>=pfinicio and v.fecha<=pffin
> and v.esactivo=1
> and case when pgrupo_id='' then true else p.grupo_id in (pgrupo_id) end
> order by p.nombre desc
>
>
> Claro el select es un poco mas complicado, la funcion completa esta asi
>
> CREATE OR REPLACE FUNCTION reporte_ventas_grupo(
> pgrupo_id varchar,
> pfinicio date,
> pffin date,
> OUT pproducto character varying,
> OUT ptotal numeric,
> OUT pcantidad integer)
>     RETURNS SETOF record
>     LANGUAGE 'plpgsql'
>     COST 100
>     VOLATILE PARALLEL UNSAFE
>     ROWS 1000
>
> AS $BODY$
> DECLARE
> rventas record;
> vtotal numeric;
> vcliente_id bigint;
> vvendedor_id bigint;
> BEGIN
>
> for rventas in
> select p.id,p.nombre,d.cantidad,d.precio
> from ventas v
> inner join ventasd d on v.id=d.venta_id
> inner join productos p on d.producto_id=p.id
> inner join grupos l on p.grupo_id=l.id
> where v.fecha>=pfinicio and v.fecha<=pffin
> and v.esactivo=1
> and case when pgrupo_id='' then true else p.grupo_id in (pgrupo_id) end
> order by p.nombre desc
> loop
> pproducto:=rventas.nombre;
> ptotal:=round(rventas.precio,2);
> pcantidad:=rventas.cantidad;
> return next;
> end loop;
> return;
> END;
> $BODY$;
>
>
> pero al ejecutar la funcion me da este error
>
> ERROR:  el operador no existe: integer = character varying LINE 8: ...
> case when pgrupo_id='' then true else p.grupo_id in (pgrupo...
>
> a la funcion la llamo asi
>
> select * from reporte_ventas_test('11,4,6,8,12','2021-01-01','2023-01-01')
>
> Como podria ejecutar el select con el parametro de grupo con varios
> codigos?
>

Si quieres que la lista sea un parámetro creo que lo más sencillo es
utilizar un ARRAY. El código lo incluyo como ejemplo, no lo he llegado a
probar:

CREATE

                OR REPLACE FUNCTION reporte_ventas_grupo (

                pgrupo_id INTEGER[]

                ,pfinicio DATE

                ,pffin DATE

                ,OUT pproducto CHARACTER VARYING

                ,OUT ptotal NUMERIC

                ,OUT pcantidad INTEGER

                )

RETURNS SETOF record    LANGUAGE 'plpgsql'     COST 100     VOLATILE
PARALLEL UNSAFE    ROWS 1000 AS

$BODY$

DECLARE

                rventas record;

                vtotal NUMERIC;

                vcliente_id BIGINT;

                vvendedor_id BIGINT;

BEGIN

                FOR rventas inselect p.id

                               ,p.nombre

                               ,d.cantidad

                               ,d.preciofrom ventas vinner

                JOIN ventasd d on v.id = d.venta_idinner

                JOIN productos p ON d.producto_id = p.idinner

                JOIN grupos l ON p.grupo_id = l.idwhere v.fecha >=
pfinicio and v.fecha <= pffinand v.esactivo = 1

                               AND CASE

                                               WHEN pgrupo_id = ''

                                                               THEN true

                                               ELSE p.grupo_id =
 ANY(pgrupo_id)

                                               END

                ORDER BY p.nombre

                               desclooppproducto: = rventas.nombre;

                               ptotal: = round(rventas.precio, 2);

                               pcantidad: = rventas.cantidad;

                               RETURN NEXT;

                END LOOP;

                RETURN;

END;
$BODY$;


Y para llamarlo:

select * from
reporte_ventas_test('{11,4,6,8,12}','2021-01-01','2023-01-01');


Un saludo,

Juan José Santamaría Flecha

Reply via email to