Gerade habe ich in einem Projekt eine legacy Datenbank nach Postgres importiert, und bin dabei sie zu analysieren und umzubauen. Dabei sind die Längenangaben bei Feldern vom Typ character varying
immer interessant. Hierbei kann man eine Maximallänge des Feldes in Zeichen angeben. Bei vorgegebenen Daten ist die Ausnutzung dieser Länge interessant, also die Frage, wie lang ist die maximal abgespeicherte Zeichenlänge in jedem Feld.
Eine Idee ist dies mit einer PL/pgSQL-Function zu berechnen, nach etwas Tüfteln habe ich sie hingebracht:
CREATE OR REPLACE FUNCTION public.character_varying_length() RETURNS TABLE(table_name varchar, column_name varchar, character_maximum_length integer, actual_maximum_length integer) AS $func$ DECLARE tbl information_schema.columns.table_name%TYPE; col information_schema.columns.column_name%TYPE; width information_schema.columns.character_maximum_length%TYPE; BEGIN FOR tbl, col, width IN SELECT c.table_name, c.column_name, c.character_maximum_length FROM information_schema.columns c WHERE c.table_schema = 'public' and c.data_type = 'character varying' order by c.table_name, c.ordinal_position LOOP RETURN QUERY EXECUTE format('SELECT %L::varchar, %L::varchar, %s::integer, max(length(%I)) from %I', tbl, col, width, col, tbl); END LOOP; END $func$ LANGUAGE plpgsql;
Aufgerufen wird dies mit
select * from character_varying_length()
und liefert dann 4 Spalten für alle character varying felder im Schema public
:
Diese Funktion funktioniert in jeder Postgres-Datenbank, einfach deklarieren und aufrufen wie oben.