sql >> Database >  >> RDS >> PostgreSQL

Doorloop de tabel, voer een berekening uit op elke rij

Updates rij voor rij in een lus uitvoeren is bijna altijd een slecht idee en zal extreem traag zijn en niet schalen. Je zou echt een manier moeten vinden om dat te vermijden.

Na dat gezegd te hebben:

Het enige dat uw functie doet, is de waarde van de kolomwaarde in het geheugen wijzigen - u wijzigt alleen de inhoud van een variabele. Als u de gegevens wilt bijwerken, heeft u een update nodig verklaring:

U moet een UPDATE . gebruiken in de lus:

CREATE OR REPLACE FUNCTION LoopThroughTable() 
  RETURNS VOID 
AS
$$
DECLARE 
   t_row the_table%rowtype;
BEGIN
    FOR t_row in SELECT * FROM the_table LOOP
        update the_table
            set resid = 1.0
        where pk_column = t_row.pk_column; --<<< !!! important !!!
    END LOOP;
END;
$$ 
LANGUAGE plpgsql;

Merk op dat je hebt om een ​​where toe te voegen voorwaarde op de primaire sleutel voor de update verklaring anders zou je alles updaten rijen voor elk iteratie van de lus.

Een enigszins een efficiëntere oplossing is om een ​​cursor te gebruiken en vervolgens de update uit te voeren met where current of

CREATE OR REPLACE FUNCTION LoopThroughTable() 
  RETURNS VOID 
AS $$
DECLARE 
   t_curs cursor for 
      select * from the_table;
   t_row the_table%rowtype;
BEGIN
    FOR t_row in t_curs LOOP
        update the_table
            set resid = 1.0
        where current of t_curs;
    END LOOP;
END;
$$ 
LANGUAGE plpgsql;

Nee. De aanroep van de functie wordt uitgevoerd in de context van de aanroepende transactie. U moet dus commit na het uitvoeren van SELECT LoopThroughTable() als je automatische vastlegging in je SQL-client hebt uitgeschakeld.

Merk op dat de taalnaam een ​​identifier is, gebruik er geen enkele aanhalingstekens omheen. Vermijd ook het gebruik van zoekwoorden zoals row als variabelenamen.

Met behulp van dollarcitaat (zoals ik deed) maakt het schrijven van de functietekst ook gemakkelijker



  1. Hoe de bewerkingsgeschiedenis van een groot tekenreeksveld in een relationele database te behouden?

  2. mysql-query om alles te selecteren behalve

  3. Converteer datum naar milliseconden in MySQL

  4. Hoe records met bepaalde waarden in sql select uit te sluiten