【发布时间】:2020-04-17 16:14:04
【问题描述】:
我正在规范化 old_users_data 表中的地址,以将它们拆分为单独的 location 和 city 表。为此,我制作了一个循环遍历旧用户行并根据需要创建位置和城市记录的函数。 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();
但我得到了错误:
ERROR: query has no destination for result data
CONTEXT: PL/pgSQL function test_func() line 9 at SQL statement
尽管有返回语句。
这是我的数据: old_users_data 表
+----+--------+---------------------------+----------+
| id | name | address | city |
+----+--------+---------------------------+----------+
| 1 | sam | 228 Park Ave S | New York |
| 2 | rachel | 8474 Augusta St. Brooklyn | New York |
+----+--------+---------------------------+----------+
用户表
+----+--------+-------------+
| id | name | location_id |
+----+--------+-------------+
| 1 | sam | 1 |
| 2 | rachel | 2 |
+----+--------+-------------+
位置表格
+----+---------------------------+---------+
| id | address | city_id |
+----+---------------------------+---------+
| 1 | 228 Park Ave S | 1 |
| 2 | 8474 Augusta St. Brooklyn | 1 |
+----+---------------------------+---------+
城市表格
+----+----------+
| id | name |
+----+----------+
| 1 | New York |
+----+----------+
【问题讨论】:
-
从 CTE 的最后一个 INSERT 中删除
RETURNING id;。 -
最后我已经有了
return true。我删除了RETURNING id;并解决了错误。但是,只有一个用户被插入,而不是另一个。 dbfiddle.uk/… -
在新用户表中,每个唯一城市仅插入一行。 dbfiddle.uk/…
-
您不需要循环或 PL/pgSQL:dbfiddle.uk/…
-
@a_horse_with_no_name 这是在城市表中复制城市。我认为这是因为
where not exists(select * from city where city.name = oud.city)仅在开始时运行,当时城市表为空。所以New York被插入了两次。
标签: sql postgresql plpgsql