Reputation: 9479
I have the following loop (simplified for an example):
DO $$
DECLARE
l record;
BEGIN
FOR l IN SELECT id, country_id FROM logo LOOP
WITH cs AS (
INSERT INTO logo_settings (targeted) VALUES (true)
RETURNING id
)
INSERT INTO logo_settings_targeted (logo_settings_id, country_id)
VALUES
( (SELECT id FROM cs),
logo.country_id,
);
END LOOP;
END;
END $$;
The body of a loop works fine. But if I wrap it into a loop (I would like to make records for all records from logo table) - it shows an error saying:
ERROR: syntax error at or near "END"
Position: 712
END;
^
meaning the last EnND before END $$;
which does not give much sense to me. I do not know what to fix to make it running. Any hints?
Upvotes: 0
Views: 43
Reputation: 23726
Additionally to answer of @Andronicus, this is one possible way to do this without PL/pgsql:
WITH countries AS (
SELECT id, country_id,
row_number() OVER () -- 1
FROM logo
), ins_settings AS (
INSERT INTO logo_settings(targeted)
SELECT true FROM countries c
RETURNING id
)
INSERT INTO logo_settings_targeted (logo_settings_id, country_id)
SELECT
ins.id, c.country_id
FROM
(SELECT id, row_number() OVER () FROM ins_settings) ins -- 2
JOIN countries c ON c.row_number = ins.row_number
SELECT
query (which you used for the loop) into a second CTE at the top.logo
SELECT
statement and the first insert. You can use the fact, that both outputs have the same number of rows. Simply add a column with a row count to both outputs. This can be done, for example, using the row_number()
window function. As you can see, for the logo
SELECT
I already did this directly in the CTE (1), for the INSERT
output I added this in a subquery (2). Now there are the same identifiers on both tables, which can be used for the join.INSERT
.Upvotes: 1
Reputation: 26056
There is one end
to many. end loop
closes the loop body:
DO $$
DECLARE
l record;
BEGIN
FOR l IN SELECT id, country_id FROM logo LOOP
WITH cs AS (
INSERT INTO logo_settings (targeted) VALUES (true)
RETURNING id
)
INSERT INTO logo_settings_targeted (logo_settings_id, country_id)
VALUES
( (SELECT id FROM cs),
logo.country_id,
);
END LOOP;
END $$;
Upvotes: 2