varchar 필드의 유형을 정수로 변경 : "정수 유형으로 자동으로 캐스트 할 수 없음"


154

작은 테이블이 있고 특정 필드에 " character varying " 유형이 있습니다 . " 정수 " 로 변경하려고하는데 캐스팅이 불가능하다는 오류가 발생합니다.

이 문제를 해결할 방법이 있습니까? 아니면 다른 테이블을 만들고 쿼리를 사용하여 레코드를 가져와야합니다.

이 필드에는 정수 값만 포함됩니다.


어떤 ALTER TABLE을 시도했고 특정 오류 메시지는 무엇입니까?
mu는 너무 짧습니다.

@muistooshort 나는 phppgadmin에서 alter를 사용해 보았습니다. 열을 선택하고 새 필드 유형을 입력하려고했습니다. 오류는 :SQL error: ERROR: column "MID" cannot be cast to type integer
itsols

3
첫 번째는 테이블을 백업하는 것입니다. 그런 다음 동일한 테이블에 정수 유형의 다른 열 (예 : field2)을 작성할 수 있습니다. field1의 정수 값으로 변환을 field2로 선택하십시오. 그런 다음 열의 이름을 바꿉니다.
Igor

@ Igor하지만 새 열이 테이블의 끝에 떨어집니다. 같은 위치에 가질 수 없습니까?
itsols

2
@itsols 열 위치에 대한 관심은 대개 iffy 응용 프로그램 디자인의 표시입니다. 거의 항상 SELECT열 서수 위치에 의존하지 않고 명시 적으로 명명 된 열과 목록을 사용하려고합니다 . 즉, 답변에 제공된 접근 방식은 열 위치를 유지합니다.
Craig Ringer

답변:


264

에서 암시 (자동) 주조 없습니다 text또는 varchar으로는 integer(A를 전달할 수 없습니다 당신을 즉, varchar기대 함수에 integer또는 지정 varchar에 필드를 integer사용 명시 적 캐스트 지정해야하므로, 하나) ALTER TABLE ... ALTER COLUMN에 ... TYPE을. .. 사용 :

ALTER TABLE the_table ALTER COLUMN col_name TYPE integer USING (col_name::integer);

텍스트 필드에 공백이있을 수 있습니다. 이 경우 다음을 사용하십시오.

ALTER TABLE the_table ALTER COLUMN col_name TYPE integer USING (trim(col_name)::integer);

변환하기 전에 공백을 제거합니다.

이 명령은에서 명령을 실행 한 경우 오류 메시지에서 분명 psql하지만 PgAdmin-III이 전체 오류를 표시하지 않을 수 있습니다. psqlPostgreSQL 9.2 에서 테스트하면 어떻게됩니까?

=> CREATE TABLE test( x varchar );
CREATE TABLE
=> insert into test(x) values ('14'), (' 42  ');
INSERT 0 2
=> ALTER TABLE test ALTER COLUMN x TYPE integer;
ERROR:  column "x" cannot be cast automatically to type integer
HINT:  Specify a USING expression to perform the conversion. 
=> ALTER TABLE test ALTER COLUMN x TYPE integer USING (trim(x)::integer);
ALTER TABLE        

USING링크 를 추가해 주셔서 감사합니다 @muistooshort .

이 관련 질문 도 참조하십시오 . Rails 마이그레이션에 관한 것이지만 근본 원인은 동일하며 답변이 적용됩니다.

오류가 계속 발생하면 열 값과 관련이 없지만이 열 또는 열 기본값에 대한 인덱스는 유형 변환에 실패 할 수 있습니다. ALTER COLUMN 전에 인덱스를 삭제 한 후 다시 작성해야합니다. 기본값은 적절히 변경해야합니다.


시간 내 주셔서 감사합니다. 그러나 나는 이것을 작동시킬 수 없다. 나는 당신의 ALTER 라인을 시험해 보았습니다. 그리고 "Syntax error Using Using"근처에 오류가 있습니다
itsols

내 진술 : ALTER TABLE "tblMenus"ALTER COLUMN "MID"USING (trim ( "MID") :: integer);
itsols

1
@itsols 내 실수 야. 나는 당신의 의견을 본 것처럼 그것을 고쳤습니다. 개정판을 참조하십시오. 처음에는 일반적인 예제가 아니라 데모 코드에서 옳았습니다.
Craig Ringer

정말 감사합니다! 이 답변은 많은 문제와 시간을 절약했습니다. 왜 niether phppgadmin이나 pgadmin이 이것을 기능으로 가지고 있는지 궁금합니다.
itsols

@itsols 대부분의 핵심 팀은 PgAdmin에 관심이 없으며 그 중 일부를 사용합니다. 그것은 약간의 성가신 유용성 사마귀와 기능 제한이 있습니다. 이것은 그들 중 많은 것 중 하나 일뿐입니다. PgAdmin을 사용하는 전문가는 거의 없기 때문에 자신을 괴롭히는 것을 고치려는 동기는 없습니다. psql더 빠르고 쉽게 찾을 수 있기 때문에 직접 사용하지는 않습니다 . 필자는 blog.ringerc.id.au/2012/05/…
Craig Ringer

70

이것은 나를 위해 일했습니다.

varchar 열을 int로 변경

change_column :table_name, :column_name, :integer

얻었다 :

PG::DatatypeMismatch: ERROR:  column "column_name" cannot be cast automatically to type integer
HINT:  Specify a USING expression to perform the conversion.

에 물렸다

change_column :table_name, :column_name, 'integer USING CAST(column_name AS integer)'

이 연습을 데이터로 사용해 보았으며 데이터가 손상되지 않았습니까?
itsols

3
열에있는 것이 정수인 한, yes
bibangamba

나와 함께 작동하지 않습니다. 저는 레일이있는 루비 2.2.3을 사용하고 있습니다. 4.2.3
Thinh D. Bui

@ ThinhD.Bui-나를 위해 일함, 2.3.0, 레일 4.2.6
Philip

1
뿐만 아니라 기본 설정에주의
시스코 퀸 테로

17

당신은 다음과 같이 할 수 있습니다 :

change_column :table_name, :column_name, 'integer USING CAST(column_name AS integer)'

또는 이것을 시도하십시오 :

change_column :table_name, :column_name, :integer, using: 'column_name::integer'

이 주제에 대해 더 자세히 알고 싶다면이 기사를 읽으십시오 : https://kolosek.com/rails-change-database-column


8

이것을 시도하십시오, 그것은 확실히 작동합니다.

문자열 열을 정수로 변환하기 위해 Rails 마이그레이션을 작성할 때 일반적으로 다음과 같이 말합니다.

change_column :table_name, :column_name, :integer

그러나 PostgreSQL은 다음과 같이 불평합니다.

PG::DatatypeMismatch: ERROR:  column "column_name" cannot be cast automatically to type integer
HINT:  Specify a USING expression to perform the conversion.

"힌트"는 기본적으로 이러한 상황이 발생했는지 확인하고 데이터 변환 방법을 확인해야 함을 나타냅니다. 마이그레이션에서 다음과 같이 말하십시오.

change_column :table_name, :column_name, 'integer USING CAST(column_name AS integer)'

위의 내용은 다른 데이터베이스 어댑터에서 알고있는 내용과 유사합니다. 숫자가 아닌 데이터가있는 경우 결과가 예기치 않을 수 있습니다 (그러나 결국 정수로 변환하는 중임).


방금 change_column에주의해야 할 점을 하나 더 추가하고 싶었습니다. 돌이킬 수 없습니다. 이 작업을 뒤집을 수 있도록 마이그레이션에서 위아래로 사용하는 것이 좋습니다.
Mukesh Kumar Gupta

2
PG::InvalidTextRepresentation: ERROR: invalid input syntax for integer: ""오류가 발생
Shaig Khaligli

6

나는 같은 문제를 겪었다. 내가 변경하려고하는 열의 기본 문자열 값이 있다는 것을 깨달았습니다. 기본값을 제거하면 오류가 사라졌습니다. :)


이 열의 기존 인덱스도 문제가 될 수 있습니다. ALTER 전에 삭제하고 나중에 다시 작성해야합니다.
Envek

1

실수로 또는 정수와 텍스트 데이터를 혼합하지 않은 경우 먼저 업데이트 명령 아래에서 실행해야합니다 (위의 경우는 테이블 변경이 실패합니다).

UPDATE the_table SET col_name = replace(col_name, 'some_string', '');

3
regexp_replace(col_name, '[^0-9.]','','g')원치 않는 문자와 공백을 제거하려는 경우 와 같은 방법을 사용 하는 것이 좋습니다. 당신은 유지하려는 경우에는 좀 더 복잡한 뭔가가 필요 거라고 NaN하고 Inf10E42과학적 표기법을하지만.
Craig Ringer

1

개발 환경에서 작업 중이거나 프로덕션 환경에서 데이터를 백업하는 경우 먼저 DB 필드에서 데이터를 지우거나 값을 0으로 설정하십시오.

UPDATE table_mame SET field_name= 0;

그 후 아래 쿼리를 실행하고 쿼리를 성공적으로 실행 한 후 schemamigration으로 이동 한 후 마이그레이션 스크립트를 실행하십시오.

ALTER TABLE table_mame ALTER COLUMN field_name TYPE numeric(10,0) USING field_name::numeric;

나는 그것이 당신을 도울 것이라고 생각합니다.


1

나는 같은 문제가 있었다. 열의 기본값을 재설정하기 시작했습니다.

change_column :users, :column_name, :boolean, default: nil
change_column :users, :column_name, :integer, using: 'column_name::integer', default: 0, null: false
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.