Varchar alanının türünü tamsayı olarak değiştirin: “tamsayı tipine otomatik olarak kullanılamaz”


154

Küçük bir tablo var ve belirli bir alan " karakter değişen " türünü içerir . " Tamsayı " olarak değiştirmek çalışıyorum ama döküm mümkün olmayan bir hata veriyor.

Bunun bir yolu var mı ya da ben sadece başka bir tablo oluşturmak ve bir sorgu kullanarak içine kayıtları getirmek gerekir.

Alan yalnızca tamsayı değerler içerir.


Hangi ALTER TABLE'ı denediniz ve belirli hata mesajı neydi?
mu çok kısa

@muistooshort phppgadmin'den alter kullanmayı denedim. Sütunu seçti ve yeni alan türünü girmeye çalıştı. Hata:SQL error: ERROR: column "MID" cannot be cast to type integer
itsols

3
Birincisi tabloyu yedeklemektir. Ardından, aynı tabloda tamsayı türünde başka bir sütun (diyelim field2) oluşturabilirsiniz. Field1 öğesinin field2 içine cast to integer değerini seçin. Ardından sütunu yeniden adlandırın.
Igor

@Igor ama yeni sütun tablonun sonuna düşüyor değil mi? Aynı pozisyonda olamaz mıyım?
itsols

2
@itsols Sütun pozisyonlarını önemsemek genellikle iffy uygulama tasarımının bir işaretidir. Neredeyse her zaman SELECTsütun sıra sıralarına dayanmadan, açıkça adlandırılmış sütunlar ve listeler kullanmak istersiniz . Bununla birlikte, cevaplarda verilen yaklaşım sütun konumunu koruyacaktır.
Craig Ringer

Yanıtlar:


264

Örtük (otomatik) dökme yoktur textya varcharkadar integer(bir geçemez sizi yani varcharbekliyor bir işleve integerveya atamak varcharbir alanını integerkullanarak açık döküm belirtmelisiniz, böylece biri) ALTER TABLE ... ALTER COLUMN ... TYPE. .. KULLANIMI :

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

Metin alanlarınızda boşluk olabileceğini unutmayın; bu durumda şunları kullanın:

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

dönüştürmeden önce beyaz boşluk şerit.

Bu komut, komut çalıştırıldıysa bir hata mesajından açıkça anlaşıldı psql, ancak PgAdmin-III size tam hatayı göstermiyor olabilir. psqlPostgreSQL 9.2'de test edersem ne olur :

=> 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        

USINGBağlantıyı eklediğiniz için teşekkürler muistooshort .

Ayrıca bu ilgili soruya bakın ; Rails göçleri ile ilgili, ancak bunun altında yatan neden aynı ve cevap geçerli.

Hata devam ederse, sütun değerleri ile ilgili olmayabilir, ancak bu sütun veya sütun varsayılan değerleri üzerindeki dizinler yazım hatası yapılamayabilir. Endekslerin ALTER COLUMN öncesi bırakılması ve sonra yeniden oluşturulması gerekir. Varsayılan değerler uygun şekilde değiştirilmelidir.


Zaman ayırdığınız için teşekkürler. Ama bu işe yaramıyor gibi görünmüyorum. Ben ALTER hattını denedim ve bana bir hata veriyor "kullanma yakınında sözdizimi hatası"
itsols

Benim ifadem: ALTER TABLE "tblMenus" ALTER COLUMN "MID" KULLANIM (trim ("MID") :: integer);
itsols

1
@itsols Tamamen benim hatam; Yorumunu gördüğüm gibi düzelttim. Bkz. Revize. Demo kodunda haklıydı, başlangıçtaki jenerik örnek değil.
Craig Ringer

Milyonlarca kez teşekkürler! Bu cevap bana çok fazla sıkıntı ve zaman kazandırdı. Acaba neden daha phppgadmin veya pgadmin bir özellik olarak bu var ...
itsols

@itsols Çekirdek ekibin çoğu PgAdmin ile ilgilenmiyor ve çok azı bunu kullanıyor. Bazı can sıkıcı kullanılabilirlik siğilleri ve işlevsellik sınırlamaları vardır. Bu birçoğundan sadece biri. Birkaç uzman PgAdmin kullandığından, onları rahatsız edecek şeyleri düzeltmek için motive değiller. Kendim kullanmıyorum, çünkü psqlçok daha hızlı ve kolay buluyorum . Bir süre önce yedekleme ve geri yükleme konusunda PgAdmin kullanılabilirliği hakkında biraz rant yazdım: blog.ringerc.id.au/2012/05/…
Craig Ringer

71

bu benim için çalıştı.

varchar sütununu int olarak değiştir

change_column :table_name, :column_name, :integer

var:

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

chnged

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

Bu alıştırmayı verilerle denediniz mi ve verileriniz sağlam mı?
itsols

3
sütunda ne olduğu bir tamsayı olduğu sürece, evet
bibangamba

Benimle çalışmıyor. Ruby 2.2.3 raylı 4.2.3 kullanıyorum
Thinh D. Bui

@ ThinhD.Bui - Benim için çalışıyor, 2.3.0, raylar 4.2.6
Philip

1
Varsayılanlara da dikkat edin
Francisco Quintero

17

Bunu şöyle yapabilirsiniz:

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

veya şunu deneyin:

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

Bu konu hakkında daha fazla bilgi edinmek istiyorsanız bu makaleyi okuyun: https://kolosek.com/rails-change-database-column


8

Bunu deneyin, kesinlikle işe yarayacak.

Bir dize sütununu genellikle söyleyeceğiniz bir tam sayıya dönüştürmek için Rails taşıma işlemlerini yazarken:

change_column :table_name, :column_name, :integer

Ancak, PostgreSQL şikayet edecek:

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

"İpucu" temelde bunun olmasını istediğinizi ve verilerin nasıl dönüştürüleceğini onaylamanız gerektiğini söyler. Göçünüzde şunu söyleyin:

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

Yukarıdakiler diğer veritabanı adaptörlerinden bildiklerinizi taklit edecektir. Sayısal olmayan verileriniz varsa, sonuçlar beklenmedik olabilir (ancak sonuçta bir tam sayıya dönüştürüyorsunuz).


Sadece bir nokta daha eklemek istedim, change_column ile dikkatli olun. geri döndürülemez. Bunu geri dönüşümlü hale getirmek için geçişte yukarı ve aşağı kullanmanızı öneririm.
Mukesh Kumar Gupta

2
PG::InvalidTextRepresentation: ERROR: invalid input syntax for integer: ""hatası olur
Shaig Khaligli

6

Ben de aynı problemi yaşadım. Ben değiştirmeye çalıştığım sütun için varsayılan bir dize değeri olduğunu fark daha. Varsayılan değerin kaldırılması hatayı ortadan kaldırdı :)


Bu sütundaki mevcut dizinler de sorun olabilir. ALTER'den önce bırakılmaları ve sonra yeniden yaratılması gerekir.
Envek

1

Yanlışlıkla metin verileriyle tamsayıları karıştırdıysanız veya karıştırmadıysanız, önce güncelleme komutunun altında yürütmelisiniz (yukarıdaki değişiklik tablosu başarısız olursa):

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

3
regexp_replace(col_name, '[^0-9.]','','g')İstenmeyen karakterleri ve boşlukları soymaya çalışıyorsanız böyle bir şeyle daha iyi olursunuz. Eğer korumak istiyorsanız biraz daha sofistike bir şey gerekiyordu NaNve Infve 10E42bilimsel gösterim olsa.
Craig Ringer

1

Geliştirme ortamı üzerinde çalışıyorsanız (veya üretim ortamı için üzerinde çalışıyorsanız) önce verilerinizi DB alanından temizleyin veya değeri 0 olarak ayarlayın.

UPDATE table_mame SET field_name= 0;

Bundan sonra aşağıdaki sorguyu çalıştırmak ve sonra başarıyla, şemamigration için çalıştırın ve bundan sonra taşıma komut dosyasını çalıştırın.

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

Sanırım sana yardımcı olacak.


1

Aynı sorunu yaşadım. Sütunun varsayılanını sıfırlamaya başladım.

change_column :users, :column_name, :boolean, default: nil
change_column :users, :column_name, :integer, using: 'column_name::integer', default: 0, null: false
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.