有没有办法列出信息模式中包含带NULL值的布尔类型列的所有表?如果我有表的名称,我以后可以使用查询:
SELECT * FROM table_name WHERE column_name IS NULL
当然,如果有办法用单个查询列出所有表中的所有行,那就更快了。
一步一步地执行此操作:
SELECT * FROM table1 WHERE column_name IS NULL
SELECT * FROM table2 WHERE column_name IS NULL
SELECT * FROM table3 WHERE column_name IS NULL
...
已填充表,对于新数据库,此类列应具有NOT NULL
约束。
答案 0 :(得分:3)
尝试:
SELECT table_catalog, table_schema, table_name, column_name, ordinal_position
FROM information_schema.columns
WHERE table_schema <> 'pg_catalog' AND data_type = 'boolean';
和:
DO $$
DECLARE
r record;
s record;
BEGIN
FOR r IN SELECT table_catalog, table_schema, table_name, column_name, ordinal_position
FROM information_schema.columns
WHERE table_schema <> 'pg_catalog' AND data_type = 'boolean'
LOOP
FOR s IN EXECUTE 'SELECT ' || quote_literal(r.table_schema) || ', ' || quote_literal(r.table_name) || ', ' || quote_literal(r.column_name) || ' WHERE EXISTS (SELECT 1 FROM ' || quote_ident(r.table_schema) || '.' || quote_ident(r.table_name) || ' WHERE ' || quote_ident(r.column_name) || ' IS NULL);'
LOOP
RAISE NOTICE '** % % %', quote_ident(r.table_schema), quote_ident(r.table_name), quote_ident(r.column_name);
END LOOP;
END LOOP;
END
$$;
奥斯瓦尔多
答案 1 :(得分:2)
如果您正在运行postgresql 9.0+,则可以使用匿名plpgsql块来执行某些动态SQL。
DO $$
DECLARE
rec RECORD;
v_result INTEGER;
BEGIN
FOR rec IN
SELECT 'select 1 from ' || quote_ident(n.nspname) ||'.'|| quote_ident(c.relname) ||
' where ' || quote_ident(a.attname) || ' IS NULL LIMIT 1' as qry_to_run,
n.nspname||'.'||c.relname as tbl,
a.attname as col
FROM pg_class as c
INNER JOIN pg_attribute as a ON (a.attrelid = c.oid)
INNER JOIN pg_type as t ON (t.oid = a.atttypid)
LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE a.attnum >= 1
AND c.relkind = 'r'
AND pg_catalog.format_type(a.atttypid, a.atttypmod) = 'boolean'
AND n.nspname NOT IN ('pg_catalog','information_schema')
AND a.attnotnull IS NOT TRUE
LOOP
EXECUTE rec.qry_to_run INTO v_result;
IF v_result = 1 THEN
RAISE NOTICE 'Table % has NULLs in the BOOLEAN field %', rec.tbl,rec.col;
v_result := 0;
END IF;
END LOOP;
END;
$$;
答案 2 :(得分:2)
这使@bma's excellent answer更进一步,使其更短,更快,更聪明:
DO $$
DECLARE
rec record;
_found boolean;
BEGIN
FOR rec IN
SELECT format('SELECT TRUE FROM %s WHERE %I IS NULL LIMIT 1'
, c.oid::regclass, a.attname) AS qry_to_run
,c.oid::regclass AS tbl
,a.attname AS col
FROM pg_namespace n
JOIN pg_class c ON c.relnamespace = n.oid
JOIN pg_attribute a ON a.attrelid = c.oid
WHERE n.nspname <> 'information_schema'
AND n.nspname NOT LIKE 'pg_%' -- exclude system, temp, toast tbls
AND c.relkind = 'r'
AND a.attnum > 0
AND a.atttypid = 'boolean'::regtype
AND a.attnotnull = FALSE
AND a.attisdropped = FALSE
LOOP
EXECUTE rec.qry_to_run INTO _found;
IF _found THEN
RAISE NOTICE 'Table % has NULLs in the BOOLEAN field %'
, rec.tbl,rec.col;
END IF;
END LOOP;
END
$$;