Query with SP to locate 100000 records from one table to another in postgres

0

I have a query, I have a problem where I have a table package and another bins, where package has 100000 (the structure is described below) in this table there is a field called wheitgh which has an int random value from 0 to a maximum of 100 and in the other table bins is a container so I have to accommodate all the packages of different sizes in bins containers, with the premise that it is the smallest amount of containers, the following code works for me up to 1000 packages without problem, but when I increase the number the query does not finish but to process, and I have no idea what can be! Greetings!

/ CREATE TABLE packages (ID int Primary Key, Weight int NOT NULL, BinNo int);   CREATE TABLE Bins (BinNo int Primary Key, SpaceLeft int); /

CREATE OR REPLACE FUNCTION poblate_tables ()   RETURNS integer AS $ BODY $ declare - _i integer: = 0;

_packageQuantity    integer := 0;
_packageMaxQuantity     integer := 10000;
_binsQuantity       integer := 0;
_binsMaxQuantity    integer := 20000;

_maxPackageWeight   integer := 0;

begin

LOOP
    _packageQuantity = _packageQuantity + 1;
    INSERT INTO Packages(ID, Weight) VALUES (_packageQuantity, random());


    IF _packageQuantity = _packageMaxQuantity THEN
    EXIT;  -- exit loop
    END IF;
END LOOP;


SELECT MAX(Weight) into _maxPackageWeight FROM Packages;


WHILE _binsQuantity < _binsMaxQuantity
LOOP
    _binsQuantity = _binsQuantity + 1;
    INSERT INTO Bins(BinNo, SpaceLeft) VALUES (_binsQuantity, random()+_maxPackageWeight);

END LOOP;

return 1;

end; $ BODY $   LANGUAGE 'plpgsql' VOLATILE;

CREATE OR REPLACE FUNCTION locate_package ()   RETURNS integer AS $ BODY $

DECLARE

_binId  integer;
_binSpace integer;
_packageID integer;
_packageWeight integer;
_rs record;

BEGIN        for _rs in         SELECT ID, Weight         FROM Packages WHERE BinNo is null         ORDER BY Weight DESC             / Runs all packages that do not have an assigned container             // Order first those that have the most weight because it is easier to find a container when they are less busy             // As you go around you assign a container to each one, if you find             // I assume that the space of the container is related to the weight and not to the unit of the package. For example, a container with SpaceLeft = 200 can save two packages of 100kg /         LOOP

        _packageID = _rs.ID;                -- id del paquete que quiero ubicar
        _packageWeight = _rs.Weight;        -- peso del paquete que quiero ubicar

        --Obtiene un Contenedor de aquellos contenedores que ya contienen paquetes para evitar usar uno nuevo
        SELECT bi.BinNo, bi.SpaceLeft
            into _binId, _binSpace
        FROM Bins bi
        JOIN Packages pk ON bi.BinNo = pk.BinNo
        WHERE SpaceLeft >= _packageWeight
        GROUP BY bi.BinNo, bi.SpaceLeft
        ORDER BY SpaceLeft DESC
        LIMIT 1;

        if _binId is null   --Si no encontro contenedor en la consulta anterior busca uno nuevo
        THEN

            SELECT bi.BinNo, bi.SpaceLeft
            into _binId, _binSpace
            FROM Bins bi
            WHERE SpaceLeft >= _packageWeight
            ORDER BY SpaceLeft DESC
            LIMIT 1;

        END IF;

        if _binId is not null
        THEN
            --actualizo el paquete para asignar el id de contenedor encontrado
            UPDATE Packages SET BinNo = _binId WHERE ID = _packageID;
            --actualizo el espacio disponible del contenedor restando lo ocupado por el nuevo paquete
            UPDATE Bins SET SpaceLeft = _binSpace - _packageWeight WHERE BinNo = _binId;             
        END IF;
    END LOOP;

RETURN 1; end; $ BODY $   LANGUAGE 'plpgsql' VOLATILE;

select poblate_tables ();  select locate_package (); - SELECT * FROM packages; - SELECT * FROM bins;

    
asked by Lucas Pasteris 13.10.2018 в 08:48
source

0 answers