Cách thay đổi kiểu dữ liệu cột từ ký tự thành số trong PostgreSQL 8.4


136

Tôi đang sử dụng truy vấn sau đây:

ALTER TABLE presales ALTER COLUMN code TYPE numeric(10,0); 

để thay đổi kiểu dữ liệu của một cột từ character(20)sang numeric(10,0)nhưng tôi đang gặp lỗi:

cột "mã" không thể được đúc để nhập số

Câu trả lời:


240

Bạn có thể thử sử dụng USING:

USINGMệnh đề tùy chọn chỉ định cách tính giá trị cột mới từ giá trị cũ; nếu bị bỏ qua, chuyển đổi mặc định giống như một phép gán được chuyển từ kiểu dữ liệu cũ sang mới. Một USINGmệnh đề phải được cung cấp nếu không có hàm ẩn hoặc gán từ loại cũ sang loại mới.

Vì vậy, điều này có thể hoạt động (tùy thuộc vào dữ liệu của bạn):

alter table presales alter column code type numeric(10,0) using code::numeric;
-- Or if you prefer standard casting...
alter table presales alter column code type numeric(10,0) using cast(code as numeric);

Điều này sẽ thất bại nếu bạn có bất cứ thứ gì trong codeđó không thể chuyển thành số; nếu SỬ DỤNG thất bại, bạn sẽ phải dọn sạch dữ liệu không phải là số trước khi thay đổi loại cột.


cột này được sử dụng làm khóa ngoại trong bảng khác, tôi đoán tôi cũng sẽ phải thay đổi kiểu dữ liệu của nó?
user728630

2
@ user728630: Bạn sẽ phải bỏ FK, thay đổi cả hai cột và sau đó thêm FK trở lại. Bạn có một cơ sở dữ liệu thử nghiệm để chơi và sao lưu cơ sở dữ liệu sản xuất, phải không?
mu quá ngắn

tôi đã xóa ràng buộc khóa ngoại, thay đổi kiểu dữ liệu nhưng sau đó không thể thêm FK. Nhận được lỗi sau LRI: chèn hoặc cập nhật trên bảng "hóa đơn" vi phạm ràng buộc khóa ngoại "billing_presale_fk" CHI TIẾT: Khóa (sale, cpf_cnpj) = (4.05943560000101) không có trong bảng "bán trước".
user728630

2
@funwhilelost Đó là một loại diễn viên . Các tài liệu ALTER TABLE được liên kết bao gồm những gì bạn có thể sử dụng với SỬ DỤNG.
mu quá ngắn

3
@muistooshort Tôi thấy từ các tài liệu đó thực sự là một biểu thức. Điều đó có ý nghĩa hơn. Các loại diễn viên bắt tôi mất cảnh giác. Tôi đã kết thúc vớiTYPE varchar(255) USING (substring(formertextcolumn from 1 for 255))
funwhilelost

7

Nếu VARCHARcột của bạn chứa các chuỗi trống ( không giống NULLvới PostgreSQL như bạn có thể nhớ lại), bạn sẽ phải sử dụng một cái gì đó trong dòng sau đây để đặt mặc định:

ALTER TABLE presales ALTER COLUMN code TYPE NUMERIC(10,0)
            USING COALESCE(NULLIF(code, '')::NUMERIC, 0);

(tìm thấy với sự giúp đỡ của câu trả lời này )

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.