Apress.Expert.Oracle.Database.Architecture.9i.and.10g.Programming.Techniques.and.Solutions.Sep.2005

rekharaghuram
from rekharaghuram More from this publisher
05.11.2015 Views

CHAPTER 12 ■ DATATYPES 501 The INSERT succeeded, and we can see that the LENGTH of the inserted data is one character—all of the character string functions work “character-wise.” So the length of the field is one character, but the LENGTHB (length in bytes) function shows it takes 2 bytes of storage, and the DUMP function shows us exactly what those bytes are. That example demonstrates one very common issue people encounter when using multibyte character sets, namely that a VARCHAR2(N) doesn’t necessarily hold N characters, but rather N bytes. The next issue people confront frequently is that the maximum length in bytes of a VARCHAR2 is 4,000, and in a CHAR it is 2,000: ops$tkyte@O10GUTF> declare 2 l_data varchar2(4000 char); 3 l_ch varchar2(1 char) := unistr( '\00d6' ); 4 begin 5 l_data := rpad( l_ch, 4000, l_ch ); 6 insert into t ( c ) values ( l_data ); 7 end; 8 / declare * ERROR at line 1: ORA-01461: can bind a LONG value only for insert into a LONG column ORA-06512: at line 6 That shows that a 4,000-character string that is really 8,000 bytes long cannot be stored permanently in a VARCHAR2(4000 CHAR) field. It fits in the PL/SQL variable because in PL/SQL a VARCHAR2 is allowed to be up to 32KB in size. However, when it is stored in a table, the hard limit is 4,000 bytes. We can store 2,000 of these characters successfully: ops$tkyte@O10GUTF> declare 2 l_data varchar2(4000 char); 3 l_ch varchar2(1 char) := unistr( '\00d6' ); 4 begin 5 l_data := rpad( l_ch, 2000, l_ch ); 6 insert into t ( c ) values ( l_data ); 7 end; 8 / PL/SQL procedure successfully completed. ops$tkyte@O10GUTF> select length( c ), lengthb( c ) 2 from t 3 where c is not null; LENGTH(C) LENGTHB(C) ---------- ---------- 2000 4000 And as you can see, they consume 4,000 bytes of storage.

502 CHAPTER 12 ■ DATATYPES The “N” Variant So, of what use are the NVARCHAR2 and NCHAR (for completeness)? They are used in systems where the need to manage and store multiple character sets arises. This typically happens in a database where the predominant character set is a single-byte, fixed-width one (such as WE8ISO8859P1), but the need arises to maintain and store some multibyte data. There are many systems that have legacy data but need to support multibyte data for some new applications, or systems that want the efficiency of a single-byte character set for most operations (string operations on a fixed-width string are more efficient than on a string where each character may store a different number of bytes) but need the flexibility of multibyte data at some points. The NVARCHAR2 and NCHAR datatypes support this need. They are generally the same as their VARCHAR2 and CHAR counterparts, with the following exceptions: • Their text is stored and managed in the database’s national character set, not the default character set. • Their lengths are always provided in characters, whereas a CHAR/VARCHAR2 may specify either bytes or characters. In Oracle9i and later, the database’s national character set may take one of two values: UTF8 or AL16UTF16 (UTF16 in 9i; AL16UTF16 in 10g). This makes the NCHAR and NVARCHAR types suitable for storing only multibyte data, which is a change from earlier releases of the database (Oracle8i and earlier allowed you to choose any character set for the national character set). Binary Strings: RAW Types Oracle supports the storage of binary data as well as text. Binary data is not subject to the character set conversions we discussed earlier with regard to the CHAR and VARCHAR2 types. Therefore, binary datatypes are not suitable for storing user-supplied text, but are suitable for storing encrypted information—encrypted data is not “text,” but a binary representation of the original text, word processing documents containing binary markup information, and so on. Anything that should not be considered by the database to be “text” and that should not have character set conversion applied to it should be stored in a binary datatype. Oracle supports three datatypes for storing binary data: • The RAW type, which we focus on in this section and is suitable for storing RAW data up to 2,000 bytes in size. • The BLOB type, which supports binary data of much larger sizes, coverage of which we’ll defer to the “LOB Types” section later in the chapter. • The LONG RAW type, which is supported for backward compatibility and should not be considered for new applications. The syntax for the binary RAW type is straightforward: RAW( ) For example, the following code creates a table capable of storing 16 bytes of binary information per row:

502<br />

CHAPTER 12 ■ DATATYPES<br />

The “N” Variant<br />

So, of what use are the NVARCHAR2 <strong>and</strong> NCHAR (for completeness)? They are used in systems<br />

where the need to manage <strong>and</strong> store multiple character sets arises. This typically happens in<br />

a database where the predominant character set is a single-byte, fixed-width one (such as<br />

WE8ISO8859P1), but the need arises to maintain <strong>and</strong> store some multibyte data. There are many<br />

systems that have legacy data but need to support multibyte data for some new applications,<br />

or systems that want the efficiency of a single-byte character set for most operations (string<br />

operations on a fixed-width string are more efficient than on a string where each character<br />

may store a different number of bytes) but need the flexibility of multibyte data at some<br />

points.<br />

The NVARCHAR2 <strong>and</strong> NCHAR datatypes support this need. They are generally the same as<br />

their VARCHAR2 <strong>and</strong> CHAR counterparts, with the following exceptions:<br />

• Their text is stored <strong>and</strong> managed in the database’s national character set, not the<br />

default character set.<br />

• Their lengths are always provided in characters, whereas a CHAR/VARCHAR2 may specify<br />

either bytes or characters.<br />

In <strong>Oracle</strong>9i <strong>and</strong> later, the database’s national character set may take one of two values:<br />

UTF8 or AL16UTF16 (UTF16 in 9i; AL16UTF16 in 10g). This makes the NCHAR <strong>and</strong> NVARCHAR types<br />

suitable for storing only multibyte data, which is a change from earlier releases of the database<br />

(<strong>Oracle</strong>8i <strong>and</strong> earlier allowed you to choose any character set for the national character set).<br />

Binary Strings: RAW Types<br />

<strong>Oracle</strong> supports the storage of binary data as well as text. Binary data is not subject to the<br />

character set conversions we discussed earlier with regard to the CHAR <strong>and</strong> VARCHAR2 types.<br />

Therefore, binary datatypes are not suitable for storing user-supplied text, but are suitable for<br />

storing encrypted information—encrypted data is not “text,” but a binary representation of<br />

the original text, word processing documents containing binary markup information, <strong>and</strong> so<br />

on. Anything that should not be considered by the database to be “text” <strong>and</strong> that should not<br />

have character set conversion applied to it should be stored in a binary datatype.<br />

<strong>Oracle</strong> supports three datatypes for storing binary data:<br />

• The RAW type, which we focus on in this section <strong>and</strong> is suitable for storing RAW data up to<br />

2,000 bytes in size.<br />

• The BLOB type, which supports binary data of much larger sizes, coverage of which we’ll<br />

defer to the “LOB Types” section later in the chapter.<br />

• The LONG RAW type, which is supported for backward compatibility <strong>and</strong> should not be<br />

considered for new applications.<br />

The syntax for the binary RAW type is straightforward:<br />

RAW( )<br />

For example, the following code creates a table capable of storing 16 bytes of binary information<br />

per row:

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!