Note that the average column length will only be accurate after RUNSTATS was performed. Also, you could combine steps 1 and 2 quite easily into a single query:
Code:
SELECT SUBSTR(c.tabname, 1, 30),
(SUM(AVGCOLLEN) + 10) * ( SELECT card
FROM syscat.tables AS t
WHERE t.tabname = c.tabname )
FROM syscat.columns AS c
GROUP BY tabname
HAVING tabname IN ( SELECT tabname
FROM syscat.tables
WHERE type = 'T' )
Furthermore, you calculate the number of bytes that the data in a table requires. But the rows are stored on pages and SYSCAT.TABLES.NPAGES gives you the number of pages for a table. Multiply that by the page size and you will get the real storage occupied by the table (again, RUNSTATS is necessary to get an accurate page count).
p.s: If you are on DB2 LUW, you should not use the internal and undocumented tables in schema SYSIBM. Instead, refer to the official catalog views in the SYSCAT schema. Otherwise, it will be your fault if your application breaks due to catalog changes.