sql >> Database >  >> RDS >> PostgreSQL

Stel lege strings ('') in op NULL in de hele database

De meest efficiënte manier om dit te bereiken:

  • Voer een enkele UPDATE uit per tafel.
  • Alleen null-kolommen bijwerken (niet gedefinieerd NOT NULL ) met een daadwerkelijke lege tekenreeks.
  • Alleen rijen bijwerken met een daadwerkelijke lege tekenreeks.
  • Laat andere waarden ongewijzigd.

Dit gerelateerde antwoord heeft een plpgsql-functie die de UPDATE . bouwt en uitvoert commando met behulp van systeemcatalogus pg_attribute automatisch en veilig voor een bepaalde tafel:

  • Vervang lege tekenreeksen door null-waarden

Gebruik van de functie f_empty2null() van dit antwoord kun je als volgt door geselecteerde tabellen bladeren:

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

Voorzichtig! Hiermee worden alle lege tekenreeksen in alle kolommen van alle gebruikerstabellen in de database bijgewerkt. Zorg ervoor dat u dat wilt, anders kan uw database worden vernietigd.

Je hebt UPDATE nodig privileges op alle geselecteerde tafels, natuurlijk.

Als kinderbeveiliging heb ik commentaar gegeven op de lading.

Je hebt misschien opgemerkt dat ik de systeemcatalogi rechtstreeks gebruik, niet het informatieschema (wat ook zou werken). Over dit:

  • Hoe te controleren of een tabel in een bepaald schema bestaat
  • Query om namen van uitvoerkolommen en gegevenstypen van een query, tabel of weergave te retourneren

Voor herhaald gebruik

Hier is een geïntegreerde oplossing voor herhaald gebruik. Zonder veiligheidsvoorzieningen:

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;

Bel:

SELECT * FROM pg_temp.f_all_empty2null();

Retourneren:

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

Opmerking hoe ik zowel de tabel- als de kolomnamen op de juiste manier heb ontsnapt!

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

Overweeg:

  • Tabelnaam als een PostgreSQL-functieparameter

Voorzichtig! Dezelfde waarschuwing als hierboven.
Beschouw ook de basisuitleg in het antwoord dat ik hierboven heb gelinkt:

  • Vervang lege tekenreeksen door null-waarden


  1. Hoe te converteren naar hoofdletters in MariaDB

  2. Dynamisch kolommen genereren in PostgreSQL

  3. Hoe de volgende waarde van de SQL Server-reeks in Entity Framework te krijgen?

  4. Verbinding maken met Vertica in IRI Workbench