sql >> Base de Datos >  >> RDS >> PostgreSQL

Iterar a través de la tabla, realizar el cálculo en cada fila

Hacer actualizaciones fila por fila en un bucle casi siempre es una mala idea y lo hará. ser extremadamente lento y no escalará. Realmente deberías encontrar una manera de evitar eso.

Después de haber dicho eso:

Todo lo que hace su función es cambiar el valor de la columna en la memoria; solo está modificando el contenido de una variable. Si desea actualizar los datos, necesita una update declaración:

Necesitas usar un UPDATE dentro 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;

Tenga en cuenta que tiene para agregar un where condición en la clave principal para la update de lo contrario, actualizaría todas filas para cada iteración del ciclo.

Un ligeramente la solución más eficiente es usar un cursor y luego hacer la actualización 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;

No. La llamada a la función se ejecuta en el contexto de la transacción de llamada. Por lo tanto, debe commit después de ejecutar SELECT LoopThroughTable() si ha deshabilitado la confirmación automática en su cliente SQL.

Tenga en cuenta que el nombre del idioma es un identificador, no use comillas simples alrededor de él. También debe evitar el uso de palabras clave como row como nombres de variables.

Usando comillas en dólares (como hice yo) también hace que escribir el cuerpo de la función sea más fácil