Как преобразовать столбец таблицы в другой тип данных - PullRequest
6 голосов
/ 21 мая 2010

У меня есть столбец с типом Varchar в моей базе данных Postgres, который я хотел обозначить целыми числами ... и теперь я хочу изменить их, к сожалению, это не работает с моей миграцией rails.

change_column :table1, :columnB, :integer

Который, кажется, выводит этот SQL:

ALTER TABLE table1 ALTER COLUMN columnB TYPE integer

Итак, я попытался сделать это:

execute 'ALTER TABLE table1 ALTER COLUMN columnB TYPE integer USING CAST(columnB AS INTEGER)'

но приведение не работает в этом случае, потому что некоторые столбцы имеют значение null ...

есть идеи?

Ошибка:

PGError: ERROR:  invalid input syntax for integer: ""
: ALTER TABLE table1 ALTER COLUMN columnB TYPE integer USING CAST(columnB AS INTEGER)

Postgres v8.3

Ответы [ 2 ]

13 голосов
/ 21 мая 2010

Похоже, проблема в том, что в вашей таблице пустые строки. Вам нужно будет обработать это, возможно, с помощью оператора case, такого как:

execute %{ALTER TABLE "table1" ALTER COLUMN columnB TYPE integer USING CAST(CASE columnB WHEN '' THEN NULL ELSE columnB END AS INTEGER)}

Обновление: полностью переписано на основе обновленного вопроса.

2 голосов
/ 21 мая 2010

NULL не должны быть проблемой здесь. Сообщите нам свою версию postgresql и сообщение об ошибке. Кроме того, почему вы цитируете идентификаторы? Имейте в виду, что идентификаторы без кавычек преобразуются в нижний регистр (поведение по умолчанию), поэтому в вашем запросе может возникнуть проблема с вашим столбцом «columnB» - он сначала отображается в кавычках, а в приведении - без кавычек.

Обновление: перед преобразованием столбца в целое число вы должны быть уверены, что все ваши значения являются конвертируемыми. В этом случае это означает, что столбец B должен содержать только цифры (или ноль). Вы можете проверить это чем-то вроде

  select columnB from table where not columnB ~ E'^[0-9]+$';

Если вы хотите, чтобы ваши пустые строки были преобразованы в целые числа NULL, то сначала запустите

  UPDATE table set  columnB = NULL WHERE columnB = '';
...