Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Oracle Database 11g.pdf
Скачиваний:
78
Добавлен:
10.06.2015
Размер:
12.69 Mб
Скачать

646  Chapter 13  n  Implementing Globalization Support

NLS_LENGTH_SEMANTICS BYTE

NLS_NCHAR_CONV_EXCP FALSE

NLS_NCHAR_CHARACTERSET AL16UTF16

NLS_RDBMS_VERSION 11.1.0.6.0

20 rows selected.

The values shown in the NLS_DATABASE_PARMETERS view are set at database-creation time and based on the parameters used in the CREATE DATABASE statement.

V$NLS_VALID_VALUES

The V$NLS_VALID_VALUES dynamic performance view lists all valid values for each of the following NLS parameters: NLS_LANGUAGE, NLS_SORT, NLS_TERRITORY, and

NLS_CHARACTERSET.

The following example shows a truncated listing:

SQL> select *

from v$nls_valid_values where value like ‘%GER%’;

PARAMETER

VALUE

ISDEP

---------------

---------------

-----

LANGUAGE

GERMAN

FALSE

LANGUAGE

GERMAN DIN

FALSE

TERRITORY

GERMANY

FALSE

TERRITORY

ALGERIA

FALSE

SORT

GERMAN

FALSE

SORT

XGERMAN

FALSE

SORT

GERMAN_DIN

FALSE

SORT

XGERMAN_DIN

FALSE

8 rows selected.

 

 

SQL>

 

 

Using Datetime Datatypes

A challenge in managing data in a global environment is synchronizing transactions that occur across time zones. Oracle’s globalization support offers special datatypes and functionality to manage dates and times across differing time zones.

Using Datetime Datatypes 

647

In the following sections, you’ll learn about the Oracle datatypes that store date and time information. The data stored using these datatypes are often called datetimes, and you’ll learn about the following:

NN

DATE

 

NN

TIMESTAMP

 

NN

TIMESTAMP WITH TIME ZONE

NN

TIMESTAMP WITH LOCAL TIME ZONE

 

You’ll also be introduced to several datetime SQL functions. Last, time-zone parameters and files will be covered.

Using the DATE Datatype

The DATE datatype is used to store date information as well as time information in the database. In fact, every date stored as a DATE datatype will have an accompanying time, even if no time was specified when the date was stored. See Exercise 13.1, “Time Elements in DATE Datatypes,” for further information on time elements.

To define a column using the DATE datatype, use the DATE keyword as shown here:

SQL> create table birthdates ( client_id NUMBER,

birthdate DATE);

Table created.

Oracle dates consist of seven parts: century, year, month, day, hours, minutes, and seconds (elapsed since midnight). In fact, they are stored internally in the database as seven separate one-byte elements.

To demonstrate, insert a row into the BIRTHDATES table that was created earlier:

SQL> insert into birthdates values(1, TO_DATE(‘01-DEC-68’));

1 row created.

SQL> commit;

Commit complete.

Next, select the date from the table using the following TO_CHAR formatting option:

SQL> select to_char(birthdate,’YYYY-MM-DD:HH24:MI:SS’) from birthdates;

648  Chapter 13  n  Implementing Globalization Support

TO_CHAR(BIRTHDATE,’

-------------------

1968-12-01:00:00:00

You can see the elements displayed clearly when using this formatting option. However, that doesn’t tell you anything about how the data is stored internally. To see that, use the DUMP function, as shown here:

SQL> select dump(birthdate) from birthdates;

DUMP(BIRTHDATE)

------------------------------------------------------

Typ=12 Len=7: 119,168,12,1,1,1,1

The DUMP function shows the datatype, the length (number of bytes), and the actual byte values for a particular element. So, the example shows that the BIRTHDATE element is stored internally as a DATE datatype (typ=12). It occupies 7 bytes (Len=7) of storage, and the values stored in those bytes are 119, 168, 12, 1, 1, 1, and 1. The century is recorded in the first byte as 100 + the century. The year is recorded in the second byte as 100 + the year. The month and day of the month are stored in subsequent bytes. The hour, minute, and second are each incremented by 1.

Oracle stores the century and the year elements using excess-100 notation, which means that it adds 100 to the number before storing it. Also, the hours, minutes, and seconds elements are stored using excess-1 notation. As you probably guessed, that means that it adds 1 to each number before storing it.

Therefore, if the stored values were converted to standard decimal notation, this is what we would see:

DUMP(BIRTHDATE)

------------------------------------------------------

Typ=12 Len=7: 19,68,12,1,1,1,1

Now, you can see that the stored values do indeed match the original date, as shown here:

SQL> select to_char(birthdate,’YYYY-MM-DD:HH24:MI:SS’) from birthdates;

TO_CHAR(BIRTHDATE,’

-------------------

1968-12-01:00:00:00

By better understanding how the data is stored internally, you can think of dates as collections of individual elements that can be accessed together or individually. In Exercise 13.1, we will practice storing date and time values in columns with different data types, then query and compare the results.

Using Datetime Datatypes 

649

E x e r c i s e 13 .1

Time Elements in DATE Datatypes

DATE datatypes always store both a date and a time. If no time is specified when storing a date, Oracle will use a default time of midnight. This can be problematic if you’re not careful, as this exercise will demonstrate.

1.First, confirm the date by selecting SYSDATE from dual:

SQL> select sysdate from dual;

SYSDATE

---------

19-OCT-08

2.Create a table with a VARCHAR2 column to contain a date string and a DATE column:

SQL> create table conv_dates (datestring varchar2(15), converted_date date);

Table created.

3.Insert the current date into a table column defined as a datatype of DATE:

SQL> insert into conv_dates

values (‘10-19-2008’, to_date(‘10-19-2008’,’MM-DD-YYYY’));

1 row created.

SQL> commit;

Commit complete.

4.Execute the following SQL:

SQL> select * from conv_dates where converted_date = sysdate;

no rows selected

Even though the two dates appear identical, the query fails to return any matching rows. The following queries will show you the reason:

SQL> select

to_char(converted_date, ‘MM-DD-YYYY HH24:MI’) from conv_dates;

650  Chapter 13  n  Implementing Globalization Support

E x e r c i s e 13 .1   ( c o n t i n u e d )

TO_CHAR(CONVERTE

----------------

10-19-2008 00:00

12-01-1968 00:00

SQL> select to_char(sysdate,’MM-DD-YYYY HH24:MI’) from dual;

TO_CHAR(SYSDATE,

----------------

10-19-2008 22:22

Because no time element was defined when you inserted the rows into the CONV_DATES table, Oracle defaulted the time to midnight. SYSDATE, on the other hand, returns the current date and the current time. Therefore, unless you happen to run the query at exactly midnight, the query returns no rows.

To resolve this problem, you can use the TRUNC function, as shown here:

SQL> select * from conv_dates

where trunc(converted_date) = trunc(sysdate);

DATESTRING CONVERTED_

--------------- ----------

10-19-2008 19/10/08

The TRUNC function removes the time element from the date element in a DATE value. With the time element gone, the query returns one row, as expected.

When entering date information into a DATE datatype, you can specify it in several ways:

Literal    The date can be entered as a literal, which matches the NLS_DATE_FORMAT format. For example, if NLS_DATE_FORMAT is defined as ‘MM-DD-YYYY’, then a literal of ‘12-21- 2000’ would be acceptable, as shown in this example:

SQL> alter session set NLS_DATE_FORMAT = “MM-DD-YYYY”;

Session altered.

Using Datetime Datatypes 

651

SQL> insert into birthdates values(2, ‘12-21-2000’);

1 row created.

Note that in this example, because no time portion was specified, Oracle will set the time elements to represent midnight.

ANSI date literal    An American National Standards Institute (ANSI) date literal contains no time element. It must be formatted exactly as shown here:

DATE ‘YYYY-MM-DD’

Dates can be entered using the ANSI date-literal format at any time, regardless of the NLS_ DATE_FORMAT setting. Here’s an example:

SQL> insert into birthdates

2 values(3, DATE ‘1969-08-23’);

1 row created.

TO_DATE function    Dates can also be entered by using the TO_DATE function. This function converts text strings to DATE types based on the format specified. An example is shown here:

SQL> insert into birthdates

values(4, to_date(‘04-19-1977 13:45’, ‘MM-DD-YYYY HH24:MI’);

This example specifies not only the date, but also the hours and minutes elements of the time.

The TO_DATE function can also be handy for converting dates that have been stored as character types. Consider the following examples using the CONV_DATES table created earlier in this section. This table will hold a string of 15 characters and a date. Now, a string representation of two dates will be inserted in the table. Note that they are being stored as VARCHAR2 character data, not as dates:

SQL> insert into conv_dates (datestring) values (‘12-01-1968’);

1 row created.

SQL> insert into conv_dates (datestring) values (‘04-09-1965’);

1 row created.

652  Chapter 13  n  Implementing Globalization Support

SQL> commit;

Commit complete.

Next, the strings will be converted and stored as dates by using the TO_DATE function:

SQL> update conv_dates set converted_date =

to_date(datestring,’MM-DD-YYYY’);

2 rows updated.

SQL> commit;

Commit complete.

Now both will be selected, as shown here:

SQL> select * from conv_dates;

DATESTRING

CONVERTED_D

---------------

-----------

12-01-1968

01-DEC-1968

04-09-1965

09-APR-1965

As you can see in this example, the TO_DATE function converted the dates stored as VARCHAR2 data in the DATESTRING column into the DATE datatype format, which was subsequently stored in the CONVERTED_DATE column.

Using the TIMESTAMP Datatype

The TIMESTAMP datatype offers all the date and time elements found in the DATE datatype in addition to the extended functionality of storing fractional seconds.

By default, the TIMESTAMP datatype stores fractional seconds to six digits of precision. This can be changed, however, by specifying a number from 0 and 9 in parentheses after the TIMESTAMP keyword. This number determines the digits of precision for the fractional seconds, as shown here:

SQL> create table test_stamp (stamp timestamp(2));

Table created.

Using Datetime Datatypes 

653

SQL> insert into test_stamp

select to_timestamp(‘19-OCT-2008 17:54.38.92’, ‘DD-MON-YYYY HH24:MI:SS:FF’)

from dual;

1 row created.

SQL> commit;

Commit complete.

SQL> select * from test_stamp;

STAMP

------------------------------------

19-OCT-08 05.54.38.92 PM

As you can see, the timestamp was entered using the TO_TIMESTAMP function (which is similar to the TO_DATE function). Notice that fractional seconds can be specified by using the FF element in the date mask.

The TIMESTAMP datatype should be used when locale information (time zone) is not required but fractional-second granularity is. For example, application event logging is a common use of the TIMESTAMP datatype.

Using the TIMESTAMP WITH TIME ZONE Datatype

The TIMESTAMP WITH TIME ZONE datatype extends the functionality of the TIMESTAMP datatype by including time-zone information. The time-zone data is stored as an offset (hours and minutes) between the local time and the UTC (Coordinated Universal Time, formerly known as Greenwich mean time). It can be displayed either in this form or in the form of a region name.

Like the TIMESTAMP datatype, the TIMESTAMP WITH TIME ZONE datatype stores fractional seconds to six digits of precision. This can be changed by specifying a number from 0 and 9 in parentheses between the TIMESTAMP keyword and the WITH TIME ZONE keywords. This number determines the digits of precision for the fractional seconds, as in this example:

SQL> create table stamp_tz (stamp_tz TIMESTAMP(4) WITH TIME ZONE); Table created

The TIMESTAMP WITH TIME ZONE is recommended when local information and precise time transactions across time zones need to be synchronized. For example, a bank with branches in different time zones needs to post transactions in real time, regardless of location.

654  Chapter 13  n  Implementing Globalization Support

Using the TIMESTAMP WITH LOCAL TIME ZONE Datatype

The TIMESTAMP WITH TIME ZONE datatype doesn’t actually store time-zone information at all. Instead, when a record is inserted into a column defined with a datatype of TIMESTAMP WITH LOCAL TIME ZONE, the following happens:

NNIf the incoming data has no time-zone element, it is assumed to be local time and is stored as is.

NNIf the incoming data has a time-zone element but the time zone matches the local time zone, the time-zone element is dropped and the data is stored.

NNIf the incoming data has a time-zone element and the time zone does not match the local time zone, the timestamp is adjusted to local time. The data is then stored without a time-zone element.

Using this method synchronizes all time elements to the local time, allowing a company that spans multiple time zones to see data in real time relative to the local time zone. One way to utilize this datatype is to use the supplied CURRENT_TIMESTAMP function, which returns the current date and time in the session time zone, in a value of datatype TIMESTAMP WITH TIME ZONE.

Using the TIMESTAMP WITH LOCAL TIME ZONE Datatype

Suppose your company is headquartered in London and you have a branch office in New York. Transactions from the branch office need to be stored in your London database and synchronized to London time.

The time-zone information for London is as follows:

Element

Value

Standard time zone

No UTC offset

Daylight Savings Time

+1 hour

Current time-zone offset

UTC +1 hour

Time-zone abbreviation

BST (British summer time)

Current time

Friday, September 3, 2008, at 1:15:14 p.m. BST

Using Datetime Datatypes 

655

The time-zone information for New York is as follows:

Element

Value

Standard time zone

UTC –5 hours

Daylight Savings Time

+1 hour

Current time-zone offset

UTC –4 hours

Time-zone abbreviation

EDT (eastern daylight time)

Current time

Friday, September 3, 2008, at 8:15:14 a.m. EDT

As you can see, London is currently one hour ahead of UTC, whereas New York is four hours behind. Therefore, London’s time is five hours ahead of New York’s.

Now, suppose a transaction comes in from your New York branch to your London office. The timestamp data will be stored in a column defined with the TIMESTAMP WITH LOCAL TIME ZONE datatype. Before storing the data, Oracle synchronizes the time by adding five hours to the timestamp value and drops the time-zone element.

In Exercise 13.2, you’ll see the functionality of the TIMESTAMP WITH LOCAL TIME ZONE datatype.

E x e r c i s e 13 . 2

Using TIMESTAMP WITH LOCAL TIME ZONE

To demonstrate the functionality of the TIMESTAMP WITH LOCAL TIME ZONE datatype, perform the following steps:

1.Create table timezone_test with two columns: x as TIMESTAMP and y as TIMESTAMP WITH LOCAL TIME ZONE. Set your server time zone to UTC –5:

SQL> create table timezone_test (x timestamp, y timestamp with local time zone);

Table created.

2.Alter the session time zone to 5 hours behind UTC, and then insert sysdate into both columns in the timezone_test table.

SQL> ALTER SESSION SET TIME_ZONE = ‘-5:00’;

SQL> insert into timezone_test values (sysdate, sysdate); 1 row created.

656  Chapter 13  n  Implementing Globalization Support

E x e r c i s e 13 . 2   ( c o n t i n u e d )

3.Insert the client time into both columns using the current_timestamp function, and query the results:

SQL> insert into timezone_test values (current_timestamp,

current_timestamp);

 

 

1 row created.

 

 

SQL> select * from timezone_test;

 

X

 

Y

 

------------------------------

------------------------------

11-NOV-08

07.25.31.000000 PM

11-NOV-08

07.25.31.000000 PM

11-NOV-08

07.25.36.897000 PM

11-NOV-08

07.25.36.897000 PM

SQL>

 

 

 

4.Modify your local time zone to UTC –7, and repeat step 3:

SQL> ALTER SESSION SET TIME_ZONE = ‘-7:00’;

SQL> insert into timezone_test values (current_timestamp, current_timestamp);

1 row created.

SQL> select * from timezone_test;

 

X

 

Y

 

------------------------------

------------------------------

11-NOV-08

07.25.31.000000 PM

11-NOV-08 05.25.31.000000 PM

11-NOV-08

07.25.36.897000 PM

11-NOV-08

05.25.36.897000 PM

11-NOV-08

05.31.35.104000 PM

11-NOV-08

05.31.35.104000 PM

5.Modify your local time zone to UTC –5, and query the timezone_test table:

SQL> ALTER SESSION SET TIME_ZONE = ‘-5:00’; SQL> select * from timezone_test;

X

 

 

Y

 

------------------------------

------------------------------

11-NOV-08

07.25.31.000000 PM

11-NOV-08

07.25.31.000000 PM

11-NOV-08

07.25.36.897000

PM

11-NOV-08

07.25.36.897000 PM

11-NOV-08

05.31.35.104000

PM

11-NOV-08

07.31.35.104000 PM

Note that column y, the TIMESTAMP WITH TIMEZONE column, shows the corrected time based on the local time zone because the time-zone data was retained. Note that column x does not retain the time-zone data and is not corrected if the time zone changes.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]