【问题标题】:How to run get the result from a query built from SELECT FORMAT in Postgresql at pgadmin?如何在 pgadmin 的 Postgresql 中运行从 SELECT FORMAT 构建的查询中获取结果?
【发布时间】:2021-05-09 19:18:51
【问题描述】:

我有一个在 pgadmin 中运行的命令,如下所示:

SELECT format('SELECT * FROM %I.%I CROSS JOIN LATERAL json_to_record(%I::json) AS rs(%s)', 'public', 'vehicles', 'column_A', array_to_string(
               (SELECT ARRAY(SELECT DISTINCT col FROM vehicles CROSS JOIN LATERAL json_object_keys(column_A::json) AS t(col) ORDER BY col)), ' text , '
 ) || ' text')

它打印一个以SELECT 语句开头的字符串。

如何直接从FORMAT 返回的字符串中获取查询结果?

我尝试过类似的方法:

DO
$$

WITH str as( SELECT format('SELECT * FROM %I.%I CROSS JOIN LATERAL json_to_record(%I::json) AS rs(%s)', 'public', 'vehicles', 'column_A', array_to_string(
               (SELECT ARRAY(SELECT DISTINCT col FROM vehicles CROSS JOIN LATERAL json_object_keys(column_A::json) AS t(col) ORDER BY col)), ' text , '
 ) || ' text'))

BEGIN EXECUTE str;

END
$$

但是,我收到一条错误消息:

错误:“WITH”处或附近的语法错误

我在这里错过了什么?请指教!!

更新答案

结合以下专家的回答,以下是更新后的版本,以供日后参考:

do $$
DECLARE
   query text;
begin
    query := format('SELECT * FROM %I.%I CROSS JOIN LATERAL json_to_record(%I::json) AS rs(%s)', 'public', 'vehicles', 'column_A', array_to_string(
               (SELECT ARRAY(SELECT DISTINCT col FROM vehicles CROSS JOIN LATERAL json_object_keys(column_A::json) AS t(col) ORDER BY col)), ' text , '
 ) || ' text');
    execute format('create or replace temp view tmp_view_vehicles as %s', query);
end $$;

select * from tmp_view_vehicles;

感谢大家的耐心等待!

【问题讨论】:

    标签: sql postgresql plpgsql pgadmin


    【解决方案1】:

    如果您不想创建存储函数但想使用匿名do 块获取结果,那么您可以使用临时视图:

    do $$
    begin
        execute format('create or replace temp view tmp_view_123 as select ...', ...);
    end $$;
    
    select * from tmp_view_123;
    

    创建的视图仅对当前会话可见。

    demo

    【讨论】:

    • 非常有用的建议。
    【解决方案2】:

    您混淆了 SQL 和 PL/pgSQL 语法,而且方式不一致。

    定义一个 PL/pgSQL 变量:

    DO
    $$DECLARE
       query text;
       result record;
    BEGIN
       query := format(...);
       EXECUTE query INTO result;
    END;$$;
    

    【讨论】:

    • 我如何从EXECUTE query得到结果?
    • EXECUTE ... INTO。但这与您的问题无关,是吗?
    • 对不起,如果我没有把我的问题说清楚。我想获得从字符串查询构建的结果。换句话说,我想从format(...) 得到结果,这是一个Select 语句。如何使用EXECUTE ... INTOSelect 获取结果?
    • 您要获取SELECT 语句还是SELECT 语句的结果?前者在query,后者可以在EXECUTE query INTO var
    • 我已经更新了我的问题。我想从SELECT 语句中得到结果。你能用EXECUTE query INTO var更新答案吗?如何声明上面的var 类型?
    【解决方案3】:

    简单的答案是

    do language plpgsql
    $$
    begin
     EXECUTE format('SELECT ....' <your code here>);
    end;
    $$;
    

    但是匿名块不返回任何东西。也许您必须将块塑造为table-returning function

    • 编辑

    我认为没有直接的方法可以做到这一点 - 动态更改函数的返回表结构。但是您可以返回一个包含键值对的单个 json 列。
    这是这样一个函数:

    create or replace function query_to_jsonset(qr text) returns setof json as
    $$
    begin
        return query execute 'SELECT row_to_json(dyntbl) FROM ('||qr||') AS dyntbl';
    end;
    $$ language plpgsql;
    

    然后您的查询将看起来很简单:

    select js from query_to_jsonset(format(....)) js;
    

    请注意query_to_jsonset 不安全。

    【讨论】:

    • 如何返回未定义列的表?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-12
    • 1970-01-01
    相关资源
    最近更新 更多