如何在创建 FOR 循环的 POSTGRESQL 中创建存储过程?
How to create a stored procedure in POSTGRESQL that makes a FOR loop?
我正在研究如何在 POSTGRESQL 中创建触发器和存储过程,我的任务是更新 table ALBUM 中名为 num_long_title_songs 的列。
需要统计table首歌曲中超过12个字符的歌曲数量,然后更新ALBUM中列的值。
我已经用 for 循环创建了下一个查询,这正是我想要的:
do $$
begin
FOR i IN 1..100 LOOP
UPDATE ALBUM
SET num_long_title_songs =(SELECT count(s.title)
FROM ALBUM a,SONG s
WHERE a.id_album=s.id_album
AND LENGTH(s.title) > 12
AND a.id_album=i
GROUP BY a.id_album
ORDER BY a.id_album)
WHERE id_album IN (SELECT a.id_album
FROM ALBUM a,SONG s
WHERE a.id_album=s.id_album
AND LENGTH(s.title) > 12
AND a.id_album=i
GROUP BY a.id_album
ORDER BY a.id_album);
-- i will take on the values 1,2,3,4,5,6,7,8,9,10 within the loop
END LOOP;
END; $$
问题是我需要创建一个存储过程才能创建触发器。我尝试将其放入 CREATE FUNCTION 结构中,但我无法创建它...您能帮我了解如何将此 'for' 循环放入函数中吗?
如果要更新 table ALBUM 中的现有行,只需 运行 以下 UPDATE
语句:
UPDATE ALBUM a
SET num_long_title_songs = s.total
FROM ( SELECT s.id_album
, count(s.title) AS total
FROM SONG s
WHERE LENGTH(s.title) > 12
GROUP BY s.id_album
) AS s
WHERE a.id_album=s.id_album
AND a.num_long_title_songs <> s.total ;
如果要在tableALBUM
中插入或更新行时自动更新num_long_title_songs字段[=29] =] SONG
, 那么你需要一个 trigger function
:
CREATE OR REPLACE FUNCTION update_num_long_title_songs ()
RETURNS TRIGGER LANGUAGE plpgsql AS
$$
BEGIN
UPDATE ALBUM a
SET num_long_title_songs = s.total
FROM ( SELECT s.id_album
, count(s.title) AS total
FROM SONG s
WHERE LENGTH(s.title) > 12
AND s.id_album = NEW.id_album
) AS s
WHERE a.id_album=s.id_album
AND a.num_long_title_songs <> s.total ;
END ;
$$ ;
CREATE TRIGGER after_insert_update_SONG AFTER INSERT OR UPDATE OF title ON SONG
FOR EACH ROW EXECUTE FUNCTION update_num_long_title_songs () ;
AFTER 很重要,以便考虑在 table SONG
中插入或更新的新行作为 num_long_title_songs[=25 的新值=].
我正在研究如何在 POSTGRESQL 中创建触发器和存储过程,我的任务是更新 table ALBUM 中名为 num_long_title_songs 的列。
需要统计table首歌曲中超过12个字符的歌曲数量,然后更新ALBUM中列的值。
我已经用 for 循环创建了下一个查询,这正是我想要的:
do $$
begin
FOR i IN 1..100 LOOP
UPDATE ALBUM
SET num_long_title_songs =(SELECT count(s.title)
FROM ALBUM a,SONG s
WHERE a.id_album=s.id_album
AND LENGTH(s.title) > 12
AND a.id_album=i
GROUP BY a.id_album
ORDER BY a.id_album)
WHERE id_album IN (SELECT a.id_album
FROM ALBUM a,SONG s
WHERE a.id_album=s.id_album
AND LENGTH(s.title) > 12
AND a.id_album=i
GROUP BY a.id_album
ORDER BY a.id_album);
-- i will take on the values 1,2,3,4,5,6,7,8,9,10 within the loop
END LOOP;
END; $$
问题是我需要创建一个存储过程才能创建触发器。我尝试将其放入 CREATE FUNCTION 结构中,但我无法创建它...您能帮我了解如何将此 'for' 循环放入函数中吗?
如果要更新 table ALBUM 中的现有行,只需 运行 以下 UPDATE
语句:
UPDATE ALBUM a
SET num_long_title_songs = s.total
FROM ( SELECT s.id_album
, count(s.title) AS total
FROM SONG s
WHERE LENGTH(s.title) > 12
GROUP BY s.id_album
) AS s
WHERE a.id_album=s.id_album
AND a.num_long_title_songs <> s.total ;
如果要在tableALBUM
中插入或更新行时自动更新num_long_title_songs字段[=29] =] SONG
, 那么你需要一个 trigger function
:
CREATE OR REPLACE FUNCTION update_num_long_title_songs ()
RETURNS TRIGGER LANGUAGE plpgsql AS
$$
BEGIN
UPDATE ALBUM a
SET num_long_title_songs = s.total
FROM ( SELECT s.id_album
, count(s.title) AS total
FROM SONG s
WHERE LENGTH(s.title) > 12
AND s.id_album = NEW.id_album
) AS s
WHERE a.id_album=s.id_album
AND a.num_long_title_songs <> s.total ;
END ;
$$ ;
CREATE TRIGGER after_insert_update_SONG AFTER INSERT OR UPDATE OF title ON SONG
FOR EACH ROW EXECUTE FUNCTION update_num_long_title_songs () ;
AFTER 很重要,以便考虑在 table SONG
中插入或更新的新行作为 num_long_title_songs[=25 的新值=].