我们有一些遗留代码+数据,在对列设置NOT NULL
限制时有点懒惰(生成数据的代码也是如此(。
并不总是知道这些列是否应该为空(有时功能是几年前编写的(。
最好查看我们的真实数据,看看这些列中是否有任何可为空,但碰巧没有 NULL 值。我们可能会考虑其中一些作为候选者,以添加非空限制。
(显然,仅仅没有空值并不意味着这并不一定意味着它们不应该为空:我们可能只是运气不好,但这是一个很好的起点(
这是我想到的:
CREATE OR REPLACE FUNCTION any_is_null(col TEXT, tab TEXT, OUT tmp BOOL) RETURNS boolean
AS $$
BEGIN
EXECUTE format('SELECT
true
from %s
WHERE %s IS NULL LIMIT 1
', tab, col) into tmp;
END;
$$ LANGUAGE plpgsql;
select c.table_schema,
c.table_name,
c.column_name,
case c.is_nullable
when 'NO' then 'false'
when 'YES' then 'true'
end as nullable,
CASE
WHEN any_is_null(c.column_name, c.table_name) IS NULL
AND c.is_nullable = 'YES'
THEN true
ELSE FALSE
END as could_be_non_nullable
from information_schema.columns c
join information_schema.tables t
on c.table_schema = t.table_schema
and c.table_name = t.table_name
where c.table_schema in ('public')
and t.table_type = 'BASE TABLE'
order by table_schema,
table_name,
column_name;
将where c.table_schema in ('public')
替换为要关注的架构。
完成后不要忘记删除该功能。
PS:如果您有很多没有 NULL 值的列,这可能会最大化您的数据库,因为每一列都会被全表扫描(所以要小心!