我想创建一个items基于返回的函数tags。但是,我不知道如何在IN()子句中格式化数组。我相信这就是为什么我没有结果的原因。
items
tags
IN()
这是我得到的:
CREATE OR REPLACE FUNCTION getItemsByTag(tags text[]) RETURNS TABLE (id bigint, title text, tag text[]) AS $$ BEGIN IF array_length(tags, 1) > 0 THEN EXECUTE format(' SELECT d.id, d.title, array_agg(t.title) FROM items d INNER JOIN item_tags dt ON dt.item_id = d.id INNER JOIN tags t ON t.id = dt.tag_id AND t.title IN (%L) GROUP BY d.id, d.title ', array_to_string(tags, ',')); -- ELSE ... END IF; END; $$ LANGUAGE plpgsql;
然后,当我打电话给:
select getItemsByTag('{"gaming", "sport"}');
即使有标有“游戏”的项目,我也没有得到结果。
CREATE TABLE items( id serial primary key, title text); CREATE TABLE tags( id serial primary key, title text); CREATE TABLE item_tags( item_id int references items(id), tag_id int references tags(id), primary key(item_id, tag_id)); insert into items (title) values ('my title 1'), ('my title 2'); insert into tags (title) values ('tag1'), ('tag2'); insert into item_tags (item_id, tag_id) values (1,1), (1, 2);
功能:
称呼:
select getItemsByTag('{"tag1", "tag2"}');
您实际上 并 没有 返回 结果。您将为此使用RETURN QUERY EXECUTE。
RETURN QUERY EXECUTE
但是您不需要在这里以动态SQL开头…
CREATE OR REPLACE FUNCTION get_items_by_tag(VARIADIC tags text[]) RETURNS TABLE (id int, title text, tag text[]) AS $func$ BEGIN IF array_length(tags, 1) > 0 THEN -- NO need for EXECUTE RETURN QUERY SELECT d.id, d.title, array_agg(t.title) FROM items d JOIN item_tags dt ON dt.item_id = d.id JOIN tags t ON t.id = dt.tag_id AND t.title = ANY ($1) -- use ANY construct GROUP BY d.id; -- PK covers whole table -- array_to_string(tags, ',') -- no need to convert array with ANY -- ELSE ... END IF; END $func$ LANGUAGE plpgsql;
用实际数组调用:
SELECT * FROM get_items_by_tag(VARIADIC '{tag1,tag2}'::text[]);
或致电列出项目(“字典”):
SELECT * FROM get_items_by_tag('tag1', 'tag2');
不知道为什么有IF array_length(tags, 1) > 0 THEN,但是可能被完全取代IF tags IS NOT NULL THEN或根本没有IF,然后跟进IF NOT FOUND THEN。
IF array_length(tags, 1) > 0 THEN
IF tags IS NOT NULL THEN
IF
IF NOT FOUND THEN