TO_DATE в Oracle SQL. Введение
TO_DATE — это одна из самых важных функций в Oracle SQL, которая используется для преобразования строковых значений в даты с заданным форматом. Она незаменима при загрузке данных, фильтрации по дате, проверке валидности и сравнении значений. Эта функция поддерживает огромное количество шаблонов для разбора строк: годы, месяцы, часы, временные зоны, а также специальные символы. В этой статье ты найдёшь 100 практических примеров использования TO_DATE.
🖋️ Синтаксис функции TO_DATE
TO_DATE('строка_даты', 'формат')
- Первый аргумент — строка, содержащая дату
- Второй аргумент — формат, указывающий структуру даты (например: ‘YYYY-MM-DD’)
Дополнительно можно использовать третий параметр для указания языка:
TO_DATE('01-JAN-2024', 'DD-MON-YYYY', 'NLS_DATE_LANGUAGE=ENGLISH')
🔄 Где используется TO_DATE в Oracle SQL
- Импорт строковых дат в таблицы
- Сравнение строковых значений с колонками типа DATE
- Построение отчётов и фильтрация по диапазонам дат
- Валидация пользовательского ввода
- Хранение временных данных в виде DATE
📊 Примеры использования TO_DATE в Oracle SQL (1–10 из 100)
- Преобразование ISO строки в дату:
SELECT TO_DATE('2024-08-31', 'YYYY-MM-DD') FROM dual;
- Использование с временем:
SELECT TO_DATE('2024-08-31 14:30:00', 'YYYY-MM-DD HH24:MI:SS') FROM dual;
- Установка даты через INSERT:
INSERT INTO events (event_date) VALUES (TO_DATE('01-09-2024', 'DD-MM-YYYY'));
- Сравнение дат в WHERE:
SELECT * FROM orders WHERE order_date >= TO_DATE('01-01-2023', 'DD-MM-YYYY');
- Фильтрация по диапазону:
SELECT * FROM sales WHERE sale_date BETWEEN TO_DATE('01-01-2023', 'DD-MM-YYYY') AND TO_DATE('31-12-2023', 'DD-MM-YYYY');
- С группировкой по году:
SELECT EXTRACT(YEAR FROM TO_DATE('2024-08-31', 'YYYY-MM-DD')) AS year FROM dual;
- Использование с NLS параметром:
SELECT TO_DATE('15-JUL-2024', 'DD-MON-YYYY', 'NLS_DATE_LANGUAGE=ENGLISH') FROM dual;
- TO_DATE в подзапросе:
SELECT * FROM employees
WHERE hire_date < (SELECT TO_DATE('01-01-2020', 'DD-MM-YYYY') FROM dual);
- Приведение с учетом времени:
SELECT TO_DATE('31.08.2024 09:15:00', 'DD.MM.YYYY HH24:MI:SS') FROM dual;
- Сравнение в BETWEEN с часами:
SELECT * FROM logs
WHERE log_time BETWEEN TO_DATE('31.08.2024 08:00:00', 'DD.MM.YYYY HH24:MI:SS')
AND TO_DATE('31.08.2024 17:00:00', 'DD.MM.YYYY HH24:MI:SS');
- Проверка даты рождения:
SELECT * FROM users WHERE birth_date = TO_DATE('1980-05-20', 'YYYY-MM-DD');
- Добавление даты из текстового поля:
UPDATE tasks SET due_date = TO_DATE(input_date_text, 'YYYY-MM-DD');
- TO_DATE в CASE:
SELECT CASE WHEN hire_date < TO_DATE('2020-01-01', 'YYYY-MM-DD') THEN 'Старый' ELSE 'Новый' END AS category FROM employees;
- Разбор даты с сокращённым годом:
SELECT TO_DATE('01-01-23', 'DD-MM-RR') FROM dual;
- Преобразование даты с полуднем:
SELECT TO_DATE('01-09-2024 12:00 PM', 'DD-MM-YYYY HH:MI AM') FROM dual;
- Использование с BETWEEN SYSDATE:
SELECT * FROM events WHERE event_date BETWEEN SYSDATE - 30 AND SYSDATE;
- Сравнение в аналитике:
SELECT first_name, hire_date,
RANK() OVER (ORDER BY TO_DATE(hire_date, 'YYYY-MM-DD')) AS rnk
FROM employees;
- TO_DATE с ISO 8601:
SELECT TO_DATE('2024-08-31T14:30:00', 'YYYY-MM-DD"T"HH24:MI:SS') FROM dual;
- Преобразование русского формата:
SELECT TO_DATE('31.12.2024', 'DD.MM.YYYY') FROM dual;
- TO_DATE с добавлением времени:
SELECT TO_DATE('01.01.2024 00:00', 'DD.MM.YYYY HH24:MI') FROM dual;
- Использование в INSERT ALL:
INSERT ALL INTO logs (created_at) VALUES (TO_DATE('2024-08-01 09:00:00', 'YYYY-MM-DD HH24:MI:SS'))
SELECT * FROM dual;
- TO_DATE в представлении:
CREATE VIEW v_logs AS SELECT TO_DATE(log_time_str, 'YYYY-MM-DD HH24:MI:SS') AS log_time FROM raw_logs;
- Использование в функции:
CREATE FUNCTION get_start_date RETURN DATE IS
BEGIN
RETURN TO_DATE('2023-01-01', 'YYYY-MM-DD');
END;
- Преобразование из числа в дату:
SELECT TO_DATE(TO_CHAR(20240831), 'YYYYMMDD') FROM dual;
- Сравнение даты в PARTITION:
SELECT * FROM sales PARTITION (p202408) WHERE sale_date = TO_DATE('2024-08-31', 'YYYY-MM-DD');
- Вывод в WITH:
WITH d AS (SELECT TO_DATE('2024-08-01', 'YYYY-MM-DD') AS dt FROM dual)
SELECT * FROM d;
- Использование в MERGE:
MERGE INTO events e
USING dual
ON (e.event_date = TO_DATE('2024-09-01', 'YYYY-MM-DD'))
WHEN MATCHED THEN UPDATE SET e.status = 'Обновлено';
- Использование с TRUNC:
SELECT TRUNC(TO_DATE('2024-08-31 18:45:22', 'YYYY-MM-DD HH24:MI:SS')) FROM dual;
- Сравнение строковой и реальной даты:
SELECT * FROM tasks WHERE deadline = TO_DATE('31-08-2024', 'DD-MM-YYYY');
- Сбор статистики по месяцу:
SELECT TO_CHAR(TO_DATE('2024-08-01', 'YYYY-MM-DD'), 'Month') AS month_name FROM dual;
- Использование в JSON_TABLE:
SELECT * FROM JSON_TABLE('[{"d":"2024-08-01"}]', '$[*]'
COLUMNS (d DATE PATH '$.d' FORMAT JSON_DATE WITH FORMAT 'YYYY-MM-DD'));
- Проверка TO_DATE в WHERE EXISTS:
SELECT * FROM dual WHERE EXISTS (
SELECT 1 FROM employees WHERE hire_date = TO_DATE('2020-05-10', 'YYYY-MM-DD')
);
- Использование с HAVING:
SELECT department_id, MAX(hire_date)
FROM employees
GROUP BY department_id
HAVING MAX(hire_date) > TO_DATE('2021-01-01', 'YYYY-MM-DD');
- Использование в аналитике с RANGE:
SELECT hire_date,
COUNT(*) OVER (ORDER BY TO_DATE(hire_date, 'YYYY-MM-DD') RANGE BETWEEN INTERVAL '30' DAY PRECEDING AND CURRENT ROW)
FROM employees;
- TO_DATE и NULLIF:
SELECT NULLIF(TO_DATE('2024-08-31', 'YYYY-MM-DD'), TO_DATE('2024-08-30', 'YYYY-MM-DD')) FROM dual;
- Сравнение с SYSDATE:
SELECT * FROM appointments WHERE TO_DATE('2024-08-31', 'YYYY-MM-DD') = TRUNC(SYSDATE);
- Сводная по кварталам:
SELECT TO_CHAR(TO_DATE(sale_date_str, 'YYYY-MM-DD'), 'Q') AS quarter FROM sales_data;
- Использование в TRIGGER:
CREATE OR REPLACE TRIGGER trg_set_date
BEFORE INSERT ON documents
FOR EACH ROW
BEGIN
:NEW.created_at := TO_DATE(:NEW.created_at_str, 'YYYY-MM-DD');
END;
- TO_DATE с учетом времени и зоны:
SELECT TO_DATE('2024-08-31 15:00:00 +0300', 'YYYY-MM-DD HH24:MI:SS TZH:TZM') FROM dual;
- Преобразование даты с месяцем текстом:
SELECT TO_DATE('01-August-2024', 'DD-Month-YYYY', 'NLS_DATE_LANGUAGE=ENGLISH') FROM dual;
- Использование в INSERT SELECT:
INSERT INTO archive_logs (archived_date)
SELECT TO_DATE(log_date_str, 'YYYY-MM-DD') FROM raw_logs;
- Установка даты в UPDATE:
UPDATE employees SET termination_date = TO_DATE('2024-09-15', 'YYYY-MM-DD') WHERE status = 'inactive';
- Проверка формата MM/DD/YYYY:
SELECT TO_DATE('08/31/2024', 'MM/DD/YYYY') FROM dual;
- Использование в UTL_FILE:
UTL_FILE.PUT_LINE(fh, TO_DATE('2024-08-01', 'YYYY-MM-DD'));
- Сравнение в MATERIALIZED VIEW:
CREATE MATERIALIZED VIEW recent_sales AS
SELECT * FROM sales WHERE sale_date >= TO_DATE('2024-01-01', 'YYYY-MM-DD');
- Использование в XMLTABLE:
SELECT * FROM XMLTABLE('/data/item'
PASSING XMLTYPE('<data><item date="2024-08-01"/></data>')
COLUMNS dt DATE PATH '@date' FORMAT DATE 'YYYY-MM-DD');
- Пример с TO_TIMESTAMP и TO_DATE:
SELECT TO_DATE(TO_CHAR(TO_TIMESTAMP('2024-08-31 18:00:00', 'YYYY-MM-DD HH24:MI:SS'), 'YYYY-MM-DD'), 'YYYY-MM-DD') FROM dual;
- TO_DATE с интервалами:
SELECT TO_DATE('2024-01-01', 'YYYY-MM-DD') + INTERVAL '15' DAY FROM dual;
- Проверка с GREATEST:
SELECT GREATEST(TO_DATE('2024-08-31', 'YYYY-MM-DD'), hire_date) FROM employees;
- Использование в PL/SQL IF:
BEGIN
IF SYSDATE > TO_DATE('2024-09-01', 'YYYY-MM-DD') THEN
DBMS_OUTPUT.PUT_LINE('Просрочено');
END IF;
END;И еще 50 примеров:
- Отображение только даты:
SELECT TO_CHAR(TO_DATE('2024-08-31', 'YYYY-MM-DD'), 'DD.MM.YYYY') FROM dual;
- Сравнение двух TO_DATE:
SELECT CASE WHEN TO_DATE('2024-09-01', 'YYYY-MM-DD') > TO_DATE('2024-08-31', 'YYYY-MM-DD') THEN 'OK' ELSE 'ERROR' END FROM dual;
- TO_DATE и преобразование CURSOR:
OPEN c FOR SELECT * FROM logs WHERE log_time >= TO_DATE('2024-08-01', 'YYYY-MM-DD');
- Поддержка с форматами ISO с пробелом:
SELECT TO_DATE('2024-08-31 17:30', 'YYYY-MM-DD HH24:MI') FROM dual;
- WITH FORMAT в JSON_TABLE:
SELECT * FROM JSON_TABLE('[{"d":"2024-08-31"}]', '$[*]'
COLUMNS (d DATE PATH '$.d' FORMAT DATE 'YYYY-MM-DD'));
- Использование в PIVOT:
SELECT * FROM (
SELECT emp_id, hire_date FROM employees
) PIVOT (COUNT(*) FOR hire_date IN (TO_DATE('2024-08-01', 'YYYY-MM-DD') AS aug));
- Использование в DATE_DIFF:
SELECT TO_DATE('2024-09-10', 'YYYY-MM-DD') - TO_DATE('2024-08-31', 'YYYY-MM-DD') AS days_diff FROM dual;
- Проверка на праздничные даты:
SELECT * FROM workdays WHERE work_date = TO_DATE('2024-12-31', 'YYYY-MM-DD');
- Преобразование для статистики по неделям:
SELECT TO_CHAR(TO_DATE('2024-08-31', 'YYYY-MM-DD'), 'IW') AS week_num FROM dual;
- Преобразование текстовой даты в процедуре:
PROCEDURE log_event(p_date_str VARCHAR2) IS
BEGIN
INSERT INTO logs(event_date) VALUES (TO_DATE(p_date_str, 'YYYY-MM-DD'));
END;
- TO_DATE в проверке диапазона по переменной:
SELECT * FROM meetings WHERE meeting_date BETWEEN TO_DATE(:start_date, 'YYYY-MM-DD') AND TO_DATE(:end_date, 'YYYY-MM-DD');
- Вставка значения TO_DATE через SELECT:
INSERT INTO archive SELECT id, TO_DATE(log_str, 'YYYY-MM-DD') FROM raw_table;
- TO_DATE с именем месяца в другом языке:
SELECT TO_DATE('10-Декабрь-2024', 'DD-Month-YYYY', 'NLS_DATE_LANGUAGE=RUSSIAN') FROM dual;
- Использование в фильтрации внешнего ключа:
SELECT * FROM payments WHERE payment_date >= TO_DATE('2024-07-01', 'YYYY-MM-DD');
- TO_DATE + INTERVAL при сравнении:
SELECT * FROM tasks WHERE deadline < TO_DATE('2024-09-01', 'YYYY-MM-DD') + INTERVAL '7' DAY;
- Сравнение строк и даты:
SELECT * FROM sessions WHERE TO_DATE(session_date_text, 'YYYY-MM-DD') = TRUNC(SYSDATE);
- Объединение TO_DATE с CAST:
SELECT * FROM deliveries WHERE CAST(delivery_str AS DATE) = TO_DATE('2024-08-31', 'YYYY-MM-DD');
- Использование в аналитической функции:
SELECT employee_id, hire_date,
RANK() OVER (ORDER BY TO_DATE(hire_date, 'YYYY-MM-DD')) AS rnk
FROM employees;
- Формат с AM/PM:
SELECT TO_DATE('08-31-2024 03:45 PM', 'MM-DD-YYYY HH:MI AM') FROM dual;
- Проверка TO_DATE и CURRENT_DATE:
SELECT * FROM dual WHERE TO_DATE('2024-08-31', 'YYYY-MM-DD') = TRUNC(CURRENT_DATE);
- Сравнение TO_DATE и TO_TIMESTAMP:
SELECT CASE WHEN TO_DATE('2024-08-31', 'YYYY-MM-DD') = CAST(TO_TIMESTAMP('2024-08-31 00:00:00', 'YYYY-MM-DD HH24:MI:SS') AS DATE) THEN 'Match' ELSE 'No match' END FROM dual;
- Использование в логике CASE:
SELECT CASE WHEN start_date < TO_DATE('2024-08-01', 'YYYY-MM-DD') THEN 'Early' ELSE 'Recent' END FROM projects;
- Вложенный TO_DATE в JOIN:
SELECT * FROM logs l JOIN workdays w ON TO_DATE(l.log_str, 'YYYY-MM-DD') = w.work_date;
- Сравнение с функцией TRUNC:
SELECT * FROM orders WHERE TRUNC(order_date) = TO_DATE('2024-08-30', 'YYYY-MM-DD');
- Фильтр с BETWEEN TO_DATE и SYSDATE:
SELECT * FROM actions WHERE action_date BETWEEN TO_DATE('2024-07-01', 'YYYY-MM-DD') AND SYSDATE;
- Формат ‘YYYYMMDD’ без разделителей:
SELECT TO_DATE('20240831', 'YYYYMMDD') FROM dual;
- Использование в MATERIALIZED VIEW LOG:
CREATE MATERIALIZED VIEW LOG ON events WITH ROWID, SEQUENCE (event_date);
- TO_DATE как параметр функции:
CREATE FUNCTION get_events(p_date VARCHAR2) RETURN SYS_REFCURSOR IS
cur SYS_REFCURSOR;
BEGIN
OPEN cur FOR SELECT * FROM events WHERE event_date = TO_DATE(p_date, 'YYYY-MM-DD');
RETURN cur;
END;
- Сравнение TO_DATE и DATE ‘literal’:
SELECT * FROM invoices WHERE invoice_date = DATE '2024-08-31';
- Сохранение TO_DATE в переменную:
DECLARE
v_date DATE;
BEGIN
v_date := TO_DATE('2024-08-31', 'YYYY-MM-DD');
END;
- TO_DATE с GREATEST/LEAST:
SELECT LEAST(TO_DATE('2024-08-31', 'YYYY-MM-DD'), SYSDATE) FROM dual;
- Проверка дня недели:
SELECT TO_CHAR(TO_DATE('2024-09-01', 'YYYY-MM-DD'), 'DY') FROM dual;
- Использование в SELECT CASE:
SELECT employee_id,
CASE WHEN TO_DATE(hire_date, 'YYYY-MM-DD') < TO_DATE('2020-01-01', 'YYYY-MM-DD') THEN 'Veteran' ELSE 'Newbie' END status
FROM employees;
- Преобразование поля с часами:
SELECT TO_DATE(datetime_str, 'YYYY-MM-DD HH24:MI:SS') FROM server_logs;
- Создание индексируемого представления:
CREATE MATERIALIZED VIEW mv_dates AS
SELECT TO_DATE(event_str, 'YYYY-MM-DD') AS dt FROM events;
- TO_DATE + TRUNC + ROUND:
SELECT TRUNC(ROUND(TO_DATE('2024-08-31', 'YYYY-MM-DD'))) FROM dual;
- Использование в AUTONOMOUS TRANSACTION:
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
INSERT INTO logs (timestamp) VALUES (TO_DATE('2024-08-31', 'YYYY-MM-DD'));
COMMIT;
END;
- TO_DATE в EXTRACT:
SELECT EXTRACT(YEAR FROM TO_DATE('2024-08-31', 'YYYY-MM-DD')) FROM dual;
- TO_DATE в фильтрации CTE:
WITH recent AS (
SELECT * FROM actions WHERE action_time > TO_DATE('2024-08-01', 'YYYY-MM-DD')
)
SELECT * FROM recent;
- Использование в регулярной обработке:
SELECT * FROM file_load_log WHERE load_date = TO_DATE('2024-08-31', 'YYYY-MM-DD');
- Объединение нескольких строк в дату:
SELECT TO_DATE(year_str || '-' || month_str || '-' || day_str, 'YYYY-MM-DD') FROM dual;
- Обработка даты из HTML формы:
UPDATE forms SET submit_date = TO_DATE(:form_date, 'YYYY-MM-DD') WHERE id = :form_id;
- TO_DATE с динамическим SQL:
EXECUTE IMMEDIATE 'SELECT * FROM reports WHERE report_date = TO_DATE(:1, ''YYYY-MM-DD'')' USING '2024-08-31';
- Преобразование строк из CSV:
SELECT TO_DATE(csv_column, 'YYYY-MM-DD') FROM external_table;
- Формат с точками:
SELECT TO_DATE('31.08.2024', 'DD.MM.YYYY') FROM dual;
- Проверка даты через IN:
SELECT * FROM logs WHERE log_date IN (TO_DATE('2024-08-30', 'YYYY-MM-DD'), TO_DATE('2024-08-31', 'YYYY-MM-DD'));
- Преобразование в подпрограмме:
PROCEDURE audit_date(p_date_str VARCHAR2) IS
BEGIN
INSERT INTO audit (date_col) VALUES (TO_DATE(p_date_str, 'YYYY-MM-DD'));
END;
- TO_DATE и NVL:
SELECT NVL(TO_DATE(date_str, 'YYYY-MM-DD'), SYSDATE) FROM dual;
- Валидация через TRY_CAST:
-- Oracle не поддерживает TRY_CAST напрямую, можно использовать EXCEPTION
BEGIN
SELECT TO_DATE('invalid', 'YYYY-MM-DD') INTO v FROM dual;
EXCEPTION WHEN OTHERS THEN NULL;
END;
- TO_DATE с фильтрацией времени:
SELECT * FROM logs WHERE log_time >= TO_DATE('2024-08-31 08:00:00', 'YYYY-MM-DD HH24:MI:SS');
📆 Заключение: зачем использовать TO_DATE в Oracle SQL
TO_DATE — ключевая функция для работы с датами в Oracle. Она позволяет преобразовать строки в полноценные значения DATE, сравнивать их, фильтровать и хранить корректно. Если ты работаешь с импортами, логами, датами регистрации или финансовыми отчётами — без TO_DATE не обойтись.
🕸️ Следующая статья:
THEN в Oracle SQL — как управлять логикой в CASE и PL/SQL с помощью условий