Sql 将表中所有列中的“不适用”替换为“不适用”

Sql 将表中所有列中的“不适用”替换为“不适用”,sql,postgresql,sql-update,dynamic-sql,psql,Sql,Postgresql,Sql Update,Dynamic Sql,Psql,如何在PostgreSQL中更新表的所有列?而不是一次只做一个专栏。 鉴于此表: Table1 Field1 | Field 2 | Field 3 123 | 987 | n/a 456 | n/a | 101 n/a | abcdef | n/a 结果应该是: Table1 Field1 | Field 2 | Field 3 123 | 987 | NA 456 | NA | 101 NA | abcdef |

如何在PostgreSQL中更新表的所有列?而不是一次只做一个专栏。 鉴于此表:

Table1
Field1 | Field 2 | Field 3
123    | 987     | n/a
456    | n/a     | 101
n/a    | abcdef  | n/a
结果应该是:

Table1
Field1 | Field 2 | Field 3
123    | 987     | NA
456    | NA      | 101
NA     | abcdef  | NA
我正在寻找单个SQL查询。

您可以从DO语句或plpgsql函数中的系统目录动态生成更新命令:

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;
这将汇编并自动执行以下表单的查询:

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);
提供更多信息和链接的相关答案:


@尼廷格尔:如果这回答了你的问题。
BEGIN;
SELECT * FROM f_global_replace('table1'::regclass, 'n/a', 'NA');

TABLE table1;  -- all good?

COMMIT;  -- then commit; else ROLLBACK;