PL/SQL programing 第六版学习笔记-4

2020-12-02  本文已影响0人  e652d1fb12eb

Chapter 9 Numbers

Numeric Datatypes

if you compile your code natively and your situation is such that your variable will never be NULL and will never overflow,then the SIMPLE_INTEGER type will scream with better performance. Consider this example: Page250

Number Conversions

An advantage of CAST, however, is that it is part of the ISO SQL standard, whereas the TO_CHAR and TO_NUMBER functions are not. If writing 100% ANSI-compliant code is important to you, you should investigate the use of CAST.

CEIL
Returns the smallest integer that is greater than or equal to the specified value. This integer is the “ceiling” over your value.

FLOOR
Returns the largest integer that is less than or equal to the specified value. This integer is the “floor” under your value.

ROUND
Performs rounding on a number. You can round with a positive number of decimal places (the number of digits to the right of the decimal point) and also with a negative number of decimal places (the number of digits to the left of the decimal point).

TRUNC
Truncates a number to the specified number of decimal places. TRUNC simply discards all values beyond the number of decimal places provided in the call.

Chapter 10 Dates and Timestamps

Stores a date and time, resolved to the second. Does not include time zone.

Stores a date and time without respect to time zone. Except for being able to resolve
time to the billionth of a second (nine decimal places of precision), TIMESTAMP
is the equivalent of DATE.

Stores the time zone along with the date and time value, allowing up to nine decimal
places of precision.

Stores a date and time with up to nine decimal places of precision. This datatype is
sensitive to time zone differences. Values of this type are automatically converted
between the database time zone and the local (session) time zone. When values are
stored in the database, they are converted to the database time zone, but the local
(session) time zone is not stored. When a value is retrieved from the database, that
value is converted from the database time zone to the local (session) time zone.

The following example illustrates some of these functions:

set SERVEROUTPUT on;
BEGIN
DBMS_OUTPUT.PUT_LINE('Session Timezone='||SESSIONTIMEZONE);
DBMS_OUTPUT.PUT_LINE('Session Timestamp='||CURRENT_TIMESTAMP);
DBMS_OUTPUT.PUT_LINE('DB Server Timestamp='||SYSTIMESTAMP);
DBMS_OUTPUT.PUT_LINE('DB Timezone='||DBTIMEZONE);
EXECUTE IMMEDIATE 'ALTER SESSION SET TIME_ZONE=DBTIMEZONE';
DBMS_OUTPUT.PUT_LINE('DB Timestamp='||CURRENT_TIMESTAMP);
-- Revert session time zone to local setting
EXECUTE IMMEDIATE 'ALTER SESSION SET TIME_ZONE=LOCAL';
END;

Allows you to define an interval of time in terms of years and months.

INTERVAL DAY TO SECOND

Allows you to define an interval of time in terms of days, hours, minutes, and
seconds (including fractional seconds).

One use for INTERVAL types is when you need to look at the difference between two
datetime values.

/* File on web: interval_between.sql */
DECLARE
start_date TIMESTAMP;
end_date TIMESTAMP;
service_interval INTERVAL YEAR TO MONTH;
years_of_service NUMBER;
months_of_service NUMBER;
BEGIN
-- Normally, we would retrieve start and end dates from a database.
start_date := TO_TIMESTAMP('29-DEC-1988','dd-mon-yyyy');
end_date := TO_TIMESTAMP ('26-DEC-1995','dd-mon-yyyy');
-- Determine and display years and months of service
service_interval := (end_date - start_date) YEAR TO MONTH;
DBMS_OUTPUT.PUT_LINE(service_interval);
-- Use the new EXTRACT function to grab individual
-- year and month components.
years_of_service := EXTRACT(YEAR FROM service_interval);
months_of_service := EXTRACT(MONTH FROM service_interval);
DBMS_OUTPUT.PUT_LINE(years_of_service || ' years and '
|| months_of_service || ' months');
END;

Had I not used an INTERVAL type, I would have had to code something like the following:

months_of_service := ROUND(months_between(end_date, start_date));
years_of_service := TRUNC(months_of_service/12);
months_of_service := MOD(months_of_service,12);

Date and timestamp literals,are part of the ISO SQL standard and have been supported since Oracle9i Database.They represent yet another option for you to use in getting values into datetime variables.A date literal consists of the keyword DATE followed by a date (and only a date) value in the following format:
DATE 'YYYY-MM-DD'

A timestamp literal consists of the keyword TIMESTAMP followed by a datetime value
in a very specific format:
TIMESTAMP 'YYYY-MM-DD HH:MI:SS[.FFFFFFFFF] [{+|-}HH:MI]'

The function NUMTOYMINTERVAL (pronounced “num to Y M interval”) converts a
numeric value to an interval of type INTERVAL YEAR TO MONTH. The function
NUMTODSINTERVAL (pronounced “num to D S interval”) likewise converts a numeric
value to an interval of type INTERVAL DAY TO SECOND.

DECLARE
y2m INTERVAL YEAR TO MONTH;
BEGIN
y2m := NUMTOYMINTERVAL (10.5,'Year');
DBMS_OUTPUT.PUT_LINE(y2m);
END;
The output is:
+10-06

The next example converts a numeric value to an interval of type INTERVAL DAY TO
SECOND:

DECLARE
an_interval INTERVAL DAY TO SECOND;
BEGIN
an_interval := NUMTODSINTERVAL (1440,'Minute');
DBMS_OUTPUT.PUT_LINE(an_interval);
END;
The output is:
+01 00:00:00.000000
PL/SQL procedure successfully completed.

TO_YMINTERVAL converts a character string value into an INTERVAL YEAR TO
MONTH value.
TO_YMINTERVAL('Y-M')
TO_DSINTERVAL converts a character string into an INTERVAL DAY TO
SECOND value.
TO_DSINTERVAL('D HH:MI:SS.FF')

DECLARE
y2m INTERVAL YEAR TO MONTH;
BEGIN
y2m := INTERVAL '40-3' YEAR TO MONTH;
DBMS_OUTPUT.PUT_LINE(TO_CHAR(y2m,'YY "Years" and MM "Months"'));
END;
The output is the same as if no format mask had been specified:
+000040-03

If you’re not satisfied with the default conversion of intervals to character strings, you
can use the EXTRACT function:

DECLARE
y2m INTERVAL YEAR TO MONTH;
BEGIN
y2m := INTERVAL '40-3' YEAR TO MONTH;
DBMS_OUTPUT.PUT_LINE(
EXTRACT(YEAR FROM y2m) || ' Years and '
|| EXTRACT(MONTH FROM y2m) || ' Months'
);
END;
The output is:
40 Years and 3 Months

The following example shows EXTRACT being used to check whether the current
month is November:

BEGIN
IF EXTRACT (MONTH FROM SYSDATE) = 11 THEN
DBMS_OUTPUT.PUT_LINE('It is November');
ELSE
DBMS_OUTPUT.PUT_LINE('It is not November');
END IF;
END;
DECLARE
current_date TIMESTAMP;
result_date TIMESTAMP;
BEGIN
current_date := SYSTIMESTAMP;
result_date:= current_date + INTERVAL '1500 4:30:2' DAY TO SECOND;
DBMS_OUTPUT.PUT_LINE(result_date);
END;
DECLARE
end_of_may2008 TIMESTAMP;
next_month TIMESTAMP;
BEGIN
end_of_may2008 := TO_TIMESTAMP('31-May-2008', 'DD-Mon-YYYY');
next_month := TO_TIMESTAMP(ADD_MONTHS(end_of_may2008, 1));
DBMS_OUTPUT.PUT_LINE(next_month);
END;
The results are:
30-Jun-2008 00:00:00.000000

There is no SUBTRACT_MONTHS function, but you can call ADD_MONTHS with
negative month values. For example, use ADD_MONTHS(current_date, −1) in the
previous example to go back one month to the last day of April.

上一篇 下一篇

猜你喜欢

热点阅读