Cannot cast 5391736069126 to integer
CAST(... AS INTEGER) 에서 값이 32비트 정수 범위를 넘어 실패한 것이다.
| 타입 | 크기 | 범위 |
|---|---|---|
TINYINT |
8비트 | -128 ~ 127 |
SMALLINT |
16비트 | -32,768 ~ 32,767 |
INTEGER (INT) |
32비트 | -2,147,483,648 ~ 2,147,483,647 |
BIGINT |
64비트 | -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807 |
5391736069126 은 약 5.4조라 INTEGER 로 들어가지 않는다. 정수 리터럴 자체는 Trino 가 알아서 BIGINT 로 해석하므로, 캐스팅을 명시한 쪽이 범위를 좁힌 셈이다.
값의 성격에 맞는 타입으로 바꾼다.
SELECT CAST(col AS BIGINT) FROM t;
SELECT CAST('5391736069126' AS BIGINT);
범위를 넘는 행이 섞여 있고 그것만 걸러 내고 싶다면 TRY_CAST 를 쓴다. 실패한 행은 오류 대신 NULL 이 된다.
SELECT TRY_CAST(col AS INTEGER) AS v FROM t;
SELECT col FROM t WHERE TRY_CAST(col AS INTEGER) IS NULL; -- 범위를 넘는 값 목록
소수부가 있거나 정확한 자릿수가 필요하면 DECIMAL(p,s) 를 쓴다. 최대 정밀도는 38자리다.
SELECT CAST(col AS DECIMAL(20,0)) FROM t;
13자리 안팎의 큰 정수는 대개 둘 중 하나다.
BIGINT 나 VARCHAR 로 둔다.SELECT from_unixtime(5391736069126 / 1000); -- 밀리초 epoch 가정
SELECT from_unixtime(5391736069126 / 1e3); -- 소수까지 살리려면
from_unixtime 은 초 단위를 받으므로 밀리초 값을 그대로 넣으면 엉뚱한 연도가 나온다. 결과가 상식적인 연도인지 먼저 확인한다.
원본 스키마를 만들 때부터 정하는 편이 낫다. 시각·ID 컬럼에는 INTEGER 를 쓰지 않는다. JDBC 커넥터로 외부 DB 를 읽는 경우에는 커넥터의 타입 매핑을 확인한다. Oracle NUMBER 처럼 정밀도가 선언되지 않은 컬럼은 매핑 규칙에 따라 엉뚱하게 좁혀질 수 있다.