chuỗi typecast thành số nguyên - Postgres


123

Tôi đang nhập dữ liệu từ một bảng có nguồn cấp dữ liệu thô trong Varchar, tôi cần nhập một cột trong varchar vào một cột chuỗi. Tôi đã cố gắng sử dụng <column_name>::integercũng như to_number(<column_name>,'9999999')nhưng tôi nhận lỗi, vì có một vài lĩnh vực có sản phẩm nào, tôi cần phải khôi phục lại theo trống hoặc null vào bảng mới.

Vui lòng cho tôi biết nếu có chức năng tương tự.


5
Bạn có thể cho chúng tôi thấy thông báo lỗi không? Điều đó sẽ hữu ích
Frank Heikens

Câu trả lời:


126

Đoán hoang dã: Nếu giá trị của bạn là một chuỗi trống, bạn có thể sử dụng NULLIF để thay thế nó cho một NULL:

SELECT
    NULLIF(your_value, '')::int

56

Bạn thậm chí có thể đi xa hơn và hạn chế đối với trường liên kết này, chẳng hạn như: -

SELECT CAST(coalesce(<column>, '0') AS integer) as new_field
from <table>
where CAST(coalesce(<column>, '0') AS integer) >= 10; 

28

Nếu bạn cần coi các cột trống là NULLs, hãy thử cách này:

SELECT CAST(nullif(<column>, '') AS integer);

Mặt khác, nếu bạn có NULLcác giá trị cần tránh, hãy thử:

SELECT CAST(coalesce(<column>, '0') AS integer);

Tôi đồng ý, thông báo lỗi sẽ giúp ích rất nhiều.


25

Cách duy nhất tôi thành công để không gặp lỗi do NULL, hoặc các ký tự đặc biệt hoặc chuỗi trống là làm như sau:

SELECT REGEXP_REPLACE(COALESCE(<column>::character varying, '0'), '[^0-9]*' ,'0')::integer FROM table

2
Đối với tôi (9.6.2) đây là điều duy nhất có hiệu quả, tất cả các câu trả lời khác đều thất bại.
Jasper de Vries

2
Bạn không thể thêm một WHERE <column> != NULL?
Matthieu

14

Tôi không thể bình luận (quá ít danh tiếng? Tôi khá mới) về bài đăng của Lukas.

Trên thiết lập PG của tôi to_number(NULL)không hoạt động, vì vậy giải pháp của tôi sẽ là:

SELECT CASE WHEN column = NULL THEN NULL ELSE column :: Integer END
FROM table

1
Điều này sẽ hiệu quả, nhưng nó phải tương đương chính xác với NULLIF()cách tiếp cận ít dài dòng hơn. Tiêu chuẩn thực sự định nghĩa NULLIF là một dạng của vị từ CASE.
kgrittn

13

Nếu giá trị chứa các ký tự không phải số, bạn có thể chuyển đổi giá trị thành số nguyên như sau:

SELECT CASE WHEN <column>~E'^\\d+$' THEN CAST (<column> AS INTEGER) ELSE 0 END FROM table;

Toán tử CASE kiểm tra <cột>, nếu nó khớp với mẫu số nguyên, nó sẽ chuyển tỷ lệ thành số nguyên, nếu không nó sẽ trả về 0


1

bạn có thể sử dụng truy vấn này

SUM(NULLIF(conversion_units, '')::numeric)

1

Vấn đề chung

Nhập kiểu ngây thơ ép bất kỳ chuỗi nào thành một số nguyên như vậy

SELECT ''::integer

Thường dẫn đến lỗi nổi tiếng:

Query failed: ERROR: invalid input syntax for integer: ""

Vấn đề

PostgreSQL không có chức năng được xác định trước để an toàn nhập kiểu truyền bất kỳ chuỗi nào thành số nguyên một .

Giải pháp

Tạo một hàm do người dùng định nghĩa lấy cảm hứng từ hàm intval () của PHP .

CREATE FUNCTION intval(character varying) RETURNS integer AS $$

SELECT
CASE
    WHEN length(btrim(regexp_replace($1, '[^0-9]', '','g')))>0 THEN btrim(regexp_replace($1, '[^0-9]', '','g'))::integer
    ELSE 0
END AS intval;

$$
LANGUAGE SQL
IMMUTABLE
RETURNS NULL ON NULL INPUT;

Sử dụng

/* Example 1 */
SELECT intval('9000');
-- output: 9000

/* Example 2 */
SELECT intval('9gag');
-- output: 9

/* Example 3 */
SELECT intval('the quick brown fox jumps over the lazy dog');
-- output: 0

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.