Robienie aktualizacji wiersz po wierszu w pętli jest prawie zawsze złym pomysłem i będzie być bardzo powolny i nie będzie się skalować. Naprawdę powinieneś znaleźć sposób, aby tego uniknąć.
Po tym, jak powiedziałem, że:
Wszystko, co robi twoja funkcja, to zmiana wartości wartości kolumny w pamięci - po prostu modyfikujesz zawartość zmiennej. Jeśli chcesz zaktualizować dane, potrzebujesz update
oświadczenie:
Musisz użyć UPDATE
wewnątrz pętli:
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;
Pamiętaj, że masz aby dodać where
warunek na kluczu podstawowym do update
oświadczenie, w przeciwnym razie zaktualizowałbyś wszystkie wiersze dla każdego iteracja pętli.
nieco bardziej wydajnym rozwiązaniem jest użycie kursora, a następnie wykonanie aktualizacji za pomocą 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;
Nie. Wywołanie funkcji jest uruchamiane w kontekście transakcji wywołującej. Musisz więc commit
po uruchomieniu SELECT LoopThroughTable()
jeśli wyłączyłeś automatyczne zatwierdzanie w swoim kliencie SQL.
Zauważ, że nazwa języka jest identyfikatorem, nie używaj wokół niej pojedynczych cudzysłowów. Należy również unikać używania słów kluczowych, takich jak row
jako nazwy zmiennych.
Korzystanie z cytowania w dolarach (tak jak ja) ułatwia również pisanie treści funkcji