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
我是 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