Най-ефективният начин да постигнете това:
- Изпълнете единична
UPDATE
на маса. - Актуализирайте само колони с нула (недефинирани
NOT NULL
). ) с всеки действително празен низ. - Актуализиране само на редове с действително празен низ.
- Оставете другите стойности непроменени.
Този свързан отговор има функция plpgsql, която изгражда и изпълнява UPDATE
команда с помощта на системния каталог pg_attribute
автоматично и безопасно за всяка дадена таблица:
- Заменете празните низове с нулеви стойности
Използване на функцията f_empty2null()
от този отговор можете да преминете през избрани таблици по следния начин:
DO
$do$
DECLARE
_tbl regclass;
BEGIN
FOR _tbl IN
SELECT c.oid::regclass
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind = 'r' -- only regular tables
AND n.nspname NOT LIKE 'pg_%' -- exclude system schemas
LOOP
RAISE NOTICE $$PERFORM f_empty2null('%');$$, _tbl;
-- PERFORM f_empty2null(_tbl); -- uncomment to prime the bomb
END LOOP;
END
$do$;
Внимавайте! Това актуализира всички празни низове във всички колони на всички потребителски таблици в DB. Уверете се, че това е, което искате, или може да удари вашата база данни.
Нуждаете се от UPDATE
привилегии за всички избрани таблици, разбира се.
Като устройство за безопасност на децата коментирах полезния товар.
Може би сте забелязали, че използвам директно системните каталози, а не информационната схема (която също би работила). Относно това:
- Как да проверите дали таблица съществува в дадена схема
- Заявка за връщане на имена на изходни колони и типове данни на заявка, таблица или изглед
За многократна употреба
Ето интегрирано решение за многократна употреба. Без предпазни устройства:
CREATE OR REPLACE FUNCTION f_all_empty2null(OUT _tables int, OUT _rows int) AS
$func$
DECLARE
_typ CONSTANT regtype[] := '{text, bpchar, varchar, \"char\"}';
_sql text;
_row_ct int;
BEGIN
_tables := 0; _rows := 0;
FOR _sql IN
SELECT format('UPDATE %s SET %s WHERE %s'
, t.tbl
, string_agg(format($$%1$s = NULLIF(%1$s, '')$$, t.col), ', ')
, string_agg(t.col || $$ = ''$$, ' OR '))
FROM (
SELECT c.oid::regclass AS tbl, quote_ident(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 NOT LIKE 'pg_%' -- exclude system schemas
AND c.relkind = 'r' -- only regular tables
AND a.attnum >= 1 -- exclude tableoid & friends
AND NOT a.attisdropped -- exclude dropped columns
AND NOT a.attnotnull -- exclude columns defined NOT NULL!
AND a.atttypid = ANY(_typ) -- only character types
ORDER BY a.attnum
) t
GROUP BY t.tbl
LOOP
EXECUTE _sql;
GET DIAGNOSTICS _row_ct = ROW_COUNT; -- report nr. of affected rows
_tables := _tables + 1;
_rows := _rows + _row_ct;
END LOOP;
END
$func$ LANGUAGE plpgsql;
Обадете се:
SELECT * FROM pg_temp.f_all_empty2null();
Връща:
_tables | _rows
---------+---------
23 | 123456
Забележка как избягах правилно имената на таблици и колони!
c.oid::regclass AS tbl, quote_ident(attname) AS col
Помислете за:
- Име на таблица като параметър на функцията на PostgreSQL
Внимавайте! Същото предупреждение като по-горе.
Помислете и за основното обяснение в отговора, който посочих по-горе:
- Заменете празните низове с нулеви стойности