我们必须找到只有NULL值的表的列。我们正在尝试构建一个plpgsql函数,该函数采用表的名称并返回此类列的列表。
如何创建这样的功能?
我们正在使用PgAdmin 1.16。
您可以查询目录表pg_attribute以获取未定义列的列表,NOT NULL因此 可以 保存NULL值:
pg_attribute
NOT NULL
NULL
SELECT quote_ident(attname) AS column_can_be_null FROM pg_attribute WHERE attrelid = 'tbl'::regclass -- valid, visible table name AND attnum >= 1 -- exclude tableoid & friends AND NOT attisdropped -- exclude dropped columns AND NOT attnotnull -- exclude columns defined NOT NULL! ORDER BY attnum;
tbl您的表名在哪里(可选的,通过模式限定)在哪里。
tbl
不要说该列中没有任何实际的NULL值。您必须测试每列。像这样:
CREATE OR REPLACE FUNCTION f_all_null_columns_of_tbl(_tbl regclass) RETURNS SETOF text AS $func$ DECLARE _row_ct bigint; -- count rows in table $1 _sql text; -- SQL string to test for NULL values _cols text[]; -- array of candidate column names _nulls bool[]; -- array of test results BEGIN EXECUTE 'SELECT count(*) FROM ' || _tbl INTO _row_ct; IF _row_ct = 0 THEN RAISE EXCEPTION 'Table % has no rows!', _tbl; -- pointless for empty table ELSE RAISE NOTICE '% rows in table %.', _row_ct, _tbl; END IF; SELECT INTO _sql, _cols 'SELECT ARRAY[' || string_agg('bool_and(' || col || ' IS NULL)', ', ') || '] FROM ' || _tbl , array_agg(col) FROM ( SELECT quote_ident(attname) AS col FROM pg_attribute WHERE attrelid = _tbl -- valid, visible table name AND attnum >= 1 -- exclude tableoid & friends AND NOT attisdropped -- exclude dropped columns AND NOT attnotnull -- exclude columns defined NOT NULL! ORDER BY attnum ) sub; EXECUTE _sql INTO _nulls; FOR i IN 1 .. array_upper(_cols, 1) LOOP IF _nulls[i] THEN -- column is NULL in all rows RETURN NEXT _cols[i]; END IF; END LOOP; RETURN; END $func$ LANGUAGE plpgsql;
称呼:
SELECT f_all_null_columns_of_tbl('my_schema.my_table');
经过Postgres 9.1和9.3测试。这使用了许多高级的plpgsql功能。