完全自动化的 PostgreSQL 完整解决方案
返回所有模式中的所有(非系统)表,其中所有列至少具有一个非空值。
您必须是超级用户(如 postgres)才能调用此函数。
或者你是一个超级用户可以拥有这个函数,它是用SECURITY DEFINER创建的。
CREATE OR REPLACE FUNCTION f_tbl_with_nonull_cols()
RETURNS TABLE(tbl text, columns text) AS
$BODY$
DECLARE
rel_id oid; -- oid of table
sch text; -- schema name
cols1 text; -- columns defined NOT NULL
cols2 text; -- other columns
q text; -- for query string
has_row bool; -- table has rows?
BEGIN
FOR rel_id, sch, tbl IN
SELECT c.oid -- AS rel_id
,n.nspname -- as sch
,c.relname -- as tbl
FROM pg_catalog.pg_class c
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind = 'r'
AND n.nspname <> 'pg_catalog'
AND n.nspname <> 'information_schema'
AND n.nspname !~ '^pg_toast'
AND pg_catalog.pg_table_is_visible(c.oid)
ORDER BY 2,3
LOOP
EXECUTE 'SELECT EXISTS (SELECT 1 FROM '
|| quote_ident(sch) ||'.' || quote_ident(tbl) || ')'
INTO has_row;
IF has_row THEN
-- defined NOT NULL -> must have values.
SELECT INTO cols1
string_agg(a.attname,', ')
FROM pg_catalog.pg_attribute a
WHERE a.attrelid = rel_id
AND a.attnum > 0
AND NOT a.attisdropped
AND a.attnotnull;
SELECT INTO q
'array_to_string(ARRAY['
|| string_agg('CASE WHEN count(' || quote_ident(a.attname)
|| ') > 0 THEN '''|| a.attname || ''' ELSE NULL END', ', ')
|| '], '', '')'
FROM pg_catalog.pg_attribute a
WHERE a.attrelid = rel_id
AND a.attnum > 0
AND NOT a.attisdropped
AND NOT a.attnotnull;
IF q IS NOT NULL THEN
EXECUTE 'SELECT ' || q || '
FROM ' || quote_ident(sch) || '.' || quote_ident(tbl)
INTO cols2;
columns := COALESCE(cols1 || ', ', '') || cols2;
ELSE
columns := COALESCE(cols1, '');
END IF;
RETURN NEXT;
ELSE
-- no rows, so no columns with non-null values
END IF;
END LOOP;
呼叫:
SELECT * FROM f_tbl_with_nonull_cols();
tbl | columns
----------------+----------------------------------
table1 | id, col1, col7,
table2 | id, col4, col5, col8, col9, col10
table5 | some_id
...