
Функции преобразования данных
Под преобразованием данных (data conversion) понимается преобразование информации одного типа в информацию другого типа — обычно текста в дату, время или число, либо наоборот. Функции преобразования данных полезны по двум причинам:
• они позволяют изменять способ отображения дат, времен и чисел;
• они упрощают импорт данных из других источников.
TO_CHAR
Функция TO_CHAR преобразует дату, время или число в текст. Ее основная ценность в том, что она позволяет в широких пределах управлять отображением дат, времен и чисел. Тот факт, что все это будет показано в текстовом виде, не имеет значения при просмотре на экране SQL*Plus.
К выбранным из таблицы числам не применяется какое-либо определенное форматирование; они отображаются с тем количеством десятичных знаков, которое содержат, поэтому список не всегда бывает выровнен. Определенные проблемы связаны и с датами: они отображаются в таком формате, который мало используется в повседневной жизни, и по умолчанию не содержат времени. Функция TO_CHAR позволяет исправить обе эти ситуации.
Форматирование значений даты и времени Синтаксис функции TO_CHAR, предназначенной для изменения способа отображения дат и времени, имеет следующий вид:
ТО_СНАR(входное_значение, код_формата)
Входное_значение может быть передано функции непосредственно, но чаще оно передается указанием имени столбца таблицы. Код_формата состоит из одного или нескольких элементов, определяющих, как будут представлены дата и время.
Простой пример использования функции TO_CHAR приведен ниже.
SELECT TO_CHAR(SYSDATE, 'MM-DD-YYYY HH24:MI:SS') NOW FROM DUAL;
В данном примере код_формата задает отображение текущей даты в привычном большинству людей формате, а также позволяет увидеть временной компонент SYSDATE. Можно составить любой код формата, комбинируя элементы в соответствии с потребностями. Некоторые доступные элементы перечислены в табл. 2.3.
Таблица 2.3
Элементы кода формата даты и времени, используемого в функции TO_CHAR
-
Элемент
Значение
D
День недели (1-7)
DAY
Название дня недели, дополненное пробелами до девяти
символов
DD
День месяца (1-31)
DDD
День года (1-366)
DY
Сокращенное название дня недели
НН
Час дня(1-12)
НН12
Часдня(1-12)
НН24
Час дня (0-23)
Ml
Минуты (0-59)
ММ
Месяц (01-12; январь = 01)
MON
Сокращенное название месяца
MONTH
Название месяца, дополненное пробелами до девяти символов
РМ
P.M.
Обозначение времени после полудня (с точками или без точек)
Q
Квартал года (1,2,3,4; январь-март = 1)
RM
Римский номер месяца (I-XII; январь = I)
SS
Секунды (0-59)
SSSSS
Секунды после полуночи (0-86399)
YEAR
Год в буквенном написании
YYYY
Год из четырех цифр
YYY
YY
Y
Последние цифры года (три, две или одна)
Элемент формата DD, представляющий день месяца, имеет два необязательных суффикса, которые позволяют внести некоторые улучшения. Если добавить суффикс ТН, Oracle будет показывать "1ST" вместо "1", "2ND" вместо "2", и т.д. При добавлении суффикса SP день будет представлен в буквенном написании.
Внешний вид отображаемых дат можно еще немного улучшить. Например, элемент формата MONTH всегда дополняет название месяца до девяти символов, в результате чего возникает большой промежуток между месяцем и числом, если месяц имеет короткое название. Кроме того, вся дата записывается прописными буквами. Эти проблемы можно решить с помощью других уже известных функций. Полный список "косметических" проблем таков:
• лишние пробелы после названий месяцев;
• прописные буквы в названиях месяцев;
• прописные буквы в суффиксе после числа месяца (например, "ТН" вместо "th");
• прописные буквы в числе месяца при использовании суффикса SP.
Можно использовать ранее изученные функции для решения каждой из этих проблем. Покажем это на примере исправления следующего формата даты:
SELECT TO_CHAR(SYSDATE, 'MONTH DDTH') FROM DUAL;
Чтобы удалить избыточные пробелы после названия месяца, можно воспользоваться функцией RTRIM. При этом, однако, потребуется разделить месяц и число, что легко сделать, выбрав их как два отдельных значения и применив операцию конкатенации. Приведенная ниже команда показывает, как отделить название месяца от числа:
SELECT TO_CHAR(SYSDATE, 'MONTH') | | ' ' | | TO_CHAR(SYSDATE, 'DDTH')
FROM DUAL;
Для удаления лишних пробелов нужно подставить функцию TO_CHAR в функцию RTRIM, как показано ниже:
SELECT RTRIM(TO_CHAR(SYSDATE, 'MONTH')) | | ' ' | | TO_CHAR(SYSDATE, 'DDTH')
FROM DUAL;
Это даст желаемый интервал. Далее нужно изменить регистр символов в названии месяца, чтобы только первая буква была прописной. Функция INITCAP делает именно это, если подставить в нее часть оператора SELECT, относящуюся к названию месяца, как показано ниже:
SELECT INITCAP(RTRIM(TO_CHAR(SYSDATE, 'MONTH'))) | |
' ' | | TO_CHAR(SYSDATE, 'DDTH')
FROM DUAL;
Последнее изменение касается регистра символов в суффиксе после дня месяца. Для этого нужно использовать функцию LOWER, как показано ниже:
SELECT INITCAP(RTRIM(TO_CHAR(SYSDATE, 'MONTH'))) I I
' ' I I LOWER ( TO_CHAR ( SYSDATE , ' DDTH ' ) )
FROM DUAL;
Форматирование числовых значений Функция TO_CHAR обеспечивает также стандартизацию способа отображения чисел. В выходных данных команды
SELECT * FROM product;
цены товаров имеют разное количество десятичных знаков, что затрудняет их чтение. Для решения этой проблемы достаточно поместить в команду SELECT функцию TO_CHAR:
SELECT product_name, TO_CHAR(product_price, '$9,999.00') "Price",
quantity_on_hand, last_stock_date
FROM product;
Полученные результаты выглядят так, как показано ниже:
PRODUCT_NAME Price QUANTITY_ON_HAND LAST_STOCK
--------------------------------------- ---------- -------------------------------- --------------------
Small Widget $99.00 1 15-JAN-83
Medium Wodget $75.00 1000 15-JAN-82
Chrome Phoobar $58.00 100 15-JAN-83
Round Chrome Snaphoo $25.00 10000
Extra Huge Mega Phoobar + $9.95 1234 15-JAN-84
Square Zinculator $45.00 1 09-JUL-88
6 rows selected.
Как и форматы дат, форматы чисел составляются из одного и более элементов, каждый из которых отвечает за определенный аспект форматирования. Эти элементы приведены в табл. 2.4.
Таблица 2.4
Элементы кода формата чисел, используемого в функции TO_CHAR
-
Элемент
Пример
Описание
$
$9999
Помещает знак доллара перед значением
, (запятая)
9,999
Помещает запятую в указанной позиции
. (точка)
99.99
Помещает десятичную точку в указанной позиции
Ml
9999MI
Отображает знак "-" после отрицательного числа
S
S9999
Помещает в указанной позиции знак "+" (для положительных чисел) или знак "-" (для отрицательных чисел)
PR
9999PR
Окружает отрицательные числа <угловыми скобками>
D
99D99
Отображает в указанной позиции десятичный разделитель, принятый в вашей стране
G
99G99
Отображает в указанной позиции разделитель групп разрядов, принятый в вашей стране
С
С999
Отображает знак денежной единицы ISO в указан-
ной позиции
L
L999
Отображает знак местной денежной единицы в указанной позиции
RN или rn
RN
Отображает числа римскими цифрами верхнего или нижнего регистра (только для целых чисел от
1 до 3999)
0
0999
Отображает один и более начальных нулей
0
9990
Отображает пустые значения как нули
TO_DATE
Функция TO_DATE преобразует текстовое представление даты (и/или времени) в действительные значения даты/времени. Хотя ее основное назначение — импорт текстовых файлов с датами и временем из других баз данных, она также полезна при ручном вводе даты в формате, отличном от стандартного формата Oracle (DD-MON-YY), или при вводе времени. Эта функция имеет следующий синтаксис:
ТО_DАТЕ(входное_значение, код_формата)
Функция TO_DATE использует подмножество элементов кода формата, определенных в функции TO_CHAR (табл. 2.3).
Результаты действия функции TO_DATE при вставке даты и времени можно увидеть, выполнив следующие команды:
SELECT product_name, product_price, quantity_on_hand,
TO_CHAR(last_stock_date, 'MM-DD-YYYY HH24:MI') "Last Stocked"
FROM product;
UPDATE product SET last_stock_date = TO_DATE('December 31, 2002, 11:30 P.M.' ,
'Month dd, YYYY, HH:MI P.M.' )
WHERE product_name LIKE '%Zinc%';
SELECT product_name, product_price, quantity_on_hand,
TO_CHAR(last_stock_date, 'MM-DD-YYYY HH24:MI') "Last Stocked"
FROM product;