sql >> Databáze >  >> RDS >> PostgreSQL

Nastavte prázdné řetězce ('') na NULL v celé databázi

Nejúčinnější způsob, jak toho dosáhnout:

  • Spusťte jeden příkaz UPDATE na stůl.
  • Aktualizovat pouze sloupce s povolenou hodnotou Null (nedefinováno NOT NULL ) s jakýmkoli skutečným prázdným řetězcem.
  • Aktualizujte řádky pouze se skutečným prázdným řetězcem.
  • Ponechte ostatní hodnoty beze změny.

Tato související odpověď má funkci plpgsql, která vytváří a spouští UPDATE příkaz pomocí systémového katalogu pg_attribute automaticky a bezpečně pro jakoukoli danou tabulku:

  • Nahraďte prázdné řetězce hodnotami null

Pomocí funkce f_empty2null() z této odpovědi můžete procházet vybrané tabulky takto:

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

Pozor! Tím se aktualizují všechny prázdné řetězce ve všech sloupcích všech uživatelských tabulek v DB. Ujistěte se, že to je to, co chcete, jinak by to mohlo zničit vaši databázi.

Potřebujete UPDATE oprávnění na všech vybraných tabulkách, samozřejmě.

Jako dětská pojistka jsem komentoval užitečné zatížení.

Možná jste si všimli, že používám přímo systémové katalogy, nikoli informační schéma (což by také fungovalo). O tomto:

  • Jak zkontrolovat, zda tabulka v daném schématu existuje
  • Dotaz pro vrácení názvů výstupních sloupců a datových typů dotazu, tabulky nebo zobrazení

Pro opakované použití

Zde je integrované řešení pro opakované použití. Bez bezpečnostních zařízení:

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;

Volejte:

SELECT * FROM pg_temp.f_all_empty2null();

Vrátí:

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

Poznámka jak jsem správně escapoval názvy tabulek i sloupců!

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

Zvažte:

  • Název tabulky jako parametr funkce PostgreSQL

Pozor! Stejné varování jako výše.
Zvažte také základní vysvětlení v odpovědi, kterou jsem uvedl výše:

  • Nahraďte prázdné řetězce hodnotami null


  1. Jak zjistím, zda je databáze Oracle nastavena na automatické potvrzení?

  2. Co vlastně používá LISTAGG s ORDER BY NULL jako kritérium objednávky?

  3. Kombinace dotazů s vnořeným polem záznamů v datovém typu JSON

  4. Jak napsat REST API?