有什么方法可以在Postgres中获得更有意义的错误消息?

我们来喝点茶吧...

CREATE OR REPLACE FUNCTION allRelevantTeas() RETURNS TABLE(tea_id INTEGER) AS $function$
DeclARE
    result REFCURSOR;
    stmt TEXT;
    countries_with_tea TEXT[] := array['england','turkey','india','japan','china'];
BEGIN
    stmt := '';
    FOR tea_drinker in countries_with_tea LOOP
        stmt := stmt || format($$(SELECT tea_id FROM %I)$$,tea_drinker);
        IF tea_drinker <> 'china' THEN
            stmt := stmt || $$ UNION $$;
        END IF;
    END LOOP;

    OPEN result FOR EXECUTE stmt;
    RETURN result;
END $function$
LANGUAGE plpgsql STABLE;

SELECT * FROM allRelevantTeas();

让我们测试一下...

“ countries_with_tea”或附近的语法错误

我没看到。这可能很明显,但我只是看不到。

有人发现这是怎么回事吗?还是如果没有,有什么办法可以使Postgres获得比“存在语法错误(但我不告诉你它是什么)”更有意义的错误?

qq4714167 回答:有什么方法可以在Postgres中获得更有意义的错误消息?

您在上的循环是错误的,您需要使用FOREACHloop through the elements of an array

CREATE OR REPLACE FUNCTION allRelevantTeas() RETURNS TABLE(tea_id INTEGER) AS $function$
DECLARE
    stmt TEXT;
    tea_drinker text;
    countries_with_tea TEXT[] := array['england','turkey','india','japan','china'];
BEGIN
    stmt := '';
    FOREACH tea_drinker in array countries_with_tea LOOP
        stmt := stmt || format($$(SELECT tea_id FROM %I)$$,tea_drinker);
        IF tea_drinker <> 'china' THEN
            stmt := stmt || $$ UNION $$;
        END IF;
    END LOOP;

    RETURN query execute stmt;
END $function$
LANGUAGE plpgsql STABLE;

您实际上并不需要UNION,可以使用return query返回多个结果:

CREATE OR REPLACE FUNCTION allrelevantteas() 
  RETURNS TABLE(tea_id INTEGER) AS $function$
DECLARE
    stmt TEXT;
    tea_drinker text;
    countries_with_tea TEXT[] := array['england','china'];
BEGIN
    stmt := '';
    FOREACH tea_drinker in array countries_with_tea LOOP
      stmt := format($$(SELECT tea_id FROM %I)$$,tea_drinker);
      return query execute stmt;
    END LOOP;
END $function$
LANGUAGE plpgsql STABLE;

Online example


如果需要该日志,则最好使用表继承或视图来创建包含所有其他表的单个表。

,

只需一点便笺。我经常看我的代码,问:“在任何可预见的变化中是否有任何可能破坏的东西,现在可以防止它吗?”多年来一直很好,我几乎总能找到一些东西。这里有一个。语句“ If tea_drinker ... end if”非常脆弱。当另一个国家被添加到数组中并在中国之后被添加时会发生什么。回答,您的SQL执行失败。强化版本将检查当前tea_drinker到数组中最后一个输入的位置。这可以通过array functions,array_position和array_length来完成。

-- Instead of: 
IF tea_drinker <> 'china' THEN
   stmt := stmt || $$ UNION $$;
END IF;

-- Use 
if array_position(countries_with_tea,tea_drinker) <> array_length(countries_with_tea,1)
then 
   stmt := stmt || $$ UNION $$;
end if;
,

a_horse_with_no_name告诉您如何解决该错误,但是为了获得更有意义的错误消息,我已经使用psql收到了一条消息:

ERROR:  syntax error at or near "countries_with_tea"
LINE 8:     FOR tea_drinker in countries_with_tea LOOP
                               ^

如果您仅在第一行看到您,而在后两行看不到,则您使用的不是您的朋友。

本文链接:https://www.f2er.com/2791768.html

大家都在问