Поскольку вы заранее не знаете имен столбцов, но хотите использовать имя столбца в запросе, вам придется использовать динамический sql.Вот краткий пример:
CREATE TABLE t1 (id INTEGER, txt TEXT);
INSERT INTO t1
SELECT g, random()::TEXT
FROM generate_series(1, 10) g;
Тогда SQL для генерации запроса:
DO $$
DECLARE
query TEXT;
BEGIN
SELECT 'SELECT ' || STRING_AGG(FORMAT('sum(pg_column_size(%1$I)) AS %1$s', column_name), ', ') || ' FROM t1'
INTO query
FROM information_schema.columns
WHERE table_schema = 'public'
AND table_name = 't1';
RAISE NOTICE '%', query;
END $$
Созданный запрос SELECT pg_size_pretty(sum(pg_column_size(id))) AS id, pg_size_pretty(sum(pg_column_size(txt))) AS txt FROM t1
будет работать так же, еслиу вас были сотни столбцов.
Теперь, чтобы заставить его сгенерировать, выполнить запрос и вернуть вам результаты, это действительно зависит от того, что вы хотите.Если вы счастливы, просто распечатав его на экране, то, возможно, вы можете отформатировать его следующим образом:
DO $$
DECLARE
query TEXT;
result TEXT;
BEGIN
SELECT 'SELECT CONCAT_WS(E''\n'', ' || STRING_AGG(FORMAT('''%1$s: '' || pg_size_pretty(sum(pg_column_size(%1$I)))', column_name), ', ') || ') FROM t1'
INTO query
FROM information_schema.columns
WHERE table_schema = 'public'
AND table_name = 't1';
EXECUTE query
INTO result;
RAISE NOTICE '%', result;
END $$
Это напечатает:
id: 40 bytes
txt: 181 bytes
Если вместо этого вы хотите записьвернулся с несколькими столбцами, я не слишком уверен, как бы вы поступили, потому что количество столбцов и их имена будут неизвестны.Лучший вариант, который я могу обдумать, это вернуть его как JSON, тогда вы вернете только одну вещь, и там будет переменное число полей с любыми именами столбцов:
CREATE OR REPLACE FUNCTION test1(_schema_name TEXT, _table_name TEXT)
RETURNS JSON AS
$$
DECLARE
query TEXT;
result JSON;
BEGIN
SELECT 'SELECT ROW_TO_JSON(cols) FROM (SELECT ' || STRING_AGG(FORMAT('pg_size_pretty(sum(pg_column_size(%1$I))) AS %1$s', column_name), ', ') || ' FROM t1) AS cols'
INTO query
FROM information_schema.columns
WHERE table_schema = _schema_name
AND table_name = _table_name;
EXECUTE query
INTO result;
RETURN result;
END
$$
LANGUAGE plpgsql;
Запуск его: SELECT test1('public', 't1')
Возвращает: {"id":"40 bytes","txt":"181 bytes"}