В этом учебном пособии вы узнаете, как использовать Oracle/PLSQL функцию TO_CHAR с синтаксисом и примерами.
Описание
Функция Oracle/PLSQL TO_CHAR преобразует число или дату в строку.
Синтаксис
Синтаксис функции Oracle/PLSQL TO_CHAR:
Параметры или аргументы
value может принимать числовое значение или дату, которые будут преобразованы в строку.
format_mask не является обязательным. Это формат, который будет использоваться для преобразования значения в строку.
nls_language не является обязательным. Это язык NLS используется для преобразования значения в строку.
Примечание
Функция TO_CHAR возвращает string значение.
Применение
Функцию TO_CHAR можно использовать в следующих версиях Oracle/PLSQL:
Пример
Рассмотрим несколько примеров функции TO_CHAR и изучим, как использовать функцию TO_CHAR в Oracle/PLSQL.
Для чисел
Ниже приведены примеры для функции TO_CHAR для чисел.
Для дат
Ниже приведен список допустимых параметров, когда функция TO_CHAR используется для преобразования даты в строку. Эти параметры могут быть использованы во многих комбинациях.
Параметр
Пояснение
YEAR
Год.
YYYY
4-значный год.
YYY YY Y
Последние 3, 2 или 1 цифра(ы) года.
IYY IY I
Последние 3, 2 или 1 цифра(ы) года ISO.
IYYY
4-значный год в соответствии со стандартом ISO.
Q
Квартал года (1, 2, 3, 4; JAN-MAR = 1).
MM
Месяц (01-12; JAN = 01).
MON
Сокращенное название месяца.
MONTH
Название месяца, дополненное пробелами длиной до 9 символов.
RM
Римская цифра RM (I-XII; JAN = I).
WW
Неделя года (1-53), где неделя 1 начинается в первый день года и продолжается до седьмого дня года.
W
Неделя месяца (1-5), где неделя 1 начинается в первый день месяца и заканчивается седьмым.
IW
Неделя года (1-52 или 1-53) на основе стандарта ISO.
D
День недели (1-7).
DAY
Название дня.
DD
День месяца (1-31).
DDD
День года (1-366).
DY
Сокращенное название дня.
J
юлианский день; количество дней с 1 января 4712 г. до н.э.
MONTH MON DAY DY BC or AD or B.C. or A.D. AM or PM or A.M or P.M. The language in which these values are returned is specified either explicitly with the initialization parameter NLS_DATE_LANGUAGE or implicitly with the initialization parameter NLS_LANGUAGE. The values returned by the YEAR and SYEAR datetime format elements are always in English.
if (to_char(sysdate,’d’)>=1) and (to_char(sysdate,’d’) [new]
Теперь, когда вы имеете представление о типах данных Oracle, предназначенных для работы с датой и временем, давайте посмотрим, как присваивать даты значениям переменных этих типов и как использовать такие значения в дальнейшем. Дата и время в понятной для человека форме представляются в виде символьных строк наподобие «5 марта 2009 года» и «10:30», так что речь пойдет о преобразовании значений даты/ времени в PL/SQL — приведении символьных строк в соответствие с внутренним представлением Oracle, и наоборот.
PL/SQL проверяет и хранит даты от 1 января 4712 года до н. э. до 31 декабря 9999 года н. э. (В документации Oracle указана максимальная дата 31 декабря 4712 года). Если ввести дату без времени (во многих приложениях не требуется отслеживать время, поэтому PL/SQL позволяет его не задавать), то время в таком значении по умолчанию будет равно полуночи (00:00:00).
База данных Oracle способна интерпретировать практически все известные форматы даты и времени. Эта возможность основана на использовании маски форматирования даты, которая представляет собой строку специальных символов, определяющих формат даты для Oracle.
В следующем разделе мы рассмотрим несколько разных масок форматирования даты. Полный список всех элементов форматирования масок приводится в приложении В.
Преобразование строк в даты
Первой практической задачей, с которой вы столкнетесь при работе с датами, будет присваивание даты (или времени) переменной PL/SQL. Операция выполняется путем преобразования даты/времени во внутренний формат базы данных. Такие преобразования выполняются либо неявно, присваиванием символьной строки переменной типа даты/времени, либо явно, с помощью встроенных функций Oracle.
Неявное преобразование — вещь рискованная, и мы не рекомендуем на него полагаться. Пример неявного преобразования символьной строки при ее присваивании переменной типа DATE :
PL/SQL поддерживает следующие функции преобразования строк в дату и время:
Эти функции не только ясно показывают, что в коде выполняется преобразование, но и позволяют точно задать используемый формат даты/времени.
Вторая версия TO_DATE может использоваться только с маской форматирования J (Юлианская дата, то есть количество дней, прошедших с 1 января 4712 года до н. э.). Только в этом варианте использования TO_DATE в первом параметре может передаваться число.
В остальных случаях параметры имеют следующий смысл:
Здесь язык — один из языков, распознаваемых вашим экземпляром базы данных. За информацией о допустимых языках обращайтесь к руководству Oracle Globalization Support Guide.
Ошибки Oracle из диапазона от ORA-01800 до ORA-01899 связаны с преобразованиями дат. Чтобы узнать о некоторых тонкостях обработки дат, просмотрите документацию по этим ошибкам и ознакомьтесь с описаниями их причин. Вот лишь некоторые из них:
Как показывают предыдущие примеры, функция TO_TIMESTAMP_TZ может преобразовывать символьные строки с информацией часового пояса. И хотя часовые пояса на первый взгляд выглядят просто, в действительности все намного сложнее — вы убедитесь в этом в разделе «Часовые пояса».
Преобразование даты в строку
Здесь входная_дата — символьная строка, представляющая значение даты/времени; маска — строка из одного или нескольких элементов формата; язык_nls — строка, задающая язык отображения даты. Параметры маска и язык_nls не являются обязательными.
Несколько примеров использования функции TO_CHAR для преобразования даты:
Обратите внимание на выполненное округление. Во входных данных было указано количество секунд 00.123456789. Значение было округлено (не усечено, а именно округлено) до шести цифр: 00,123457.
Сообщение об ошибке (формат даты не распознается) только сбивает с толку. Формат даты абсолютно нормален — проблема в том, что он применяется не к тому типу данных. Поэтому при получении такого сообщения следует проверить не только формат даты, но и тип данных, который вы собираетесь преобразовывать.
Часовые пояса
Рассмотрим несколько примеров. Начнем с простейшего случая, в котором часовой пояс вообще не указан:
Дата или время?
Учтите, что каждое значение даты/времени содержит как дату, так и время. Стоит вам забыть об этом, и в вашем коде появятся ошибки. Рассмотрим пример: допустим, я написал код PL/SQL, который должен быть выполнен 1 января 2015 года:
Теперь в обеих сторонах сравнения указывается время суток, но этим временем является полночь. Функция TO_DATE также возвращает время суток, которое по умолчанию соответствует полуночи (то есть 00:00:00). Итак, в какое бы время 1 января 2015 года ни был выполнен этот блок, сравнение будет выполнено успешно, и процедура Apply2009PriceChange будет выполнена.
Функцию TRUNCATE также удобно использовать для удаления времени из временных штампов.
В этом примере значение даты/времени интерпретируется как Восточное стандартное время США (независимо от часового пояса сеанса).
Этот пример интересен тем, что он представляет не Восточное стандартное время, а просто Восточное время. Разница между ними заключается в том, что термин Восточное время может обозначать как Восточное стандартное время, так и Восточное летнее время — в зависимости от того, действует ли переход на летнее время. Я специально сформулировал этот пример так, чтобы он был неоднозначным. 2 ноября 2014 года — это дата завершения действия Восточного летнего времени, когда время 2:00 превращается в 1:00. Поэтому в указанный день 1:30 наступает дважды: по Восточному летнему и по Восточному стандартному времени. Так какое же время имеется в виду при определении 1:30 2 ноября 2014 года?
Названия региона недостаточно для различения стандартного и летнего времени. Для устранения этой неоднозначности необходимо задать сокращение часового пояса, как это сделано в двух следующих примерах. Восточное летнее время обозначается сокращением EDT (Eastern Daylight Time):
Если параметр сеанса ERROR_ON_OVERLAP_TIME равен TRUE (по умолчанию используется значение FALSE ), база данных будет выдавать ошибку при задании неоднозначного времени.
Восточное стандартное время обозначается сокращением EST (Eastern Standard Time):
Для предотвращения неоднозначности рекомендуется либо задавать смещение часового пояса в часах и минутах (например, –5:00), либо использовать сочетание названия и сокращения часового пояса. Если указано только имя региона, то при наличии неоднозначности в определении времени (летнее или стандартное) Oracle будет считать, что задано стандартное время.
О СТАНДАРТЕ ЧАСОВЫХ ПОЯСОВ
Часовые пояса настолько важны, что, казалось бы, должен существовать некий международный стандарт, определяющий их названия и сокращения. Тем не менее такого стандарта нет. Названия часовых поясов и сокращения не только не стандартизированы, но среди них даже встречаются повторения. Например, сокращение EST обозначает Восточное стандартное время и в США, и в Австралии, то есть соответствует двум часовым поясам с разным смещением времени. Сокращение BST применяется для нескольких часовых поясов, включая Тихоокеанский/Мидуэй и Лондонский, отличающиеся на 12 часов в режиме летнего времени или на 11 часов в остальное время года. Вот почему функция TO_TIMESTAMP не позволяет задавать часовой пояс лишь по сокращению названия.
Точное совпадение маски форматирования
При преобразовании символьной строки в дату/время функции преобразования TO_ *обычно руководствуются несколькими предположениями:
С модификатором FX какая-либо гибкость в интерпретации строки полностью отсутствует. Строка не может содержать лишние пробелы, если их нет в модели. Ее числовые значения должны включать начальные нули, если модель форматирования включает дополнительные цифры. Наконец, знаки препинания и литералы должны точно соответствовать знакам препинания и заключенному в кавычки тексту маски форматирования (не считая регистра символов, который всегда игнорируется). Все эти правила продемонстрированы в следующих примерах:
PL/SQL выдает одну из следующих ошибок:
Однако следующий пример выполняется успешно, потому что регистр символов не учитывается, и модификатор FX этого факта не меняет:
Модификатор FX может задаваться в верхнем регистре, нижнем регистре или со смешением регистров; его действие от этого не изменяется.
Модификатор FX работает как переключатель и может многократно встречаться в маске форматирования. Пример:
Каждый раз, когда модификатор FX встречается в маске форматирования, происходит переключение. В приведенном примере точное совпадение обязательно для дня и года, но не для месяца.
Ослабление требований к точности совпадения
Интерпретация года из двух цифр
Переход в новое тысячелетие породил интерес к хранению года в формате из четырех цифр, потому что разработчики внезапно осознали неоднозначность часто встречающегося формата с двумя цифрами. Например, к какому году относится дата 1-Jan- 45 — к 1945 или 2045? В таких ситуациях лучше всего использовать однозначный год с четырьмя цифрами. Но несмотря на это понимание, старые привычки изменяются с трудом, а внесение изменений в существующие системы сопряжено с большими трудностями. Возможно, ваши пользователи предпочитают вводить год из двух цифр, а не из четырех. Для подобных случаев Oracle предоставляет форматный элемент RR, интерпретирующий год из двух цифр в скользящем окне.
Если текущий год относится к первой половине века (годы с 0 по 49), то:
Если же текущий год относится ко второй половине века (годы с 50 по 99), то:
Запутались? Я тоже разобрался не сразу. Правила RR пытаются предположить, какой век подразумевал пользователь, если он не был указан явно.
Логику RR в текущих приложениях можно активизировать несколькими способами. Самый простой и элегантный способ — изменение маски форматирования дат по умолчанию в экземпляре базы данных. Собственно, Oracle уже делает это за нас. В стандартной установке Oracle параметр NLS_DATE_FORMAT задается следующим образом:
Если маска форматирования дат не будет жестко запрограммирована на других экранах или отчетах, год из двух цифр будет интерпретироваться по правилам, приведенным выше.
Преобразование часовых поясов в символьные строки
Часовые пояса усложняют преобразование значений даты/времени в символьные строки. Информация часового пояса состоит из следующих элементов.
Все эти элементы хранятся отдельно в переменной TIMESTAMP WITH TIME ZONE. Смещение относительно UTC присутствует всегда, но возможность вывода названия региона или сокращения зависит от того, задана эта информация или нет. Рассмотрим следующий пример:
В этом коде следует обратить внимание на некоторые аспекты, относящиеся к информации часовых поясов:
Внутреннее преобразование переводит его в смещение относительно UTC, но имя региона при этом сохраняется. Таким образом, для ts2 может быть выведено как смещение UTC, так и имя региона.
Смещения относительно UTC и регионы часовых поясов связаны отношениями «один ко многим»; смещения недостаточно для однозначного определения имени региона. Вот почему невозможно вывести имя региона, если оно не было задано изначально.
Дополнение вывода с модификатором FM
По умолчанию следующая маска форматирования генерирует как дополняющие пробелы, так и начальные нули (название месяца отделяется от дня пятью пробелами):
Однако с модификатором FM в начале маски и лишний пробел, и начальные нули исчезают:
Модификатор может задаваться в верхнем регистре, нижнем регистре или со смешением регистров; его действие от этого не изменяется.
Помните, что модификатор FM работает как переключатель и может многократно встречаться в маске форматирования. Каждый раз, когда он встречается в маске форматирования, происходит переключение. По умолчанию (то есть если модификатор FM вообще не встречается в маске) пробелы не подавляются, а начальные нули включаются в итоговое значение.
DATE values are converted to values in the default date format.
TIMESTAMP and TIMESTAMP WITH LOCAL TIME ZONE values are converted to values in the default timestamp format.
TIMESTAMP WITH TIME ZONE values are converted to values in the default timestamp with time zone format.
Interval values are converted to the numeric representation of the interval literal.
Refer to «Format Models» for information on datetime formats.
The ‘nlsparam’ argument specifies the language in which month and day names and abbreviations are returned. This argument can have this form:
You can use this function in conjunction with any of the XML functions to generate a date in the database format rather than the XML Schema standard format.
Oracle XML DB Developer’s Guide for information about formatting of XML dates and timestamps, including examples
«XML Functions» for a listing of the XML functions
Appendix C in Oracle Database Globalization Support Guide for the collation derivation rules, which define the collation assigned to the character return value of this function
The following example uses this table:
The example shows the results of applying TO_CHAR to different TIMESTAMP data types. The result for a TIMESTAMP WITH LOCAL TIME ZONE column is sensitive to session time zone, whereas the results for the TIMESTAMP and TIMESTAMP WITH TIME ZONE columns are not sensitive to session time zone:
The following example converts an interval literal into a text literal:
Using TO_CHAR to Format Dates and Numbers: Example
The following statement converts date values to the format specified in the TO_CHAR function:
The following statement converts date and timestamp values to the format specified in the TO_CHAR function:
The following statement extracts the datetime fields specified in the EXTRACT function from the input datetime expressions:
The following statement displays the input numbers as per the format specified in the TO_CHAR function:
The following statement converts the input numbers as per the format specified in the TO_CHAR function:
The following statement converts the input numbers as per the format specified in the TO_CHAR function:
View and run a related example on Oracle Live SQL at Using TO_CHAR to Format Dates and Numbers
TO_CHAR (datetime) Function: Example
The following statements create a table named empl_temp and populate it with employee details:
The following statement displays dates by using the short and long formats:
View and run a related example on Oracle Live SQL at Using the TO_CHAR Function