2017-09-18 22 views
0

我有一大堆的表具有“统计”一栏(STAT的状态;-)手柄结果时动态SQL是在一个循环中

我希望每个统计的数量,并看看吧!

我的表看起来像这样

create table a (
    a_id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), 
    a_stat status_t 
); 
create table b (
    b_id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), 
    b_stat status_t 
); 

status_t是一个枚举。

所以我这样做:

DO $$ 
DECLARE 
    tableName RECORD; 
    result RECORD; 
BEGIN 
    SET SEARCH_PATH = projet, public; 

    FOR tableName IN SELECT 
      c.relname, 
      a.attname 
      FROM pg_class AS c 
      INNER JOIN pg_attribute AS a ON a.attrelid = c.oid 
      WHERE a.attname LIKE '%stat' AND c.relkind = 'r' LOOP 

     EXECUTE format('SELECT %I, count(%I) FROM %I GROUP BY %I', 
        tableName.attname, tableName.attname, tableName.relname, tableName.attname) INTO result; 
     SELECT * FROM result; 
    END LOOP; 
END; 
$$; 

有些事情,我觉得我做得还不够好这里。

  • 有可能是一个更好的形式格式的
  • 我不能选择一条记录,我觉得数据类型并不好(但不能找出我应该使用什么类型)
  • 一个选择在for循环中不是一个好主意(我认为?)但我没有找到如何将result放入结果数组中,并在for循环之后显示它。

如何正确地做到这一点?

+0

什么是“每个统计数”?所有的行?非空行?还有别的吗? –

回答

0

您不能从DO命令返回。您可以提出通知或写入临时表来解决此问题。而是使用适当的功能。就像这样:

CREATE OR REPLACE FUNCTION foo() 
    RETURNS TABLE (sch_name text, tbl_name text, col_name text, row_count_notnull int8) AS 
$func$ 
DECLARE 
    _sch text; 
    _tbl text; 
    _col text; 
BEGIN 
    FOR _sch, _tbl, _col IN 
     SELECT n.nspname, c.relname, a.attname 
     FROM pg_class  c 
     JOIN pg_attribute a ON a.attrelid = c.oid 
     JOIN pg_namespace n ON n.oid = c.relnamespace 
     WHERE c.relnamespace = ANY ('{projet, public}'::regnamespace[]) -- projet? project? 
     AND c.relkind = 'r' 
     AND a.attname LIKE '%\_stat' -- a_stat, b_stat 
    LOOP 
     RETURN QUERY EXECUTE format(
     'SELECT $1, $2, $3, count(%I) FROM %I.%I GROUP BY 1' 
     , _col, _sch, _tbl) 
     USING _sch, _tbl, _col; 
    END LOOP; 
END 
$func$ LANGUAGE plpgsql; 

电话:

SELECT * FROM foo(); 

要点:

  • 而且不能SELECT没有目标( SELECT * FROM result; ),无论是在DO命令,也不在PLPGSQL功能。 (你可以使用简单的SQL函数,但是你没有循环。)我返回RETURN QUERY EXECUTE的结果。

  • 通过USING子句到EXECUTE

  • 动态查询中的模式限定表。否则,您可能会意外地查询错误的表格。

  • 不包含像您尝试的临时模式(即使您不知道它)。你可以添加它使用pg_my_temp_schema()如果你想,但你可能不希望它反正:

相关:

plpgsql中有很多动态SQL的例子。 Try a search.

+0

谢谢,我想知道如果我可以在for循环结束时做一个选择,但具有适当功能的解决方案看起来不错,谢谢 –