【问题标题】:Postgres dynamically select all text columns - subquery?Postgres 动态选择所有文本列 - 子查询?
【发布时间】:2014-01-22 10:28:09
【问题描述】:

我想要一个返回表中所有类型为“字符变化”的字段的选择。它需要跨多个表运行,因此需要是动态的。

我试图使用子查询首先获取文本列,然后运行查询:

SELECT (SELECT STRING_AGG(QUOTE_IDENT(column_name), ', ') FROM 
information_schema.columns WHERE table_name = foo 
AND data_type = 'character varying') FROM foo;

但这不起作用,我只得到一个列名列表,而不是值。有谁知道我怎样才能使它工作或更好的方法?

谢谢你, 本

【问题讨论】:

  • 您必须在第一步中生成 SQL 并在第二步中执行它。单个 SQL 语句在其自身执行期间无法自行生成。

标签: sql postgresql


【解决方案1】:

为此,您需要 Pl/PgSQL,因为 PostgreSQL 在其普通 SQL 方言中不支持动态 SQL。

CREATE OR REPLACE FUNCTION get_cols(target_table text) RETURNS SETOF record AS $$
DECLARE
    cols text;
BEGIN
    cols := (SELECT STRING_AGG(QUOTE_IDENT(column_name), ', ')
             FROM information_schema.columns 
             WHERE table_name = target_table 
             AND data_type = 'character varying');

    RETURN QUERY EXECUTE 'SELECT '||cols||' FROM '||quote_ident(target_table)||';';
END;
$$
LANGUAGE plpgsql;

但是,您会发现这很难调用,因为您需要知道结果列列表才能调用它。那种事是不合情理的。您需要将结果按摩成具体类型。我在这里转换为hstore,但您可以返回json 或数组或其他任何东西,真的:

CREATE OR REPLACE FUNCTION get_cols(target_table text) RETURNS SETOF hstore AS $$
DECLARE
    cols text;
BEGIN
    cols := (SELECT STRING_AGG(QUOTE_IDENT(column_name), ', ')
             FROM information_schema.columns 
             WHERE table_name = target_table 
             AND data_type = 'character varying');

    RETURN QUERY EXECUTE 'SELECT hstore(ROW('||cols||')) FROM '||quote_ident(target_table)||';';
END;
$$
LANGUAGE plpgsql;

动态 SQL 很麻烦,请考虑在应用程序级别执行此操作。

【讨论】:

  • 非常感谢您的广泛回答,很遗憾这样做很痛苦,但知道如何做很有趣。我会改为尝试应用级别。
猜你喜欢
  • 2023-03-08
  • 1970-01-01
  • 2019-08-27
  • 2021-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-28
  • 2013-07-26
相关资源
最近更新 更多