PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Iterar através da tabela, realizar cálculos em cada linha


Fazer atualizações linha por linha em um loop quase sempre é uma má ideia e será ser extremamente lento e não será dimensionado. Você deve realmente encontrar uma maneira de evitar isso.

Depois de ter dito isso:

Tudo o que sua função está fazendo é alterar o valor da coluna na memória - você está apenas modificando o conteúdo de uma variável. Se você deseja atualizar os dados, você precisa de uma update declaração:

Você precisa usar um UPDATE dentro do laço:
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;

Observe que você tem para adicionar um where condição na chave primária para a update caso contrário, você atualizaria todos linhas para cada iteração do laço.

Um ligeiramente solução mais eficiente é usar um cursor e, em seguida, fazer a atualização usando 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;

Não. A chamada para a função é executada no contexto da transação de chamada. Então você precisa commit depois de executar SELECT LoopThroughTable() se você desativou a confirmação automática em seu cliente SQL.

Observe que o nome do idioma é um identificador, não use aspas simples ao redor dele. Você também deve evitar usar palavras-chave como row como nomes de variáveis.

Usando cotação em dólar (como eu fiz) também facilita escrever o corpo da função