PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Setzen Sie leere Zeichenfolgen ('') in der gesamten Datenbank auf NULL

Der effizienteste Weg, dies zu erreichen:

  • Führen Sie ein einzelnes UPDATE aus pro Tisch.
  • Nur Nullable-Spalten aktualisieren (nicht definiert NOT NULL ) mit einem beliebigen leeren String.
  • Aktualisiere nur Zeilen mit tatsächlich leeren Zeichenfolgen.
  • Lassen Sie andere Werte unverändert.

Diese verwandte Antwort hat eine plpgsql-Funktion, die UPDATE erstellt und ausführt Befehl unter Verwendung des Systemkatalogs pg_attribute automatisch und sicher für jede gegebene Tabelle:

  • Leere Zeichenfolgen durch Nullwerte ersetzen

Verwenden der Funktion f_empty2null() Von dieser Antwort aus können Sie ausgewählte Tabellen wie folgt durchlaufen:

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$;

Vorsicht! Dadurch werden alle leeren Zeichenfolgen in allen Spalten aller Benutzertabellen in der DB aktualisiert. Stellen Sie sicher, dass Sie das wollen, oder es könnte Ihre Datenbank zerstören.

Sie benötigen UPDATE Privilegien auf alle ausgewählten Tabellen natürlich.

Als Kindersicherung habe ich die Zuladung kommentiert.

Sie haben vielleicht bemerkt, dass ich direkt die Systemkataloge verwende, nicht das Informationsschema (was auch funktionieren würde). Dazu:

  • Überprüfen, ob eine Tabelle in einem bestimmten Schema existiert
  • Abfrage zur Rückgabe von Ausgabespaltennamen und Datentypen einer Abfrage, Tabelle oder Ansicht

Für wiederholten Gebrauch

Hier ist eine integrierte Lösung für die wiederholte Verwendung. Ohne Sicherheitseinrichtungen:

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;

Aufruf:

SELECT * FROM pg_temp.f_all_empty2null();

Rückgabe:

 _tables | _rows
---------+---------
 23      | 123456

Hinweis wie ich sowohl Tabellen- als auch Spaltennamen richtig maskiert habe!

c.oid::regclass AS tbl, quote_ident(attname)  AS col

Bedenken Sie:

  • Tabellenname als PostgreSQL-Funktionsparameter

Vorsicht! Dieselbe Warnung wie oben.
Beachten Sie auch die grundlegende Erklärung in der Antwort, die ich oben verlinkt habe:

  • Leere Zeichenfolgen durch Nullwerte ersetzen