PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Scorri la tabella, esegui calcoli su ogni riga

Fare gli aggiornamenti riga per riga in un ciclo è quasi sempre una cattiva idea e lo farà essere estremamente lento e non scalare. Dovresti davvero trovare un modo per evitarlo.

Dopo aver detto che:

Tutto ciò che la tua funzione sta facendo è modificare il valore del valore della colonna in memoria:stai solo modificando il contenuto di una variabile. Se vuoi aggiornare i dati hai bisogno di un update dichiarazione:

Devi usare un UPDATE all'interno del ciclo:

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;

Tieni presente che hai per aggiungere un where condizione sulla chiave primaria per l'update dichiarazione altrimenti aggiorneresti tutto righe per ciascuno iterazione del ciclo.

Un leggermente una soluzione più efficiente consiste nell'usare un cursore, quindi eseguire l'aggiornamento utilizzando 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;

No. La chiamata alla funzione viene eseguita nel contesto della transazione chiamante. Quindi devi commit dopo aver eseguito SELECT LoopThroughTable() se hai disabilitato il commit automatico nel tuo client SQL.

Nota che il nome della lingua è un identificatore, non utilizzare virgolette singole attorno ad esso. Dovresti anche evitare di utilizzare parole chiave come row come nomi di variabili.

Utilizzo di citazione del dollaro (come ho fatto io) semplifica anche la scrittura del corpo della funzione