Извършването на актуализации ред по ред в цикъл е почти винаги лоша идея и ще бъде изключително бавен и няма да мащабира. Наистина трябва да намерите начин да избегнете това.
След като каза това:
Всичко, което вашата функция прави, е да промени стойността на стойността на колоната в паметта - вие просто променяте съдържанието на променлива. Ако искате да актуализирате данните, имате нужда от update
изявление:
Трябва да използвате UPDATE
вътре в цикъла:
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;
Имайте предвид, че имате за да добавите where
условие на първичния ключ за update
в противен случай бихте актуализирали всички редове за всеки итерация на цикъла.
A леко по-ефективното решение е да използвате курсор и след това да извършите актуализацията с 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;
Не. Извикването на функцията се изпълнява в контекста на извикващата транзакция. Така че трябва да commit
след изпълнение на SELECT LoopThroughTable()
ако сте деактивирали автоматичното ангажиране във вашия SQL клиент.
Имайте предвид, че името на езика е идентификатор, не използвайте единични кавички около него. Трябва също да избягвате използването на ключови думи като row
като имена на променливи.
Използване на котиране на долари (както направих аз) също улеснява писането на тялото на функцията