CAST в Oracle SQL. Введение
CAST — функция приведения типов в Oracle SQL. Она явно преобразует выражение к заданному типу и (опционально) длине/точности.
Используется для согласования типов в операциях и объединениях, корректного сравнения и сортировки, а также для форматирования при работе с датами, временем, интервалами и JSON.
Где используют
- Согласование колонок: унификация типов в UNION/JOIN/CASE.
- Даты/время: преобразование строк в
DATE/TIMESTAMPи наоборот. - Числа: управление точностью (
NUMBER(p,s)), перевод в текст. - Интервалы: создание значений типа
INTERVALиз чисел/строк. - JSON/XML: извлечение и приведение к скалярным типам.
Синтаксис
CAST ( expression AS datatype )
-- Примеры типов:
-- NUMBER(10,2), VARCHAR2(100), CHAR(10), DATE,
-- TIMESTAMP [(n)] [WITH TIME ZONE],
-- INTERVAL YEAR TO MONTH, INTERVAL DAY TO SECOND (n),
-- BINARY_FLOAT / BINARY_DOUBLE,
-- XMLTYPE, CLOB, BLOB,
-- CAST(MULTISET(subquery) AS collection_type)
- При преобразовании строк к датам/времени лучше использовать
TO_DATE/TO_TIMESTAMPс маской формата. - Для коллекций доступен синтаксис
CAST(MULTISET(...))в сочетании с пользовательскими типами.
100 примеров
1. Строка → DATE с надёжным форматом (через TO_DATE)
SELECT CAST(TO_DATE('2025-09-13','YYYY-MM-DD') AS DATE) AS dt
FROM dual;2. Строка → TIMESTAMP
SELECT CAST(TO_TIMESTAMP('2025-09-13 12:34:56','YYYY-MM-DD HH24:MI:SS') AS TIMESTAMP) AS ts
FROM dual;3. Число → VARCHAR2 для конкатенации
SELECT CAST(amount AS VARCHAR2(20)) || ' EUR' AS label
FROM payments;4. Вещественное с ограниченной точностью
SELECT CAST(avg_value AS NUMBER(10,2)) AS avg_2d
FROM metrics;5. Перевод в BINARY_DOUBLE для расчётов
SELECT CAST(value AS BINARY_DOUBLE) * 1.0 AS v
FROM t;6. Согласовать типы в UNION (число↔строка)
SELECT CAST(id AS VARCHAR2(20)) AS key FROM customers
UNION ALL
SELECT order_no FROM orders;7. Даты в тексте для сортировки (год‑месяц)
SELECT CAST(TO_CHAR(order_date,'YYYYMM') AS NUMBER) AS ym, COUNT(*) cnt
FROM orders
GROUP BY CAST(TO_CHAR(order_date,'YYYYMM') AS NUMBER)
ORDER BY ym;8. Секунды → INTERVAL DAY TO SECOND
SELECT CAST(NUMTODSINTERVAL(duration_sec,'SECOND') AS INTERVAL DAY TO SECOND) AS dur
FROM runs;9. Месяцы → INTERVAL YEAR TO MONTH
SELECT CAST(NUMTOYMINTERVAL(months_cnt,'MONTH') AS INTERVAL YEAR TO MONTH) AS ym
FROM plans;10. TIMESTAMP WITH TIME ZONE → локальный TIMESTAMP
SELECT CAST(ts_tz AT LOCAL AS TIMESTAMP) AS local_ts
FROM tz_events;11. JSON‑скаляр к NUMBER
SELECT CAST(JSON_VALUE(payload,'$.amount') AS NUMBER(12,2)) AS amt
FROM logs;12. JSON‑скаляр к DATE (через TO_DATE)
SELECT CAST(TO_DATE(JSON_VALUE(payload,'$.when'),'YYYY-MM-DD') AS DATE) AS d
FROM logs;13. Согласование типов в CASE
SELECT CASE WHEN is_vip=1 THEN CAST(discount AS NUMBER(5,2))
ELSE CAST(0 AS NUMBER(5,2)) END AS disc
FROM customers;14. Приведение к CHAR фиксированной длины
SELECT CAST(code AS CHAR(5)) AS code5
FROM dict;15. NVARCHAR2 → VARCHAR2
SELECT CAST(name_n AS VARCHAR2(100)) AS name
FROM i18n;16. NUMBER → DATE по ЭПОХЕ (секунды → дата)
SELECT CAST(DATE '1970-01-01' + (epoch_sec/86400) AS DATE) AS d
FROM events;17. DATE → CHAR для экспорта
SELECT CAST(TO_CHAR(d,'YYYY-MM-DD') AS VARCHAR2(10)) AS dstr
FROM calendar;18. TIMESTAMP → DATE (обрезка времени)
SELECT CAST(created_at AS DATE) AS created_date
FROM orders;SELECT CAST(order_date AS TIMESTAMP) AS ts
FROM orders;20. Согласовать типы в JOIN по ключу (строка↔число)
SELECT o.order_id, c.customer_id
FROM orders o
JOIN customers c
ON CAST(o.customer_id AS VARCHAR2(20)) = c.customer_code;Еще 20 примеров.
21. Нормализация булевого признака
SELECT CASE WHEN is_active=1 THEN 'Y' ELSE 'N' END AS flag
FROM users;22. Согласование типов в агрегатах
SELECT CAST(AVG(CAST(amount AS NUMBER(12,2))) AS NUMBER(12,2)) AS avg_amt
FROM payments;23. ROUND/округление для отчёта
SELECT CAST(ROUND(revenue, 2) AS NUMBER(12,2)) AS rev2
FROM finance;24. Приведение к тексту перед LIKE
SELECT *
FROM t
WHERE CAST(id AS VARCHAR2(30)) LIKE '2025%';25. TIMESTAMP WITH TZ → строка ISO
SELECT CAST(TO_CHAR(ts_tz, 'YYYY-MM-DD"T"HH24:MI:SS.FF TZH:TZM') AS VARCHAR2(35)) AS iso
FROM tz_events;26. INTERVAL → секунды (через EXTRACT)
SELECT EXTRACT(DAY FROM dur)*86400
+ EXTRACT(HOUR FROM dur)*3600
+ EXTRACT(MINUTE FROM dur)*60
+ EXTRACT(SECOND FROM dur) AS seconds
FROM (
SELECT CAST(NUMTODSINTERVAL(90,'MINUTE') AS INTERVAL DAY TO SECOND) AS dur FROM dual
);27. Колонка «число‑в‑строке» → NUMBER
SELECT CAST(txt_num AS NUMBER(10)) AS n
FROM src;28. Число → BINARY_FLOAT для экономии
SELECT CAST(measure AS BINARY_FLOAT) AS mf
FROM metrics;29. К началу месяца через строковое представление
SELECT CAST(TO_DATE(TO_CHAR(d,'YYYY-MM')||'-01','YYYY-MM-DD') AS DATE) AS month_start
FROM dates;30. Усечение строк до 10 символов
SELECT CAST(long_str AS VARCHAR2(10)) AS short_str
FROM t;31. Текстовый большой объект (CLOB) для JSON
SELECT CAST(json_text AS CLOB) AS payload
FROM raw_json;32. Бинарные данные (BLOB) — демонстрация
SELECT CAST(raw_bytes AS BLOB) AS bin
FROM incoming;33. Текст → XMLTYPE
SELECT CAST(xml_text AS XMLTYPE) AS x
FROM src_xml;34. XMLTYPE → текст
SELECT CAST(x AS VARCHAR2(4000)) AS xml_str
FROM xml_docs;35. Точная арифметика перед делением
SELECT CAST(numerator AS NUMBER(18,8)) / CAST(denominator AS NUMBER(18,8)) AS ratio
FROM t;36. PIVOT — подготовка типов
SELECT * FROM (
SELECT product_id, TO_CHAR(sale_date,'YYYY') AS y, amount FROM sales
) PIVOT ( SUM(amount) FOR y IN ('2023','2024','2025') );37. NULL нужного типа для UNION
SELECT id, CAST(NULL AS DATE) AS closed_at FROM a
UNION ALL
SELECT id, closed_at FROM b;38. Годы/месяцы как INTERVAL Y2M
SELECT CAST(NUMTOYMINTERVAL(3,'YEAR') AS INTERVAL YEAR TO MONTH) AS yint
FROM dual;39. Часы/минуты/секунды как INTERVAL D2S
SELECT CAST(NUMTODSINTERVAL(48,'HOUR') AS INTERVAL DAY TO SECOND) AS dint
FROM dual;40. Единый тип в CASE
SELECT CASE status
WHEN 'OK' THEN CAST(1 AS NUMBER)
ELSE CAST(0 AS NUMBER) END AS is_ok
FROM t;Еще 20 примеров.
41. JSON_VALUE → VARCHAR2(10)
SELECT CAST(JSON_VALUE(j,'$.code') AS VARCHAR2(10)) AS code
FROM jtab;42. Сумма строковых чисел
SELECT SUM(CAST(txt_val AS NUMBER)) AS total
FROM src_numbers;43. IN с подзапросом и выравниванием
SELECT *
FROM orders
WHERE customer_id IN (
SELECT CAST(code AS NUMBER) FROM customers_src
);44. TIMESTAMP(3) для согласования
SELECT CAST(ts AS TIMESTAMP(3)) AS ts3
FROM logs;45. TZ → TIMESTAMP(6) без TZ
SELECT CAST(ts_tz AS TIMESTAMP(6)) AS ts6
FROM tz_events;46. INTERVAL сек. дробная точность
SELECT CAST(NUMTODSINTERVAL(1.234567,'SECOND') AS INTERVAL DAY TO SECOND(3)) AS s3
FROM dual;47. Сравнение дат — привести обе стороны
SELECT *
FROM events
WHERE CAST(event_date AS DATE) = CAST(TO_DATE(:d,'YYYY-MM-DD') AS DATE);48. Геоданные как текст
SELECT CAST(wkt AS CLOB) AS wkt_text
FROM geo;49. Количество как текст для UI
SELECT product_id, CAST(qty AS VARCHAR2(10)) AS qty_txt
FROM items;50. NVARCHAR2/NCHAR → VARCHAR2
SELECT CAST(nname AS VARCHAR2(100)) AS name
FROM people_n;51. Форматированный вывод суммы
SELECT CAST(TO_CHAR(amount,'FM999G999D00','NLS_NUMERIC_CHARACTERS=,.') AS VARCHAR2(20)) AS amt
FROM payments;52. Фиксированная ширина кода (CHAR)
SELECT CAST(code AS CHAR(8)) AS code8
FROM dict;53. Ключ для сортировки чисел‑как‑строки
SELECT txt_num
FROM t
ORDER BY CAST(txt_num AS NUMBER);54. Временная метка без часового пояса
SELECT CAST(created_at AS TIMESTAMP) AS ts
FROM events;55. Часовой пояс → локальная дата
SELECT CAST((ts_tz AT LOCAL) AS DATE) AS local_date
FROM tz_events;56. Число как CHAR(10) для экспорта
SELECT CAST(id AS CHAR(10)) AS id_char
FROM users;57. Часы и минуты как строка
SELECT CAST(TO_CHAR(ts,'HH24:MI') AS VARCHAR2(5)) AS hhmi
FROM schedule;58. Аналитика — согласовать точность
SELECT emp_id,
AVG(CAST(salary AS NUMBER(12,2))) OVER (PARTITION BY dept_id) AS avg_sal
FROM employees;59. CSV из чисел для отчёта
SELECT CAST(TO_CHAR(a)||','||TO_CHAR(b)||','||TO_CHAR(c) AS VARCHAR2(100)) AS csv
FROM triples;60. Дробную часть отбросить (целое)
SELECT CAST(amount AS NUMBER(12,0)) AS amount_int
FROM payments;Еще 20 примеров.
61. UNION с выравниванием типов
SELECT id, name FROM users
UNION ALL
SELECT id, CAST(NULL AS VARCHAR2(100)) FROM archive;62. Выходной тип для SUM … OVER
SELECT CAST(SUM(val) OVER (PARTITION BY grp) AS NUMBER(18,2)) AS s
FROM t;63. Дата как «начало дня»
SELECT CAST(TRUNC(ts) AS DATE) AS day_start
FROM logs;64. TIMESTAMP(0) — без долей
SELECT CAST(ts AS TIMESTAMP(0)) AS ts0
FROM logs;65. INTERVAL из минут с точностью
SELECT CAST(NUMTODSINTERVAL(15.5,'MINUTE') AS INTERVAL DAY TO SECOND(1)) AS m
FROM dual;66. Жёсткий тип параметра во VIEW
CREATE OR REPLACE VIEW v AS
SELECT CAST(:p AS NUMBER(10)) AS p FROM dual;67. Ключ для JOIN после нормализации
SELECT *
FROM a JOIN b
ON CAST(a.key AS NUMBER) = b.key_num;68. Текстовый идентификатор в верхнем регистре
SELECT UPPER(CAST(id AS VARCHAR2(20))) AS id_txt
FROM t;69. BIN → HEX строковое представление
SELECT CAST(RAWTOHEX(raw_col) AS VARCHAR2(64)) AS hex
FROM bin;70. Разные шкалы точности
SELECT CAST(n AS NUMBER(9,4)) AS n4, CAST(n AS NUMBER(9,2)) AS n2
FROM t;71. Дата из JSON и сравнение
SELECT *
FROM j
WHERE CAST(TO_DATE(JSON_VALUE(jcol,'$.d'),'YYYY-MM-DD') AS DATE) >= DATE '2025-01-01';72. TZ → строка UTC
SELECT CAST(TO_CHAR((ts_tz AT TIME ZONE 'UTC'),'YYYY-MM-DD"T"HH24:MI:SS"Z"') AS VARCHAR2(25)) AS utc_iso
FROM tz_events;73. INSERT SELECT с выравниванием
INSERT INTO dst(id, created_at)
SELECT CAST(src_id AS NUMBER), CAST(created AS DATE)
FROM src;74. Цены с фиксированной точностью
SELECT CAST(price AS NUMBER(12,4)) AS price4
FROM goods;75. Внешние ключи как NUMBER
SELECT *
FROM ext e
JOIN int i ON i.id = CAST(e.ext_id AS NUMBER);76. Текст → NUMBER после валидации
SELECT id, CASE WHEN REGEXP_LIKE(txt, '^\d+$') THEN CAST(txt AS NUMBER) END AS maybe_num
FROM src;77. Год и месяц из текстовой даты
SELECT EXTRACT(YEAR FROM CAST(TO_DATE(d,'YYYY-MM-DD') AS DATE)) AS y,
EXTRACT(MONTH FROM CAST(TO_DATE(d,'YYYY-MM-DD') AS DATE)) AS m
FROM dates_txt;78. TZ → локальная дата для отчёта
SELECT CAST((ts_tz AT LOCAL) AS DATE) AS d
FROM tz_events;79. Общий тип в DECODE
SELECT DECODE(sign, '+', CAST(1 AS NUMBER), '-', CAST(-1 AS NUMBER), CAST(0 AS NUMBER)) AS sgn
FROM x;80. TRUNC и целое число
SELECT CAST(TRUNC(value) AS NUMBER(10,0)) AS v_int
FROM t;Еще 20 примеров.
81. NULL‑значение нужного типа в LEFTJOIN
SELECT a.id, b.attr
FROM a LEFT JOIN b ON a.id = b.id AND b.attr <> CAST(NULL AS VARCHAR2(1));82. Временная метка с долями секунды
SELECT CAST(SYSTIMESTAMP AS TIMESTAMP(6)) AS ts6
FROM dual;83. INTERVAL из составной строки
SELECT CAST(INTERVAL '02:03:04' HOUR TO SECOND AS INTERVAL DAY TO SECOND) AS dts
FROM dual;84. Код фиксированной ширины для сортировки
SELECT CAST(code AS CHAR(6)) AS code6
FROM codes
ORDER BY code6;85. Материализованное представление — выравнивание
CREATE MATERIALIZED VIEW mv AS
SELECT CAST(id AS NUMBER) AS id, CAST(created AS DATE) AS created
FROM src;86. Сумма как текст для UI
SELECT CAST(TO_CHAR(total,'999G999D00') AS VARCHAR2(15)) AS total_txt
FROM invoices;87. Отбрасываем копейки до двух знаков
SELECT CAST(FLOOR(amount*100)/100 AS NUMBER(12,2)) AS amt2
FROM t;88. WHERE с параметром‑меткой времени
SELECT *
FROM logs
WHERE ts >= CAST(:from_ts AS TIMESTAMP);89. Часовой пояс → локальная метка
SELECT CAST((ts_tz AT LOCAL) AS TIMESTAMP) AS ts_local
FROM tz_events;90. JSON число как NUMBER(5,0)
SELECT CAST(JSON_VALUE(j,'$.cnt') AS NUMBER(5,0)) AS cnt
FROM jtab;91. Коды справочника как CHAR(3)
SELECT CAST(code AS CHAR(3)) AS code3
FROM dict;92. Минуты → INTERVAL D2S
SELECT CAST(NUMTODSINTERVAL(minutes,'MINUTE') AS INTERVAL DAY TO SECOND) AS iv
FROM x;93. Дата к полуночи
SELECT CAST(TRUNC(d) AS DATE) AS d0
FROM calendar;94. Нормализация «числа в строке» для BETWEEN
SELECT *
FROM t
WHERE CAST(txt AS NUMBER) BETWEEN 10 AND 20;95. Унификация коллации для строк
SELECT CAST(name AS VARCHAR2(200)) AS nm
FROM people;96. TIMESTAMP(9) — максимальная точность
SELECT CAST(ts AS TIMESTAMP(9)) AS ts9
FROM t;97. INTERVAL с миллисекундами
SELECT CAST(NUMTODSINTERVAL(1.234,'SECOND') AS INTERVAL DAY TO SECOND(3)) AS s3
FROM dual;98. Строка → DATE с надёжным форматом (через TO_DATE)
SELECT CAST(TO_DATE('2025-09-13','YYYY-MM-DD') AS DATE) AS dt
FROM dual;99. Строка → TIMESTAMP
SELECT CAST(TO_TIMESTAMP('2025-09-13 12:34:56','YYYY-MM-DD HH24:MI:SS') AS TIMESTAMP) AS ts
FROM dual;100. Число → VARCHAR2 для конкатенации
SELECT CAST(amount AS VARCHAR2(20)) || ' EUR' AS label
FROM payments;Частые ошибки и подводные камни
- Неоднозначные строки дат.
CAST('2025-09-13' AS DATE)зависит от NLS‑параметров. Для надёжности используйтеTO_DATEс форматом. - Обрезка/округление. Приведение в меньшую длину/точность может обрезать текст или округлить число.
- NULL‑поведение.
CAST(NULL AS ...)вернётNULL— учитывайте при выраженияхCOALESCE/NVL. - Сравнение разных типов. Явно приводите стороны сравнения, чтобы не полагаться на неявные преобразования.
Альтернативы
TO_CHAR / TO_DATE / TO_NUMBER— когда нужна явная маска формата.CONVERT— для межнациональных кодировок (NLS).- Пользовательские типы и конструкторы — для сложных структур (коллекции/объекты).
Заключение
CAST делает преобразования типов явными и предсказуемыми. Применяйте его для согласования схем, объединений и вычислений, а для дат и строк с форматом используйте специализированные функции семейства TO_*.
Документация
Oracle SQL Language Reference — CAST
Следующая статья:
SELECT в Oracle SQL — 100 простых примеров для старта