2016-08-04 89 views
-3

Wie aktualisiert man ALLE Spalten einer Tabelle in PostgreSQL? Anstatt sie eine Spalte nach der anderen zu machen.
dieser Tabelle:Ersetzen Sie 'n/a' mit 'NA' in allen Spalten einer Tabelle

Table1 
Field1 | Field 2 | Field 3 
123 | 987  | NA 
456 | NA  | 101 
NA  | abcdef | NA 

ich für eine einzigen SQL-Abfrage Suche:

Table1 
Field1 | Field 2 | Field 3 
123 | 987  | n/a 
456 | n/a  | 101 
n/a | abcdef | n/a 

Das Ergebnis sein sollte.

Antwort

0

können Sie bauen den UPDATE Befehl dynamisch aus den Systemkatalogen in einem DO Anweisung oder plpgsql Funktion dafür:

CREATE OR REPLACE FUNCTION f_global_replace(_tbl regclass 
              , _old text 
              , _new text 
              , OUT updated_rows int) AS 
$func$ 
DECLARE 
    -- basic char types, possibly extend with citext, domains or custom types: 
    _typ CONSTANT regtype[] := '{text, bpchar, varchar}'; 
    _sql text; 
BEGIN 
    SELECT INTO _sql  -- build command 
      format('UPDATE %s SET %s WHERE $1 IN (%s)' 
       , _tbl 
       , string_agg(format('%1$s = CASE WHEN %1$s = $1 THEN $2 ELSE %1$s END', col), ', ') 
       , string_agg(col, ',')) 
    FROM (
     SELECT quote_ident(attname) AS col -- escape names, prevent SQL injection! 
     FROM pg_attribute 
     WHERE attrelid = _tbl    -- valid, visible, legal table name 
     AND attnum >= 1     -- exclude tableoid & friends 
     AND NOT attisdropped    -- exclude dropped columns 
     AND atttypid = ANY(_typ)   -- only character types 
     ORDER BY attnum 
    ) sub; 

    -- RAISE NOTICE '%', _sql;    -- debug 

    IF _sql IS NULL THEN 
     updated_rows := 0;       -- nothing to update 
    ELSE 
     EXECUTE _sql USING _old, _new; 
     GET DIAGNOSTICS updated_rows = ROW_COUNT; -- Report number of affected rows 
    END IF; 
END 
$func$ LANGUAGE plpgsql; 

Dieses montiert und führt automatisch eine Abfrage der Form:

UPDATE table1 SET field1 = CASE WHEN field1 = $1 THEN $2 ELSE field1 END , field2 = CASE WHEN field2 = $1 THEN $2 ELSE field2 END , field3 = CASE WHEN field3 = $1 THEN $2 ELSE field3 END WHERE $1 IN (field1,field2,field3);

Vorsicht! Die Funktion aktualisiert alle Zeichenspalten. Stellen Sie sicher, dass es wie erwartet funktioniert. Zur Sicherheit empfehle ich es in einer expliziten Transaktion laufen und erst nach Überprüfung begehen:

BEGIN; 
SELECT * FROM f_global_replace('table1'::regclass, 'n/a', 'NA'); 

TABLE table1; -- all good? 

COMMIT; -- then commit; else ROLLBACK; 

Verwandte Antworten mit mehr Informationen und Links:

+0

danke für die Hilfe :) –

+0

@NitinGoel: Wenn das Ihre Frage beantwortet, [in Betracht ziehen, es zu akzeptieren] (http://meta.stackexchange.com/questions/5234/ho w-akzeptiert-eine-Antwort-Arbeit/5235 # 5235). –