I am normalising addresses in my old_users_data table to split them into separate location and city tables. For this, I made a function that loops through old users rows and creates location and city records as required. Dbfiddle here
CREATE OR REPLACE FUNCTION test_func()
RETURNS BOOL AS
$$
DECLARE
temprow record;
BEGIN
FOR temprow IN
SELECT * FROM old_users_data oud
LOOP
with city as (
insert into city (name)
select temprow.city
where not exists(
select id from city where name = temprow.city
)
returning id),
locations AS (
INSERT INTO locations
(address, city)
select temprow.address, id from city
RETURNING id
)
INSERT INTO users (name, location)
SELECT temprow.name, id
FROM locations
RETURNING id;
raise notice 'Value: %, %', temprow.id, temprow.city;
END LOOP;
RETURN TRUE;
END;
$$
LANGUAGE plpgsql;
SELECT test_func();
But I am getting the error:
ERROR: query has no destination for result data
CONTEXT: PL/pgSQL function test_func() line 9 at SQL statement
despite having a return statement.
Here is my data: old_users_data table
+----+--------+---------------------------+----------+
| id | name | address | city |
+----+--------+---------------------------+----------+
| 1 | sam | 228 Park Ave S | New York |
| 2 | rachel | 8474 Augusta St. Brooklyn | New York |
+----+--------+---------------------------+----------+
users table
+----+--------+-------------+
| id | name | location_id |
+----+--------+-------------+
| 1 | sam | 1 |
| 2 | rachel | 2 |
+----+--------+-------------+
location table
+----+---------------------------+---------+
| id | address | city_id |
+----+---------------------------+---------+
| 1 | 228 Park Ave S | 1 |
| 2 | 8474 Augusta St. Brooklyn | 1 |
+----+---------------------------+---------+
city table
+----+----------+
| id | name |
+----+----------+
| 1 | New York |
+----+----------+
RETURNING id;from the last INSERT in your CTE.return trueat the end. I removed theRETURNING id;and the error resolved. However, only one user got inserted, not the other. dbfiddle.uk/…where not exists(select * from city where city.name = oud.city)is run only in the beginning, when city table is null. SoNew Yorkis inserted twice.