我为postgresql编写强大的upsert函数有很多帮助。我试图将值插入到具有3列的表中,两个是外键,一个是文本。
我有一个非常相似的功能,效果很好,它只是没有像这样的子查询。我收到了错误
"ERROR: syntax error at or near "WHERE"
LINE 24: WHERE NOT EXISTS (SELECT 1 FROM sel)"
功能:
create or replace function upsert_dish_cluster_to_network(n_id INT, c_id INT, amsover TEXT)
RETURNS SETOF dish_cluster_to_network AS
$func$
BEGIN
LOOP
BEGIN
RETURN QUERY
WITH sel AS (
SELECT dctn.id
FROM dish_cluster_to_network dctn
WHERE dctn.network_id = (SELECT id FROM unv_network WHERE amscode = n_id)
AND dctn.cluster_id = (SELECT id FROM dish_cluster_network WHERE axsyscode = c_id)
FOR SHARE
),
ins AS (
INSERT INTO dish_cluster_to_network (network_id, cluster_id, amsname_override)
VALUES (
(SELECT id FROM unv_network WHERE amscode = n_id),
(SELECT id from dish_cluster_network WHERE axsyscode = c_id),
amsover
)
WHERE NOT EXISTS (SELECT 1 FROM sel)
RETURNING *
),
upd AS (
UPDATE dish_cluster_to_network dctn
SET network_id = (SELECT id from unv_network WHERE amscode = n_id),
cluster_id = (SELECT id from dish_cluster_network WHERE axsyscode = c_id),
amsname_override = amsover
FROM sel
WHERE sel.id = dctn.id
AND ( dctn.network_id IS DISTINCT FROM (SELECT id FROM unv_network WHERE amscode = n_id)
OR dctn.cluster_id IS DISTINCT FROM (SELECT id FROM dish_cluster_network WHERE axsyscode = c_id)
)
RETURNING dctn.*
)
SELECT * FROM ins
UNION ALL
SELECT * FROM upd;
RETURN;
EXCEPTION WHEN UNIQUE_VIOLATION THEN
RAISE NOTICE 'Something Bad Happened';
END;
END LOOP;
END
$func$ LANGUAGE plpgsql;
我无法弄清楚为什么我不能拥有WHERE NOT EXISTS行。如果我注释掉该行,该函数总是插入新条目并且永远不会更新。
答案 0 :(得分:1)
insert命令没有where
子句。因此,将values
替换为select
ins AS (
INSERT INTO dish_cluster_to_network (
network_id, cluster_id, amsname_override
)
select
(SELECT id FROM unv_network WHERE amscode = n_id),
(SELECT id from dish_cluster_network WHERE axsyscode = c_id),
amsover
WHERE NOT EXISTS (SELECT 1 FROM sel)
RETURNING *
),