Najskuteczniejszy sposób na osiągnięcie tego:
- Uruchom pojedynczą
UPDATE
na stół. - Aktualizuj tylko kolumny dopuszczające wartość null (nie zdefiniowano
NOT NULL
) z dowolnym rzeczywistym pustym ciągiem. - Aktualizuj tylko wiersze z dowolnym pustym ciągiem.
- Pozostaw inne wartości bez zmian.
Ta powiązana odpowiedź ma funkcję plpgsql, która buduje i uruchamia UPDATE
polecenie przy użyciu katalogu systemowego pg_attribute
automatycznie i bezpiecznie dla dowolnej tabeli:
- Zastąp puste ciągi wartościami null
Korzystanie z funkcji f_empty2null()
z tej odpowiedzi możesz przeglądać wybrane tabele w następujący sposób:
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$;
Uważaj! To aktualizuje wszystkie puste ciągi we wszystkich kolumnach wszystkich tabel użytkowników w bazie danych. Upewnij się, że tego chcesz, bo może to zniszczyć Twoją bazę danych.
Potrzebujesz UPDATE
oczywiście przywileje na wszystkich wybranych stołach.
Jako urządzenie zabezpieczające dzieci skomentowałem ładunek.
Być może zauważyłeś, że korzystam bezpośrednio z katalogów systemowych, a nie ze schematu informacyjnego (który też by działał). O tym:
- Jak sprawdzić, czy tabela istnieje w danym schemacie
- Zapytanie do zwrócenia nazw kolumn wyjściowych i typów danych zapytania, tabeli lub widoku
Do wielokrotnego użytku
Oto zintegrowane rozwiązanie do wielokrotnego użytku. Bez urządzeń zabezpieczających:
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;
Zadzwoń:
SELECT * FROM pg_temp.f_all_empty2null();
Zwroty:
_tables | _rows
---------+---------
23 | 123456
Uwaga jak prawidłowo uciekł zarówno nazwy tabel, jak i kolumn!
c.oid::regclass AS tbl, quote_ident(attname) AS col
Rozważ:
- Nazwa tabeli jako parametr funkcji PostgreSQL
Uważaj! To samo ostrzeżenie, co powyżej.
Rozważ również podstawowe wyjaśnienie w odpowiedzi, którą połączyłem powyżej:
- Zastąp puste ciągi wartościami null