Изменение всех нулей (если есть) по всем столбцам (в таблице) на ... скажем 1 - PullRequest
4 голосов
/ 22 марта 2012

У меня есть таблица с 18 столбцами (все целые) и 1040 строк.Если любое значение равно нулю, я хочу изменить его на 1. Я использую Postgresql.Каков наилучший способ сделать это.Я не могу придумать простое заявление об обновлении ... и я новичок в БД.

Любые указатели на то, на что мне следует обратить внимание, чтобы научиться достигать чего-то подобного ... (я бы подумал, что это какой-то сценарий, если такая вещь существует для postgresql .. Я не знаю)

Спасибо

Ответы [ 2 ]

2 голосов
/ 22 марта 2012

Инструмент для замены заданного значения новым значением во всех столбцах соответствующих таблиц

Я адаптировал используемую мной функцию plpgsql для аналогичной цели:

CREATE OR REPLACE FUNCTION f_update_all_cols(_sch text, _tbl text, _old int, _new int)
  RETURNS text AS
$func$
DECLARE
   _type   CONSTANT regtype[] := '{bigint,smallint,integer}';
   _toid   regclass;            -- table oid
   _msg    text := '';          -- report
   _ct     integer;             -- count of rows for report
BEGIN
  -- Loop over tables
FOR _toid IN
   SELECT c.oid
   FROM   pg_class c
   JOIN   pg_namespace nc ON nc.oid = c.relnamespace
   WHERE  c.relkind  = 'r'
   AND    nc.nspname = _sch
   AND    c.relname  LIKE (_tbl || '%')
   ORDER  BY c.relname
LOOP
   EXECUTE (
-- RAISE NOTICE '%', (
      SELECT format('UPDATE %s SET (%s) = (%s) WHERE $1 IN (%2$s)'
                , _toid
                , string_agg(quote_ident(attname), ', ' ORDER  BY a.attnum)
                , string_agg(format('CASE WHEN %1$I = $1 THEN $2 ELSE %1$I END', attname), ', ')
                )
      FROM   pg_attribute a
      WHERE  a.attrelid = _toid
      AND    a.attnum  >= 1      -- exclude neg. attnum - tableoid etc.
      AND    NOT a.attisdropped  -- exclude deleted columns
      AND    a.atttypid = ANY(_type)
      GROUP  BY _toid)
   USING  _old, _new;
-- );

   GET DIAGNOSTICS _ct = ROW_COUNT;
   _msg := _msg || _ct || ' row(s) in: ' || _toid || E'\n';
END LOOP;

RETURN _msg;

END
$func$  LANGUAGE plpgsql;

COMMENT ON FUNCTION f_update_all_cols(text, text, int, int) IS $$
Convert 0 to 1 in all integer type columns.
$1 .. _sch: schema
$2 .. _tbl: table-pattern: left anchored search pattern; default "%"
$3 .. _old: replace this ...
$4 .. _new: ... with this)   -- $$;

Звоните:

SELECT f_update_all_cols('myschema', '', 0, 1); -- all tables in schema
SELECT f_update_all_cols('myschema', 'foo', 0, 1); -- tables starting with foo

Просматривает все столбцы типа integer и изменяет заданное значение _old на заданное _new значение. Если вы хотите включить другие типы данных, отредактируйте переменную _type соответственно.

Прокомментируйте строку EXECUTE и USING, раскомментируйте RAISE NOTICE и заключительные скобки, чтобы проверить сгенерированный код перед выполнением.

2 голосов
/ 22 марта 2012

Как насчет этого

UPDATE table SET columnA = 1 WHERE columnA = 0

Но вам потребуется запрос для каждого столбца, или

UPDATE table SET columnA = 
CASE WHEN columnA = 0 THEN 1
ELSE columnA
END,

columnB = 
CASE WHEN columnB = 0 THEN 1
ELSE columnB
END, ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...