PostgreSQL 过程

PosgtreSQL procedure

我是 postgres 函数的新手。我的要求是 运行 在 postgres 数据库的特定模式中存在的每个 table 上的一个函数,但我遇到了一个问题,因为该函数在我的查询中每次调用时只返回一条记录每个table函数调用应该returns“n”条记录。啊,这可能令人困惑-请参阅代码-

create or replace function name_list(schema text, tablename text) 
  returns text
as $body$
declare
  result text;
  query text;
begin
  query := 'SELECT "names"  FROM ' || schema || '.' || tablename;
  RAISE NOTICE '"%"' , query;
  execute query into result;
  return result;
end;
$body$
language plpgsql;
copy(select 
  table_name, 
  name_list(table_schema, table_name)
  from information_schema.tables) to 'C:\test\name_list.csv' DELIMITER ',' CSV HEADER;

我读了一些类似 set of, loop 的东西,并尝试执行但仍然没有成功。任何帮助将不胜感激。

你的函数必须是 set-returning

create or replace function name_list(schemaname text, tablename text) 
  -- function will return a set
  RETURNS SETOF text
language 'plpgsql'
as $body$
declare
  _query text;
begin
  -- correct way to format the dynamic sql
  _query := FORMAT('SELECT "names" FROM %I.%I;', schemaname, tablename);
  RAISE NOTICE '"%"' , _query;
  -- execute and return all
  RETURN QUERY EXECUTE _query;
end;
$body$;

information_schema.tables may not give you what you expect exactly. The manual:

The view tables contains all tables and views defined in the current database. Only those tables and views are shown that the current user has access to (by way of being the owner or having some privilege).

参见:

  • How to check if a table exists in a given schema

此查询可能会满足您的要求:

SELECT quote_ident(n.nspname) AS schema  -- identifiers quoted where necessary
     , quote_ident(c.relname) AS table
     , (SELECT string_agg(quote_ident(a.attname), ', ' ORDER BY a.attnum) AS column_list
        FROM   pg_catalog.pg_attribute a
        WHERE  a.attrelid = c.oid
        AND    a.attnum > 0
        AND    NOT a.attisdropped) AS column_list  -- all columns in physical order
FROM   pg_catalog.pg_class c
JOIN   pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE  n.nspname = 'public'  -- only public schema (?)
AND    c.relkind = 'r'       -- only plain tables (?)
ORDER  BY n.nspname, c.relname;

结果如下:

schema | table           | column_list
------ +-----------------+---------------------------------------------
public | foo             | id, bar
public | spatial_ref_sys | srid, auth_name, auth_srid, srtext, proj4text
public | "weird TaBlE"   | "ID", "user", "dumb name"

db<>fiddle here

这只是 returns 普通表。您可能想要包含更多种类。 The manual about pg_class.relkind:

r = ordinary table, i = index, S = sequence, t = TOAST table, v = view, m = materialized view, c = composite type, f = foreign table, p = partitioned table, I = partitioned index