Skip Headers
Oracle® Database Advanced Application Developer's Guide
11g Release 2 (11.2)

Part Number E10471-03
Go to Documentation Home
Home
Go to Book List
Book List
Go to Table of Contents
Contents
Go to Index
Index
Go to Master Index
Master Index
Go to Feedback page
Contact Us

Go to previous page
Previous
Go to next page
Next
View PDF

2 Using SQL Data Types in Database Applications

This chapter explains how to use SQL data types in database applications.

Topics:

See Also:

Overview of SQL Data Types

A data type associates a fixed set of properties with the values that can be used in a column of a table or in an argument of a subprogram. These properties cause Oracle Database to treat values of one data type differently from values of another data type. For example, Oracle Database can add values of NUMBER data type, but not values of RAW data type.

Oracle Database provides many built-in data types and several categories for user-defined types that can be used as data types.

The Oracle precompilers recognize other data types in embedded SQL programs. These data types are called external data types and are associated with host variables. Do not confuse Oracle Database built-in data types and user-defined types with external data types.

See Also:

Representing Character Data

Topics:

Overview of Character Data Types

You can use these SQL data types to store alphanumeric data:

  • CHAR and NCHAR data types store fixed-length character literals.

  • VARCHAR2 and NVARCHAR2 data types store variable-length character literals.

  • NCHAR and NVARCHAR2 data types store Unicode character data only.

  • CLOB and NCLOB data types store single-byte and multibyte character strings of up to (4 gigabytes - 1) * (the value obtained from DBMS_LOB.GETCHUNKSIZE).

  • The LONG data type stores variable-length character strings containing up to two gigabytes, but with many restrictions. This data type is provided only for backward compatibility with existing applications. In general in new applications, use CLOB and NCLOB data types to store large amounts of character data, and BLOB and BFILE to store large amounts of binary data.

  • The LONG RAW data type is similar to the RAW data type, except that it stores raw data with a length up to two gigabytes. The LONG RAW data type is provided only for backward compatibility with existing applications.

See Also:

Specifying Column Lengths as Bytes or Characters

You can specify the lengths of CHAR and VARCHAR2 columns as either bytes or characters. The lengths of NCHAR and NVARCHAR2 columns are always specified in characters, making them ideal for storing Unicode data, where a character might consist of multiple bytes. This table shows some column length specifications and their meanings:

Column Length Specification Meaning
id VARCHAR2(32 BYTE) The id column contains up to 32 single-byte characters.
name VARCHAR2(32 CHAR) The name column contains up to 32 characters of the database character set. If the database character set includes multibyte characters, then the 32 characters can occupy more than 32 bytes.
biography NVARCHAR2(2000) The biography column contains up to 2000 characters of any Unicode-representable language. The encoding depends on the national character set. The column can contain multibyte values even if the database character set is single-byte.
comment VARCHAR2(2000) The comment column contains up to 2000 bytes or characters, depending on the value of the initialization parameter NLS_LENGTH_SEMANTICS.

When using a multibyte database character encoding scheme, consider carefully the space required for tables with character columns. If the database character encoding scheme is single-byte, then the number of bytes and the number of characters in a column is the same. If it is multibyte, however, then there generally is no such correspondence. A character might consist of one or more bytes, depending upon the specific multibyte encoding scheme and whether shift-in/shift-out control codes are present. To avoid overflowing buffers, specify data as NCHAR or NVARCHAR2 if it might use a Unicode encoding that is different from the database character set.

See Also:

Choosing Between CHAR and VARCHAR2 Data Types

When deciding which data type to use for a column that stores alphanumeric data in a table, consider these points of distinction:

  • Space usage

    To store data more efficiently, use the VARCHAR2 data type. The CHAR data type blank-pads and stores trailing blanks up to a fixed column length for all column values, whereas the VARCHAR2 data type does not add extra blanks.

  • Comparison semantics

    Use the CHAR data type when you require ANSI compatibility in comparison semantics (when trailing blanks are not important in string comparisons). Use the VARCHAR2 when trailing blanks are important in string comparisons.

  • Future compatibility

    The CHAR and VARCHAR2 data types are fully supported. Today, the VARCHAR data type automatically corresponds to the VARCHAR2 data type and is reserved for future use.

When an application interfaces with Oracle Database, there is a character set on the client and server side. Oracle Database uses the NLS_LANGUAGE parameter to automatically convert CHAR, VARCHAR2, and LONG data from the database character set to the character set defined for the user session, if these are different.

Oracle Database SQL Language Reference explains the comparison semantics that Oracle Database uses to compare character data. Because Oracle Database blank-pads values stored in CHAR columns but not in VARCHAR2 columns, a value stored in a VARCHAR2 column can take up less space than the same value in a CHAR column. For this reason, a full table scan on a large table containing VARCHAR2 columns may read fewer data blocks than a full table scan on a table containing the same data stored in CHAR columns. If your application often performs full table scans on large tables containing character data, then you may be able to improve performance by storing data in VARCHAR2 rather than in CHAR columns.

Performance is not the only factor to consider when deciding which data type to use. Oracle Database uses different semantics to compare values of each data type. You might choose one data type over the other if your application is sensitive to the differences between these semantics. For example, if you want Oracle Database to ignore trailing blanks when comparing character values, then you must store these values in CHAR columns.

See Also:

Oracle Database SQL Language Reference for more information about comparison semantics for these data types

Using Character Literals in SQL Statements

Many SQL statements, functions, expressions, and conditions require character literals. For information about using character literals in SQL statements, see Oracle Database SQL Language Reference.

Representing Numeric Data

Topics:

Overview of Numeric Data Types

The SQL data types NUMBER, BINARY_FLOAT, and BINARY_DOUBLE store numeric data.

Use the NUMBER data type to store real numbers in a fixed-point or floating-point format. Numbers using this data type are guaranteed to be portable among different Oracle Database platforms, and offer up to 38 decimal digits of precision. You can store positive and negative numbers of magnitude 1 x 10-130 through 9.99 x10125, and 0, in a NUMBER column.

The BINARY_FLOAT and BINARY_DOUBLE data types store floating-point data in the 32-bit IEEE 754 format and the double precision 64-bit IEEE 754 format respectively. Compared to the Oracle Database NUMBER data type, arithmetic operations on floating-point data are usually faster for BINARY_FLOAT and BINARY_DOUBLE. Also, high-precision values require less space when stored as BINARY_FLOAT and BINARY_DOUBLE.

In client interfaces supported by Oracle Database, the native instruction set supplied by the hardware vendor performs arithmetic operations on BINARY_FLOAT and BINARY_DOUBLE data types. The term native floating-point data type includes BINARY_FLOAT and BINARY_DOUBLE data types and all implementations of these types in supported client interfaces.

The floating-point number system is a common way of representing and manipulating numeric values in computer systems. A floating-point number is characterized by these components:

  • Binary-valued sign

  • Signed exponent

  • Significand

  • Base

A floating-point value is the signed product of its significand and the base raised to the power of its exponent, as in this formula:

(-1)sign.significand.baseexponent

For example, the number 4.31 is represented as follows:

(-1)0.431.10-2

The components of the preceding representation are as follows:

Component Name Component Value
Sign 0
Significand 431
Base 10
Exponent -2

See Also:

Floating-Point Number Formats

A floating-point number format specifies how components of a floating-point number are represented. The choice of representation determines the range and precision of the values the format can represent. By definition, the range is the interval bounded by the smallest and the largest values the format can represent and the precision is the number of digits in the significand.

Formats for floating-point values support neither infinite precision nor infinite range. There are a finite number of bits to represent a number and only a finite number of values that a format can represent. A floating-point number that uses more precision than available with a given format is rounded.

A floating-point number can be represented in a binary system, as in the IEEE 754 standard, or in a decimal system, such as Oracle Database NUMBER. The base affects many properties of the format, including how a numeric value is rounded.

For a decimal floating-point number format like Oracle Database NUMBER, rounding is done to the nearest decimal place (for example. 1000, 10, or 0.01). The IEEE 754 formats use a binary format for floating-point values and round numbers to the nearest binary place (for example: 1024, 512, or 1/64).

The native floating-point data types round to the nearest binary place, so they are not satisfactory for applications that require decimal rounding. Use the Oracle Database NUMBER data type for applications in which decimal rounding is required on floating-point data.

Topics:

Using a Floating-Point Binary Format

The value of a floating-point number that uses a binary format is determined by this formula:

(-1)s 2E (b0 b1 b2 ... bp-1)

Table 2-1 describes the components of the formula.

Table 2-1 Components of the Binary Format for Floating-Point Numbers

Component Specifies . . .

s

0 or 1

E

Any integer between Emin and Emax, inclusive (see Table 2-2)

bi

0 or 1, where the sequence of bits represents a number in base 2 (see Table 2-2)


The leading bit of the significand, b0, must be set (1), except for subnormal numbers (explained later). Therefore, the leading bit is not actually stored, so the formats provide n bits of precision although only n-1 bits are stored.

Note:

The IEEE 754 specification also defines extended single-precision and extended double-precision formats, which are not supported by Oracle Database.

The parameters for these formats are described in Table 2-2.

Table 2-2 Summary of Binary Format Parameters

Parameter Single-precision (32-bit) Double-precision (64-bit)

p

24

53

Emin

-126

-1022

Emax

+127

+1023


The storage parameters for the formats are described in Table 2-3. The in-memory formats for single-precision and double-precision data types are specified by IEEE 754.

Table 2-3 Summary of Binary Format Storage Parameters

Data Type Sign bits Exponent bits Significand bits Total bits

Single-precision

1

8

24 (23 stored)

32

Double-precision

1

11

53 (52 stored)

64


A significand is normalized when the leading bit of the significand is set. IEEE 754 defines denormal or subnormal values as numbers that are too small to be represented with an implied leading set bit in the significand. The number is too small because its exponent would be too large if its significand were normalized to have an implied leading bit set. IEEE 754 formats support subnormal values. Subnormal values preserve this property: If x - y == 0.0 (using floating-point subtraction), then: x == y.

Table 2-4 shows the range and precision of the required formats in the IEEE 754 standard and those of Oracle Database NUMBER. Range limits are expressed here in terms of positive numbers; they also apply to the absolute value of a negative number. (The notation "number e exponent" used here stands for number multiplied by 10 raised to the exponent power: number . 10 exponent.)

Table 2-4 Range and Precision of IEEE 754 formats

Range and Precision Single-precision 32-bitFoot 1  Double-precision 64-bit1 Oracle Database NUMBER Data Type

Maximum positive normal number

3.40282347e+38

1.7976931348623157e+308

< 1.0e126

Minimum positive normal number

1.17549435e-38

2.2250738585072014e-308

1.0e-130

Maximum positive subnormal number

1.17549421e-38

2.2250738585072009e-308

not applicable

Mininum positive subnormal number

1.40129846e-45

4.9406564584124654e-324

not applicable

Precision (decimal digits)

6 - 9

15 - 17

38 - 40


Footnote 1 These numbers are quoted from the IEEE Numerical Computation Guide.

See Also:

Special Values for Native Floating-Point Formats

IEEE 754 supports the special values shown in Table 2-5.

Table 2-5 Special Values for Native Floating-Point Formats

Value Meaning

+INF

Positive infinity

-INF

Negative infinity

NaN

Not a number

+0

Positive zero

-0

Negative zero


NaN represent results of operations that are undefined. Many bit patterns in IEEE 754 represent NaN. Bit patterns can represent NaN with and without the sign bit set. IEEE 754 distinguishes between signalling NaNs and quiet NaNs.

IEEE 754 specifies action for when exceptions are enabled and disabled. In Oracle Database, exceptions cannot be enabled; the database action is that specified by IEEE 754 for when exceptions are disabled. In particular, Oracle Database makes no distinction between signalling and quiet NaNs. Programmers who use OCI can retrieve NaN values from Oracle Database; whether a retrieved NaN value is signalling or quiet depends on the client platform and beyond the control of Oracle Database.

IEEE 754 does not define the bit pattern for either type of NaN. Positive infinity, negative infinity, positive zero, and negative zero are each represented by a specific bit pattern.

In IEEE 754, the classes of values are:

  • Zero

  • Subnormal

  • Normal

  • Infinity

  • NaN

Except for NaN, and ignoring signs, each class in the preceding list is larger than those that precede it in the list.

In IEEE 754, NaN is unordered with other classes of special values and with itself.

When used with the database, special values of native floating-point data types act as follows:

  • All NaNs are quiet.

  • IEEE 754 exceptions are not raised.

  • NaN is ordered as follows:

    All non-NaN < NaN

    Any NaN == any other NaN

  • -0 is converted to +0.

  • All NaNs are converted to the same bit pattern.

    See Also:

    "Comparison Operators for Native Floating-Point Data Types" for more information about NaN compared to other values

Comparison Operators for Native Floating-Point Data Types

Oracle Database defines these comparison operators for operations involving floating-point data types:

  • Equal to

  • Not equal to

  • Greater than

  • Greater than or equal to

  • Less than

  • Less than or equal to

  • Unordered

Special cases:

  • Comparisons ignore the sign of zero (-0 equals, but is not less than, +0).

  • In Oracle Database, NaN equals itself. NaN is greater than everything except itself. That is, NaN == NaN and NaN > x, unless x is NaN.

    See Also:

    "Special Values for Native Floating-Point Formats" for more information about comparison results, ordering, and other actions of special values

Arithmetic Operations with Native Floating-Point Data Types

Oracle Database defines operators for these arithmetic operations:

  • Multiplication

  • Division

  • Addition

  • Subtraction

  • Remainder

  • Square root

You can define the mode used to round the result of the operation. Exceptions can be raised when operations are performed. Exceptions can also be disabled.

Formerly, Java required floating-point arithmetic to be exactly reproducible. IEEE 754 does not have this requirement. Therefore, results of operations (including arithmetic operations) can be delivered to a destination that uses a range greater than the range that the operands of the operation use.

You can compute the result of a double-precision multiplication at an extended double-precision destination. When this is done, the result must be rounded as if the destination were single-precision or double-precision. The range of the result, that is, the number of bits used for the exponent, can use the range supported by the wider (extended double-precision) destination. This occurrence may result in a double-rounding error in which the least significant bit of the result is incorrect.

This situation can occur only for double-precision multiplication and division on hardware that implements the IA-32 and IA-64 instruction set architecture. Thus, except for this case, arithmetic for these data types is reproducible across platforms. When the result of a computation is NaN, all platforms produce a value for which IS NAN is true. However, all platforms do not have to use the same bit pattern.

Conversion Functions for Native Floating-Point Data Types

Oracle Database defines functions that convert between floating-point and other formats, including string formats that use decimal precision (precision may be lost during the conversion). For example, you can use these functions:

  • TO_BINARY_DOUBLE, which converts float to double, decimal (string) to double, and float or double to integer-valued double

  • TO_BINARY_FLOAT, which converts double to float, decimal (string) to float, and float or double to integer-valued float

  • TO_CHAR, which converts float or double to decimal (string)

  • TO_NUMBER, which converts a float, double, or string to a number

Oracle Database can raise exceptions during conversion. The IEEE 754 specification defines these exceptions:

  • Invalid

  • Inexact

  • Divide by zero

  • Underflow

  • Overflow

Oracle Database does not raise these exceptions for native floating-point data types. Generally, situations that raise exceptions produce the values described in Table 2-6.

Table 2-6 Values Resulting from Exceptions

Exception Value

Underflow

0

Overflow

-INF, +INF

Invalid Operation

NaN

Divide by Zero

-INF, +INF, NaN

Inexact

Any value – rounding was performed


Client Interfaces for Native Floating-Point Data Types

Oracle Database has implemented support for native floating-point data types in these client interfaces:

  • SQL

  • PL/SQL

  • OCI and OCCI

  • Pro*C/C++

  • JDBC

Topics:

OCI Native Floating-Point Data Types SQLT_BFLOAT and SQLT_BDOUBLE

The OCI API implements the IEEE 754 single precision and double precision native floating-point data types with the data types SQLT_BFLOAT and SQLT_BDOUBLE respectively. Conversions between these types and the SQL types BINARY_FLOAT and BINARY_DOUBLE are exact on platforms that implement the IEEE 754 standard for the C data types FLOAT and DOUBLE.

Native Floating-Point Data Types Supported in ADTs

Oracle Database supports the SQL data types BINARY_FLOAT and BINARY_DOUBLE as attributes of ADTs.

Pro*C/C++ Support for Native Floating-Point Data Types

Pro*C/C++ supports the native FLOAT and DOUBLE data types using the column data types BINARY_FLOAT and BINARY_DOUBLE. You can use these data types in the same way that Oracle Database NUMBER data type is used. You can bind the native C/C++ data types FLOAT and DOUBLE to BINARY_FLOAT and BINARY_DOUBLE types respectively by setting the Pro*C/C++ precompiler command line option NATIVE_TYPES to Y (yes) when you compile your application.

Representing Date and Time Data

Topics:

Overview of Date and Time Data Types

Oracle Database supports these date and time data types:

  • DATE

    Use the DATE data type to store point-in-time values (dates and times) in a table. The DATE data type stores the century, year, month, day, hours, minutes, and seconds.

  • TIMESTAMP

    Use the TIMESTAMP data type to store values that are precise to fractional seconds. For example, an application that must decide which of two events occurred first might use TIMESTAMP. An application that specifies the time for a job might use DATE.

  • TIMESTAMP WITH TIME ZONE

    Because TIMESTAMP WITH TIME ZONE can also store time zone information, it is particularly suited for recording date information that must be gathered or coordinated across geographic regions.

  • TIME STAMP WITH LOCAL TIME ZONE

    Use TIMESTAMP WITH LOCAL TIME ZONE when the time zone is not significant. For example, you might use it in an application that schedules teleconferences, where participants each see the start and end times for their own time zone.

    The TIMESTAMP WITH LOCAL TIME ZONE type is appropriate for two-tier applications in which you want to display dates and times that use the time zone of the client system. It is generally inappropriate in three-tier applications because data displayed in a Web browser is formatted according to the time zone of the Web server, not the time zone of the browser. The Web server is the database client, so its local time is used.

  • INTERVAL DAY TO SECOND

    Use the INTERVAL DAY TO SECOND data type to represent the precise difference between two datetime values. For example, you might use this value to set a reminder for a time 36 hours in the future or to record the time between the start and end of a race. To represent long spans of time with high precision, you can use a large value for the days portion.

  • INTERVAL YEAR TO MONTH

    Use the INTERVAL YEAR TO MONTH data type to represent the difference between two datetime values, where the only significant portions are the year and the month. For example, you might use this value to set a reminder for a date 18 months in the future, or check whether 6 months have elapsed since a particular date.

Oracle Database stores dates in its own internal format. Date data is stored in fixed-length fields of seven bytes each, corresponding to century, year, month, day, hour, minute, and second.

See Also:

Oracle Call Interface Programmer's Guide for a complete description of the Oracle Database internal date format

Displaying Current Date and Time

Use the SQL function SYSDATE to return the system date and time. You can use the FIXED_DATE initialization parameter to set SYSDATE to a constant, which can be useful for testing.

By default, SYSDATE is printed without a BC or AD qualifier. You can add BC to the format string to print the date with the appropriate qualifier, as in Example 2-1.

Example 2-1 Displaying Current Date and Time with AD or BC Qualifier

SELECT TO_CHAR(SYSDATE, 'DD-MON-YYYY BC') NOW FROM DUAL;
 

Result:

NOW
-----------------------
18-MAR-2009 AD
 
1 row selected.

For input and output of dates, the standard Oracle Database default date format is DD-MON-RR. The RR datetime format element enables you store 20th century dates in the 21st century by specifying only the last two digits of the year. For example, the format '13-NOV-54' refers to the year 1954 in a query issued between 1950 and 2049, but to the year 2054 in a query issued between 2050 and 2099.

See Also:

Oracle Database SQL Language Reference for information about the RR datetime format element.

Changing the Default Date Format

Use these techniques to change the default date format:

  • To change on an instance-wide basis, use the NLS_DATE_FORMAT parameter.

  • To change during a session, use the ALTER SESSION statement.

To enter dates that are not in the current default date format, use the TO_DATE function with a format mask, as in Example 2-2.

Example 2-2 Changing the Default Date Format

SELECT TO_CHAR(TO_DATE('27-OCT-98', 'DD-MON-RR'), 'YYYY') "Year"
FROM DUAL;
 

Result:

Year
----
1998
 
1 row selected.

Be careful when using a date format such as DD-MON-YY. The YY indicates the year in the current century. For example, 31-DEC-92 is December 31, 2092, not 1992 as you might expect. To indicate years in any century other than the current one, use a different format mask, such as the default RR.

Changing the Default Time Format

Time is stored in the 24-hour format: HH24:MI:SS

By default, the time in a DATE column is 12:00:00 A.M. (midnight) if no time portion is specified or if the DATE is truncated.

In a time-only entry, the date portion defaults to the first day of the current month. To enter the time portion of a date, use the TO_DATE function with a format mask indicating the time portion, as in Example 2-3.

Example 2-3 Changing the Default Time Format

DROP TABLE birthdays;
CREATE TABLE birthdays (name VARCHAR2(20), day DATE);
INSERT INTO birthdays (name, day)
  VALUES ('ANNIE',
          TO_DATE('13-NOV-92 10:56 A.M.','DD-MON-YY HH:MI A.M.')
         );

Arithmetic Operations with Date and Time Data Types

Oracle Database provides features to help with date arithmetic, so that you need not perform your own calculations on the number of seconds in a day, the number of days in each month, and so on. Some useful features include:

  • ADD_MONTHS function, which returns the date plus the specified number of months.

  • SYSDATE function, which returns the current date and time set for the operating system on which the database resides.

  • SYSTIMESTAMP function, which returns the system date, including fractional seconds and time zone, of the system on which the database resides.

  • TRUNC function, which when applied to a DATE value, trims off the time portion so that it represents the very beginning of the day (the stroke of midnight). By truncating two DATE values and comparing them, you can determine whether they refer to the same day. You can also use TRUNC along with a GROUP BY clause to produce daily totals.

  • Arithmetic operators such as + and -. For example, SYSDATE-7 refers to 7 days before the current system date.

  • INTERVAL data types, which enable you to represent constants when performing date arithmetic rather than performing your own calculations. For example, you can add or subtract INTERVAL constants from DATE values or subtract two DATE values and compare the result to an INTERVAL.

  • Comparison operators such as >, <, =, and BETWEEN.

Converting Between Date and Time Types

Oracle Database provides several useful functions that enable you to convert to and from datetime data types. Some useful functions include:

  • EXTRACT, which extracts and returns the value of a specified datetime field from a datetime or interval value expression

  • NUMTODSINTERVAL, which converts a NUMBER or expression that can be implicitly converted to a NUMBER value to an INTERVAL DAY TO SECOND literal

  • NUMTOYMINTERVAL, which converts a NUMBER or expression that can be implicitly converted to a NUMBER value to an INTERVAL YEAR TO MONTH literal

  • TO_DATE, which converts character data to a DATE data type

  • TO_CHAR, which converts DATE data to character data

  • TO_DSINTERVAL, which converts a character string to an INTERVAL DAY TO SECOND value

  • TO_TIMESTAMP, which converts character data to a value of TIMESTAMP data type

  • TO_TIMESTAMP_TZ, which converts character data to a value of TIMESTAMP WITH TIME ZONE data type

  • TO_YMINTERVAL, which converts a character string to an INTERVAL YEAR TO MONTH type

    See Also:

    Oracle Database SQL Language Reference for details about each function

Importing and Exporting Date and Time Types

TIMESTAMP WITH TIME ZONE and TIMESTAMP WITH LOCAL TIME ZONE values are always stored in normalized format, so that you can export, import, and compare them without worrying about time zone offsets. DATE and TIMESTAMP values do not store an associated time zone, and you must adjust them to account for any time zone differences between source and target databases.

Representing Specialized Data

Topics:

Representing Geographic Data

To represent Geographic Information System (GIS) or spatial data in the database, you can use Oracle Spatial features, including the type MDSYS.SDO_GEOMETRY. You can store the data in the database by using either an object-relational or a relational model. You can use a set of PL/SQL packages to query and manipulate the data.

See Also:

Oracle Spatial Developer's Guide to learn how to use MDSYS.SDO_GEOMETRY

Representing Multimedia Data

Oracle Multimedia enables Oracle Database to store, manage, and retrieve images, audio, video, or other heterogeneous media data in an integrated fashion with other enterprise information. Oracle Multimedia extends Oracle Database reliability, availability, and data management to multimedia content in traditional, Internet, electronic commerce, and media-rich applications.

Whether you store such multimedia data inside the database as BLOB or BFILE values, or store it externally on a Web server or other kind of server, you can use Oracle Multimedia to access the data using either an object-relational or a relational model, and manipulate and query the data using a set of ADTs.

Oracle Multimedia provides the ORDAudio, ORDDoc, ORDImage, ORDImageSignature, ORDVideo, and SI_StillImage ADTs (including methods) for these purposes:

  • Extracting metadata and attributes from multimedia data

  • Retrieving and managing multimedia data from Oracle Multimedia, Web servers, file systems, and other servers

  • Performing manipulation operations on image data

See Also:

Oracle Multimedia Reference for information about Oracle Multimedia types

Representing Large Amounts of Data

Oracle Database provides several data types for representing large amounts of data. These data types are grouped under the general category of Large Objects (LOBs). Table 2-7 describes the different LOBs.

Table 2-7 Large Object Data Types

Data Type Name Description

BLOB

Binary large object

Represents large amounts of binary data such as images, video, or other multimedia data.

CLOB

Character large object

Represents large amounts of character data. CLOB types are stored by using the database character set. Oracle Database stores a CLOB up to 4,000 bytes inline as a VARCHAR2. If the CLOB exceeds this length, then Oracle Database moves the CLOB out of line.

NCLOB

National character large objects

Represents large amounts of character data in National Character Set format.

BFILE

External large object

Stores objects in the operating system's file system, outside of the database files or tablespace. The BFILE type is read-only; other LOB types are read/write. BFILE objects are also sometimes referred to as external LOBs.


An instance of type BLOB, CLOB, or NCLOB can exist as either a persistent LOB instance or a temporary LOB instance. Persistent and temporary instances differ as follows:

  • A temporary LOB instance is declared in the scope of your application.

  • A persistent LOB instance is created and stored in the database.

Except for declaring, freeing, creating, and committing, operations on persistent and temporary LOB instances are performed the same way.

The RAW and LONG RAW data types store data that is not interpreted by Oracle Database, that is, it is not converted when moving data between different systems. These data types are intended for binary data and byte strings. For example, LONG RAW can store graphics, sound, documents, and arrays of binary data; the interpretation is dependent on the use.

Oracle Net and the Export and Import utilities do not perform character conversion when transmitting RAW or LONG RAW data. When Oracle Database automatically converts RAW or LONG RAW data to and from CHAR data, as is the case when entering RAW data as a literal in an INSERT statement, the database represents the data as one hexadecimal character representing the bit pattern for every four bits of RAW data. For example, one byte of RAW data with bits 11001011 is displayed and entered as CB.

You cannot index LONG RAW data, but you can index RAW data. In earlier releases, the LONG and LONG RAW data types were typically used to store large amounts of data. Use of these types is no longer recommended for development. If your existing application still uses these types, migrate your application to use LOB types. Oracle recommends that you convert LONG RAW columns to binary LOB (BLOB) columns and convert LONG columns to character LOB (CLOB or NCLOB) columns. LOB columns are subject to far fewer restrictions than LONG and LONG RAW columns.

See Also:

Representing Searchable Text

Rather than writing low-level code to do full-text searches, you can use Oracle Text. It stores the search data in a special kind of index, and lets you query the data with operators and PL/SQL packages. This technology enables you to create your own search engine using data from tables, files, or URLs, and combine the search logic with relational queries. You can also search XML data this way with the XPath notation.

See Also:

Oracle Text Application Developer's Guide for more information

Representing XML

If you have information stored as files in XML format, or to take an ADT and store it as XML, then you can use the XMLType built-in type.

XMLType columns store their data as either CLOB or binary XML. The XMLType constructor can turn an existing object of any data type into an XML object.

When an XML object is inside the database, you can use queries to traverse it (using the XML XPath notation) and extract all or part of its data.

You can also produce XML output from existing relational data and split XML documents across relational tables and columns. You can use these packages to transfer XML data into and out of relational tables:

  • DBMS_XMLQUERY, which provides database-to-XMLType functionality

  • DBMS_XMLGEN, which converts the results of a SQL query to a canonical XML format

  • DBMS_XMLSAVE, which provides XML to database-type functionality

You can use these SQL functions to process XML:

  • EXTRACT, which applies a VARCHAR2 XPath string and returns an XMLType instance containing an XML fragment

  • SYS_XMLAGG, which aggregates all of the XML documents or fragments represented by an expression and produces a single XML document

  • SYS_XMLGEN, which takes an expression that evaluates to a particular row and column of the database, and returns an instance of type XMLType containing an XML document

  • UPDATEXML, which takes as arguments an XMLType instance and an XPath-value pair and returns an XMLType instance with the updated value

  • XMLAGG, which takes a collection of XML fragments and returns an aggregated XML document

  • XMLCOLATTVAL, which creates an XML fragment and then expands the resulting XML so that each XML fragment has the name column with the attribute name

  • XMLCONCAT, which takes as input a series of XMLType instances, concatenates the series of elements for each row, and returns the concatenated series

  • XMLELEMENT, which takes an element name for identifier, an optional collection of attributes for the element, and arguments that comprise the content of the element

  • XMLFOREST, which converts each of its argument parameters to XML, and then returns an XML fragment that is the concatenation of these converted arguments

  • XMLSEQUENCE, which either takes as input an XMLType instance and returns a varray of the top-level nodes in the XMLType, or takes as input a REFCURSOR instance, with an optional instance of the XMLFormat object, and returns as an XMLSequence type an XML document for each row of the cursor

    XMLTRANSFORM, which takes as arguments an XMLType instance and an XSL style sheet, applies the style sheet to the instance, and returns an XMLType

See Also:

Representing Dynamically Typed Data

Some languages allow data types to change at run time or let a program check the type of a variable. For example, C has the union keyword and the void * pointer, and Java has the typeof operator and wrapper types such as Number. In Oracle Database, you can create variables and columns that can hold data of any type and test such data values to determine their underlying representation. For example, you can have a single table column represent a numeric value in one row, a string value in another row, and an object in another row.

You can use the built-in ADT SYS.ANYDATA to represent values of any scalar type or ADT. SYS.ANYDATA has methods that accept scalar values of any type, and turn them back into scalars or objects. Similarly, you can use the built-in ADT SYS.ANYDATASET to represent values of any collection type. To check and manipulate type information, use the DBMS_TYPES package, as in Example 2-4. With OCI, use the OCIType, OCIAnyData, and OCIAnyDataSet interfaces.

See Also:

Example 2-4 Accessing Information in a SYS.ANYDATA Column

CREATE OR REPLACE TYPE employee_type AS
  OBJECT (empno NUMBER, ename VARCHAR2(10));
/
 
DROP TABLE mytab;
CREATE TABLE mytab (id NUMBER, data SYS.ANYDATA);
 
INSERT INTO mytab (id, data)
VALUES (1, SYS.ANYDATA.ConvertNumber(5));
 
INSERT INTO mytab (id, data)
VALUES (2, SYS.ANYDATA.ConvertObject(Employee_type(5555, 'john')));
 
CREATE OR REPLACE PROCEDURE p IS
  CURSOR cur IS SELECT id, data FROM mytab;
  v_id                        mytab.id%TYPE;
  v_data                      mytab.data%TYPE;
  v_type                      SYS.ANYTYPE;
  v_typecode                  PLS_INTEGER;
  v_typename                  VARCHAR2(60);
  v_dummy                     PLS_INTEGER;
  v_n                         NUMBER;
  v_employee                  employee_type;
  non_null_anytype_for_NUMBER exception;
  unknown_typename            exception;
BEGIN
  OPEN cur;
  LOOP
    FETCH cur INTO v_id, v_data;
    EXIT WHEN cur%NOTFOUND;
 
    /* typecode signifies type represented by v_data.
       GetType also produces a value of type SYS.ANYTYPE with methods you
       can call to find precision and scale of a number, length of a
       string, and so on. */
 
       v_typecode := v_data.GetType (v_type /* OUT */);
 
    /* Compare typecode to DBMS_TYPES constants to determine type of data
       and decide how to display it. */
  
    CASE v_typecode
      WHEN DBMS_TYPES.TYPECODE_NUMBER THEN
        IF v_type IS NOT NULL THEN  -- This condition should never happen.
          RAISE non_null_anytype_for_NUMBER;
        END IF;
 
      -- For each type, there is a Get method.
      v_dummy := v_data.GetNUMBER (v_n /* OUT */);
      DBMS_OUTPUT.PUT_LINE
        (TO_CHAR(v_id) || ': NUMBER = ' || TO_CHAR(v_n) );
 
       WHEN DBMS_TYPES.TYPECODE_OBJECT THEN
         v_typename := v_data.GetTypeName();
         IF v_typename NOT IN ('HR.EMPLOYEE_TYPE') THEN
           RAISE unknown_typename;
         END IF;
         v_dummy := v_data.GetObject (v_employee /* OUT */);
         DBMS_OUTPUT.PUT_LINE
           (TO_CHAR(v_id) || ': user-defined type = ' || v_typename ||
            ' ( ' || v_employee.empno || ', ' || v_employee.ename || ' )' );
    END CASE;
  END LOOP;
  CLOSE cur;
EXCEPTION
  WHEN non_null_anytype_for_NUMBER THEN
    RAISE_Application_Error (-20000,
      'Paradox: the return AnyType instance FROM GetType ' ||
      'should be NULL for all but user-defined types');
  WHEN unknown_typename THEN
    RAISE_Application_Error( -20000, 'Unknown user-defined type ' ||
      v_typename || ' - program written to handle only HR.EMPLOYEE_TYPE');
END;
/
 
SELECT t.data.gettypename() AS "Type Name" FROM mytab t;
 

Result:

Type Name
--------------------------------------------------------------------------------
SYS.NUMBER
HR.EMPLOYEE_TYPE
 
2 rows selected.

Representing Data with ANSI/ISO, DB2, and SQL/DS Data Types

You can define columns of tables in Oracle Database through ANSI/ISO, DB2, and SQL/DS data types. Oracle Database internally converts such data types to Oracle Database data types.

The ANSI data type conversions are shown in Table 2-8. The ANSI/ISO data types NUMERIC, DECIMAL, and DEC can specify only fixed-point numbers. For these data types, s defaults to 0.

Table 2-8 ANSI Data Type Conversions to Oracle Database Data Types

ANSI SQL Data Type Oracle Database Data Type

CHARACTER (n)

CHAR (n)

CHAR (n)

NUMERIC (p,s)

DECIMAL (p,s)

DEC (p,s)

NUMBER (p,s)

INTEGER

INT

SMALLINT

NUMBER (38)

FLOAT (p)

FLOAT (p)

REAL

FLOAT (63)

DOUBLE PRECISION

FLOAT (126)

CHARACTER VARYING(n)

CHAR VARYING(n)

VARCHAR2 (n)

TIMESTAMP

TIMESTAMP

TIMESTAMP WITH TIME ZONE

TIMESTAMP WITH TIME ZONE


Table 2-9 shows the SQL/DS and DB2 conversions.

Table 2-9 SQL/DS, DB2 Data Type Conversions to Oracle Database Data Types

DB2 or SQL/DS Data Type Oracle Database Data Type

CHARACTER (n)

CHAR (n)

VARCHAR (n)

VARCHAR2 (n)

LONG VARCHAR

LONG

DECIMAL (p,s)

NUMBER ( p,s)

INTEGER

SMALLINT

NUMBER (38)

FLOAT (p)

FLOAT (p)

DATE

DATE

TIMESTAMP

TIMESTAMP


The data types TIME, GRAPHIC, VARGRAPHIC, and LONG VARGRAPHIC of IBM products SQL/DS and DB2 have no corresponding Oracle Database data type, and they cannot be used.

Representing Conditional Expressions as Data

The Oracle Expression Filter feature enables you to store conditional expressions as data in the database. The Oracle Expression Filter provides a mechanism that you can use to place a constraint on a VARCHAR2 column to ensure that the values stored are valid SQL WHERE clause expressions. This mechanism also identifies the set of attributes that are legal to reference in the conditional expressions.

Scenario: You created the following table, in which each row holds data for a stock-trading account holder, and you want to define a column that stores information about the stocks in which each trader is interested as a conditional expression.

DROP TABLE traders;
CREATE TABLE traders (
  name     VARCHAR2(10),
  email    VARCHAR2(20),
  interest VARCHAR2(30)
);

Solution:

  1. Create a type with attributes for the trading symbol, limit price, and amount of change in the stock price:

    CREATE OR REPLACE TYPE ticker AS OBJECT (
      symbol VARCHAR2(20),
      price  NUMBER,
      change NUMBER
    );
    /
    
  2. Create an attribute set based on the type ticker:

    BEGIN
      DBMS_EXPFIL.DROP_ATTRIBUTE_SET (attr_set  => 'ticker');
    END;
    /
    BEGIN
      DBMS_EXPFIL.CREATE_ATTRIBUTE_SET
      (attr_set  => 'ticker',
      from_type => 'YES');
    END;
    /
    
  3. Associate the attribute set with the expression set stored in the database column trader.interest:

    BEGIN
      DBMS_EXPFIL.ASSIGN_ATTRIBUTE_SET
      (attr_set => 'ticker',
      expr_tab => 'traders',
      expr_col => 'interest');
      END;
    /
    

    The preceding code ensures that the interest column stores valid conditional expressions.

  4. Populate the table with trader names, e-mail addresses, and conditional expressions that represent stocks in which the trader is interested, at particular prices. For example:

    INSERT INTO traders (name, email, interest)
    VALUES ('Vishu', 'vishu@example.com', 'symbol = ''ABC'' AND price > 25');
    
  5. Use the EVALUATE operator to identify the conditional expressions that evaluate to TRUE for a given data item. For example, this query returns traders who are interested in the stock quote (symbol='ABC', price=31, change=5.2):

    SELECT name, email
    FROM traders
    WHERE EVALUATE (
      interest,
      'symbol=>''ABC'',
      price=>31,
      change=>5.2'
    ) = 1;
     
    

    Result:

    NAME       EMAIL
    ---------- --------------------
    Vishu      vishu@example.com
     
    1 row selected.
    

    To speed up this type of query, you can create an Oracle Expression Filter index on the interest column.

    See Also:

    Oracle Database Rules Manager and Expression Filter Developer's Guide for details on Oracle Expression Filter

Identifying Rows by Address

The fastest way to access a row is by its address, or rowid, which uniquely identifies it. Different rows in the same data block can have the same rowid only if they are in different clustered tables. If a row is larger than one data block, then its rowid identifies its initial row piece.

To see rowids, you query the ROWID pseudocolumn, whose value is a string that represents the address of the row. The string has the data type ROWID or UROWID.

See Also:

Oracle Database SQL Language Reference for more information about the ROWID pseudocolumn

Topics:

Querying the ROWID Pseudocolumn

Each table in Oracle Database has a pseudocolumn named ROWID, which can appear in a query in either the SELECT list or the WHERE clause.

Example 2-5 uses the ROWID pseudocolumn in the SELECT list of a query. The rowids show how the rows of the table are stored.

Example 2-5 Querying the ROWID Pseudocolumn

DROP TABLE t_tab;  -- in case it exists
CREATE TABLE t_tab (col1 ROWID);
 
INSERT INTO t_tab (col1)
SELECT ROWID
FROM employees
WHERE employee_id > 199;
 

Query:

SELECT employee_id, rowid
FROM employees
WHERE employee_id > 199;
 

ROWID varies, but result is similar to:

EMPLOYEE_ID ROWID
----------- ------------------
        200 AAAPeSAAFAAAABTAAC
        201 AAAPeSAAFAAAABTAAD
        202 AAAPeSAAFAAAABTAAE
        203 AAAPeSAAFAAAABTAAF
        204 AAAPeSAAFAAAABTAAG
        205 AAAPeSAAFAAAABTAAH
        206 AAAPeSAAFAAAABTAAI
 
7 rows selected.
 

Query:

SELECT * FROM t_tab;
 

COL1 varies, but result is similar to:

COL1
------------------
AAAPeSAAFAAAABTAAC
AAAPeSAAFAAAABTAAD
AAAPeSAAFAAAABTAAE
AAAPeSAAFAAAABTAAF
AAAPeSAAFAAAABTAAG
AAAPeSAAFAAAABTAAH
AAAPeSAAFAAAABTAAI
 
7 rows selected.

ROWID Data Type

In tables that are not index-organized, and in foreign tables, the values of the ROWID pseudocolumn have the data type ROWID. The format of this data type is either restricted, extended or external binary.

Note:

You can create tables and clusters that have columns of the type ROWID, but the values of these columns are not guaranteed to be valid rowids.

Topics:

Restricted ROWID

Internally, the ROWID is a structure that holds information that the database server must access a row. The restricted internal ROWID is 6 bytes on most platforms. Each restricted rowid includes these data:

  • Data file identifier

  • Block identifier

  • Row identifier

The restricted ROWID pseudocolumn is returned to client applications in the form of an 18-character string with a hexadecimal encoding of the data block, row, and data file components of the ROWID.

Extended ROWID

The extended ROWID data type includes the data in the restricted rowid plus a data object number. The data object number is an identification number assigned to every database segment. The extended internal ROWID is 10 bytes on most platforms.

Data in an extended ROWID pseudocolumn is returned to the client application in the form of an 18-character string (for example, "AAAA8mAALAAAAQkAAA"), which represents a base 64 encoding of the components of the extended ROWID in a four-piece format, OOOOOOFFFBBBBBBRRR. Extended rowids are not available directly. You can use a supplied package, DBMS_ROWID, to interpret extended rowid contents. The package functions extract and provide information that is available directly from a restricted rowid and information specific to extended rowids.

See Also:

Oracle Database PL/SQL Packages and Types Reference for information about the DBMS_ROWID package

External Binary ROWID

Some client applications use a binary form of the ROWID. For example, OCI and some precompiler applications can map the ROWID data type to a 3GL structure on bind or define calls. The size of the binary ROWID is the same for extended and restricted ROWIDs. The information for the extended ROWID is included in an unused field of the restricted ROWID structure.

The format of the extended binary ROWID, expressed as a C struct, is as follows:

struct riddef {
    ub4    ridobjnum; /* data obj#--this field is 
                         unused in restricted ROWIDs */
    ub2    ridfilenum;
    ub1    filler;
    ub4    ridblocknum;
    ub2    ridslotnum;
}

UROWID Data Type

The rows of some tables have addresses that are not physical or permanent or were not generated by Oracle Database. For example, the row addresses of index-organized tables are stored in index leaves, which can move. Oracle Database provides these tables with logical row identifiers, called logical rowids. Rowids of foreign tables, such as DB2 tables accessed through a gateway, are not standard Oracle Database rowids. Oracle Database provides foreign tables with identifiers called foreign rowids.Oracle Database uses universal rowids (urowids) to store the addresses of index-organized and foreign tables. Both types of urowid are stored in the ROWID pseudocolumn, as are the physical rowids of heap-organized tables.Oracle Database creates logical rowids based on the primary key of the table. The logical rowids do not change if the primary key does not change. The ROWID pseudocolumn of an index-organized table has a data type of UROWID. You can access this pseudocolumn as you would access the ROWID pseudocolumn of a heap-organized table (that is, using a SELECT ROWID statement). To store the rowids of an index-organized table, define a column of type UROWID for the table and retrieve the value of the ROWID pseudocolumn into that column.

How Oracle Database Converts Data Types

In some cases, Oracle Database accepts data of one data type where it expects data of a different data type. Generally, an expression cannot contain values with different data types. However, Oracle Database can use various SQL functions to automatically convert data to the expected data type.

See Also:

Oracle Database SQL Language Reference for details about data type conversion

Topics:

Data Type Conversion During Assignments

The data type conversion for an assignment succeeds if Oracle Database can convert the data type of the value to be assigned to the data type of the target.

Assume that test_package, its public variable var1, and table1_tab are declared as follows:

CREATE OR REPLACE PACKAGE test_package AS
  var1 CHAR(5);
END;
/
 
DROP TABLE table1_tab;
CREATE TABLE table1_tab (col1 NUMBER);

In the assignment

variable := expression

the data type of expression must be either the same as, or convertible to, the data type of variable. For example, for this assignment, Oracle Database automatically converts zero to the data type of var1, which is CHAR(5):

var1 := 0;

In the statement

INSERT INTO table1_tab (col1) VALUES (expression)

the data type of expression must be either the same as, or convertible to, the data types of col1. For example, for this statement, Oracle Database automatically converts the string '19' to the data type of col1, which is NUMBER:

INSERT INTO table1_tab (col1) VALUES ('19')

In the statement

UPDATE table1_tab SET column = expression

the data type of expression must be either the same as, or convertible to, the data type of column. For example, for this statement, Oracle Database automatically converts the string '30' to the data type of col1, which is NUMBER:

UPDATE table1_tab SET col1 = '30';

In the statement

SELECT column INTO variable FROM table1_tab

the data type of column must be either the same as, or convertible to, the data type of variable. For example, for this statement, Oracle Database automatically converts the value selected from col1, which is 30, to the data type of var1, which is CHAR(5):

SELECT col1 INTO var1 FROM table1_tab WHERE col1 = 30;

Data Type Conversion During Expression Evaluation

For expression evaluation, Oracle Database can automatically perform the same conversions as for assignments. An expression is converted to a type based on its context. For example, operands to arithmetic operators are converted to NUMBER, and operands to string functions are converted to VARCHAR2.

Oracle Database can automatically convert:

  • VARCHAR2 or CHAR to NUMBER

  • VARCHAR2 or CHAR to DATE

Character to NUMBER conversions succeed only if the character string represents a valid number. Character to DATE conversions succeed only if the character string satisfies the session default format, which is specified by the initialization parameter NLS_DATE_FORMAT.

Some common types of expressions are:

  • Simple expressions, such as:

    commission + '500'
    
  • Boolean expressions, such as:

    bonus > salary / '10'
    
  • Subprogram calls, such as:

    MOD (counter, '2')
    
  • WHERE clause conditions, such as:

    WHERE hiredate = TO_DATE('1997-01-01','yyyy-mm-dd')
    
  • WHERE clause conditions, such as:

    WHERE rowid = 'AAAAaoAATAAAADAAA'
    

In general, Oracle Database uses the rule for expression evaluation when a data type conversion is needed in places not covered by the rule for assignment conversions.

In assignments of the form:

variable := expression

Oracle Database first evaluates expression using the conversion rules for expressions; expression can be as simple or complex as desired. If it succeeds, then the evaluation of expression results in a single value and data type. Then, Oracle Database tries to assign this value to the target variable using the conversion rules for assignments.

Metadata for SQL Built-In Functions

You can see metadata for SQL built-in functions with the dynamic performance views V$SQLFN_METADATA (which has general metadata) and V$SQLFN_ARG_METADATA (which has metadata about arguments). You can join these views on the column FUNCID. For functions with unlimited arguments, such as LEAST and GREATEST, V$SQLFN_ARG_METADATA has only one row for each repeating argument.

These views enable third-party tools to leverage SQL built-in functions without maintaining their metadata in the application layer.

See Also:

Oracle Database Reference for detailed information about the dynamic performance views V$SQLFN_METADATA and V$SQLFN_ARG_METADATA

Often, an argument for a SQL built-in function can have any data type in a data type family. Table 2-10 shows which data types belong to which families.

Table 2-10 Data Type Families

Family Data Types

STRING

CHARACTER

 

VARCHAR2

 

CLOB

 

NCHAR

 

NVARCHAR2

 

NCLOB

NUMERIC

NUMBER

 

BINARY_FLOAT

 

BINARY_DOUBLE

DATETYPE

DATE

 

TIMESTAMP

 

TIMESTAMP WITH TIME ZONE

 

TIMESTAMP WITH LOCAL TIME ZONE

 

INTERVAL YEAR TO MONTH

 

INTERVAL DAY TO SECOND

BINARY

BLOB

 

RAW

 

LONGRAW


ARGn Data Type

In the view V$SQLFN_METADATA, ARGn is the data type of a function whose return value has the same data type as its nth argument. For example:

EXPR Data Type

In the view V$SQLFN_ARG_METADATA, EXPR is the data type of an argument that can be any expression. An expression is either a single value or a combination of values and SQL functions that has a single value.

Table 2-11 Display Types of SQL Built-In Functions

Display Type Description Example

NORMAL

FUNC(A,B,...)

LEAST(A,B,C)

ARITHMETIC

A FUNC B)

A+B

PARENTHESIS

FUNC()

SYS_GUID()

RELOP

A FUNC B)

A IN B

CASE_LIKE

CASE statement or DECODE decode

 

NOPAREN

FUNC

SYSDATE